diff --git a/spec/std/time/time_spec.cr b/spec/std/time/time_spec.cr index 8c80d5e6f1de..74a6f3031e08 100644 --- a/spec/std/time/time_spec.cr +++ b/spec/std/time/time_spec.cr @@ -651,18 +651,18 @@ describe Time do end it "#inspect" do - Time.utc(2014, 1, 2, 3, 4, 5).inspect.should eq "2014-01-02 03:04:05.0 UTC" - Time.utc(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789).inspect.should eq "2014-01-02 03:04:05.123456789 UTC" + Time.utc(2014, 1, 2, 3, 4, 5).inspect.should eq "2014-01-02 03:04:05Z" + Time.utc(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789).inspect.should eq "2014-01-02 03:04:05.123456789Z" with_zoneinfo do location = Time::Location.load("Europe/Berlin") - Time.local(2014, 1, 2, 3, 4, 5, location: location).inspect.should eq "2014-01-02 03:04:05.0 +01:00 Europe/Berlin" - Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: location).inspect.should eq "2014-01-02 03:04:05.123456789 +01:00 Europe/Berlin" + Time.local(2014, 1, 2, 3, 4, 5, location: location).inspect.should eq "2014-01-02 03:04:05+01:00[Europe/Berlin]" + Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: location).inspect.should eq "2014-01-02 03:04:05.123456789+01:00[Europe/Berlin]" end location = Time::Location.fixed(3601) - Time.local(2014, 1, 2, 3, 4, 5, location: location).inspect.should eq "2014-01-02 03:04:05.0 +01:00:01" - Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: location).inspect.should eq "2014-01-02 03:04:05.123456789 +01:00:01" + Time.local(2014, 1, 2, 3, 4, 5, location: location).inspect.should eq "2014-01-02 03:04:05+01:00:01" + Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: location).inspect.should eq "2014-01-02 03:04:05.123456789+01:00:01" end it "at methods" do diff --git a/src/file.cr b/src/file.cr index 0a218bcf91ec..63cbf9f17d87 100644 --- a/src/file.cr +++ b/src/file.cr @@ -40,7 +40,7 @@ require "crystal/system/file" # tempfile = File.tempfile("foo") # # File.size(tempfile.path) # => 6 -# File.info(tempfile.path).modification_time # => 2015-10-20 13:11:12 UTC +# File.info(tempfile.path).modification_time # => 2015-10-20 13:11:12Z # File.exists?(tempfile.path) # => true # File.read_lines(tempfile.path) # => ["foobar"] # ``` @@ -208,7 +208,7 @@ class File < IO::FileDescriptor # ``` # File.write("foo", "foo") # File.info("foo").size # => 3 - # File.info("foo").modification_time # => 2015-09-23 06:24:19 UTC + # File.info("foo").modification_time # => 2015-09-23 06:24:19Z # # File.symlink("foo", "bar") # File.info("bar", follow_symlinks: false).type.symlink? # => true diff --git a/src/http/common.cr b/src/http/common.cr index b82455d1df54..66963e669fe1 100644 --- a/src/http/common.cr +++ b/src/http/common.cr @@ -343,9 +343,9 @@ module HTTP # ``` # require "http" # - # HTTP.parse_time("Sun, 14 Feb 2016 21:00:00 GMT") # => "2016-02-14 21:00:00 UTC" - # HTTP.parse_time("Sunday, 14-Feb-16 21:00:00 GMT") # => "2016-02-14 21:00:00 UTC" - # HTTP.parse_time("Sun Feb 14 21:00:00 2016") # => "2016-02-14 21:00:00 UTC" + # HTTP.parse_time("Sun, 14 Feb 2016 21:00:00 GMT") # => "2016-02-14 21:00:00Z" + # HTTP.parse_time("Sunday, 14-Feb-16 21:00:00 GMT") # => "2016-02-14 21:00:00Z" + # HTTP.parse_time("Sun Feb 14 21:00:00 2016") # => "2016-02-14 21:00:00Z" # ``` # # Uses `Time::Format::HTTP_DATE` as parser. diff --git a/src/json/to_json.cr b/src/json/to_json.cr index b4d0881f79e9..979709de7adf 100644 --- a/src/json/to_json.cr +++ b/src/json/to_json.cr @@ -310,7 +310,7 @@ end # end # # timestamp = TimestampArray.from_json(%({"dates":[1459859781,1567628762]})) -# timestamp.dates # => [2016-04-05 12:36:21 UTC, 2019-09-04 20:26:02 UTC] +# timestamp.dates # => [2016-04-05 12:36:21Z, 2019-09-04 20:26:02Z] # timestamp.to_json # => %({"dates":[1459859781,1567628762]}) # ``` # @@ -328,7 +328,7 @@ end # end # # timestamp = TimestampArray.from_json(%({"dates":["Apr 5, 2016","Sep 4, 2019"]})) -# timestamp.dates # => [2016-04-05 00:00:00 UTC, 2019-09-04 00:00:00 UTC] +# timestamp.dates # => [2016-04-05 00:00:00Z, 2019-09-04 00:00:00Z] # timestamp.to_json # => %({"dates":["Apr 5, 2016","Sep 4, 2019"]}) # ``` # @@ -371,7 +371,7 @@ end # end # # timestamp = TimestampHash.from_json(%({"birthdays":{"foo":1459859781,"bar":1567628762}})) -# timestamp.birthdays # => {"foo" => 2016-04-05 12:36:21 UTC, "bar" => 2019-09-04 20:26:02 UTC} +# timestamp.birthdays # => {"foo" => 2016-04-05 12:36:21Z, "bar" => 2019-09-04 20:26:02Z} # timestamp.to_json # => %({"birthdays":{"foo":1459859781,"bar":1567628762}}) # ``` # @@ -389,7 +389,7 @@ end # end # # timestamp = TimestampHash.from_json(%({"birthdays":{"foo":"Apr 5, 2016","bar":"Sep 4, 2019"}})) -# timestamp.birthdays # => {"foo" => 2016-04-05 00:00:00 UTC, "bar" => 2019-09-04 00:00:00 UTC} +# timestamp.birthdays # => {"foo" => 2016-04-05 00:00:00Z, "bar" => 2019-09-04 00:00:00Z} # timestamp.to_json # => %({"birthdays":{"foo":"Apr 5, 2016","bar":"Sep 4, 2019"}}) # ``` # @@ -435,7 +435,7 @@ end # end # # person = Person.from_json(%({"birth_date": 1459859781})) -# person.birth_date # => 2016-04-05 12:36:21 UTC +# person.birth_date # => 2016-04-05 12:36:21Z # person.to_json # => %({"birth_date":1459859781}) # ``` module Time::EpochConverter @@ -459,7 +459,7 @@ end # end # # timestamp = Timestamp.from_json(%({"value": 1459860483856})) -# timestamp.value # => 2016-04-05 12:48:03.856 UTC +# timestamp.value # => 2016-04-05 12:48:03.856Z # timestamp.to_json # => %({"value":1459860483856}) # ``` module Time::EpochMillisConverter diff --git a/src/time.cr b/src/time.cr index 081114b1e0dc..d1e94571f227 100644 --- a/src/time.cr +++ b/src/time.cr @@ -9,7 +9,7 @@ require "crystal/system/time" # Leap seconds are ignored. # # Internally, the time is stored as an `Int64` representing seconds from epoch -# (`0001-01-01 00:00:00.0 UTC`) and an `Int32` representing +# (`0001-01-01 00:00:00Z`) and an `Int32` representing # nanosecond-of-second with value range `0..999_999_999`. # # The supported date range is `0001-01-01 00:00:00.0` to @@ -84,7 +84,7 @@ require "crystal/system/time" # # ``` # time = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin")) -# time # => 2018-03-08 22:05:13 +01:00 Europe/Berlin +# time # => 2018-03-08 22:05:13+01:00[Europe/Berlin] # time.location # => # # time.zone # => # # time.offset # => 3600 @@ -94,7 +94,7 @@ require "crystal/system/time" # # ``` # time = Time.utc(2018, 3, 8, 22, 5, 13) -# time # => 2018-03-08 22:05:13.0 UTC +# time # => 2018-03-08 22:05:13Z # time.location # => # # time.zone # => # # time.offset # => 0 @@ -106,8 +106,8 @@ require "crystal/system/time" # ``` # time_de = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin")) # time_ar = time_de.in Time::Location.load("America/Argentina/Buenos_Aires") -# time_de # => 2018-03-08 22:05:13 +01:00 Europe/Berlin -# time_ar # => 2018-03-08 18:05:13 -03:00 America/Argentina/Buenos_Aires +# time_de # => 2018-03-08 22:05:13+01:00[Europe/Berlin] +# time_ar # => 2018-03-08 18:05:13-03:00[America/Argentina/Buenos_Aires] # ``` # # Both `Time` instances show a different local date-time, but they represent @@ -115,8 +115,8 @@ require "crystal/system/time" # equal: # # ``` -# time_de.to_utc # => 2018-03-08 21:05:13 UTC -# time_ar.to_utc # => 2018-03-08 21:05:13 UTC +# time_de.to_utc # => 2018-03-08 21:05:13Z +# time_ar.to_utc # => 2018-03-08 21:05:13Z # time_de == time_ar # => true # ``` # @@ -267,7 +267,7 @@ struct Time # :nodoc: DAYS_PER_4_YEARS = 365*4 + 1 - # This constant is defined to be "1970-01-01 00:00:00 UTC". + # This constant is defined as `1970-01-01 00:00:00Z`". # Can be used to create a `Time::Span` that represents an Unix Epoch time duration. # # ``` @@ -379,7 +379,7 @@ struct Time # # ``` # time = Time.local(2016, 2, 15, 10, 20, 30, location: Time::Location.load("Europe/Berlin")) - # time.inspect # => "2016-02-15 10:20:30.0 +01:00 Europe/Berlin" + # time.inspect # => "2016-02-15 10:20:30+01:00[Europe/Berlin]" # ``` # # Valid value ranges for the individual fields: @@ -470,7 +470,7 @@ struct Time end # Creates a new `Time` instance that corresponds to the number of *seconds* - # and *nanoseconds* elapsed from epoch (`0001-01-01 00:00:00.0 UTC`) + # and *nanoseconds* elapsed from epoch (`0001-01-01 00:00:00.0`) # observed in *location*. # # Valid range for *seconds* is `0..315_537_897_599`. @@ -493,7 +493,7 @@ struct Time end # Creates a new `Time` instance that corresponds to the number of *seconds* - # and *nanoseconds* elapsed from epoch (`0001-01-01 00:00:00.0 UTC`) + # and *nanoseconds* elapsed from epoch (`0001-01-01 00:00:00Z`) # in UTC. # # Valid range for *seconds* is `0..315_537_897_599`. @@ -512,24 +512,24 @@ struct Time {% end %} # Creates a new `Time` instance that corresponds to the number of - # *seconds* elapsed since the Unix epoch (`1970-01-01 00:00:00 UTC`). + # *seconds* elapsed since the Unix epoch (`1970-01-01 00:00:00Z`). # # The time zone is always UTC. # # ``` - # Time.unix(981173106) # => 2001-02-03 04:05:06 UTC + # Time.unix(981173106) # => 2001-02-03 04:05:06Z # ``` def self.unix(seconds : Int) : Time utc(seconds: UNIX_EPOCH.total_seconds + seconds, nanoseconds: 0) end # Creates a new `Time` instance that corresponds to the number of - # *milliseconds* elapsed since the Unix epoch (`1970-01-01 00:00:00 UTC`). + # *milliseconds* elapsed since the Unix epoch (`1970-01-01 00:00:00Z`). # # The time zone is always UTC. # # ``` - # time = Time.unix_ms(981173106789) # => 2001-02-03 04:05:06.789 UTC + # time = Time.unix_ms(981173106789) # => 2001-02-03 04:05:06.789Z # time.millisecond # => 789 # ``` def self.unix_ms(milliseconds : Int) : Time @@ -540,12 +540,12 @@ struct Time end # Creates a new `Time` instance that corresponds to the number of - # *nanoseconds* elapsed since the Unix epoch (`1970-01-01 00:00:00.000000000 UTC`). + # *nanoseconds* elapsed since the Unix epoch (`1970-01-01 00:00:00Z`). # # The time zone is always UTC. # # ``` - # time = Time.unix_ns(981173106789479273) # => 2001-02-03 04:05:06.789479273 UTC + # time = Time.unix_ns(981173106789479273) # => 2001-02-03 04:05:06.789479273Z # time.nanosecond # => 789479273 # ``` def self.unix_ns(nanoseconds : Int) : Time @@ -566,8 +566,8 @@ struct Time # new_year = Time.utc(2019, 1, 1, 0, 0, 0) # tokyo = new_year.to_local_in(Time::Location.load("Asia/Tokyo")) # new_york = new_year.to_local_in(Time::Location.load("America/New_York")) - # tokyo.inspect # => "2019-01-01 00:00:00.0 +09:00 Asia/Tokyo" - # new_york.inspect # => "2019-01-01 00:00:00.0 -05:00 America/New_York" + # tokyo.inspect # => "2019-01-01 00:00:00+09:00[Asia/Tokyo]" + # new_york.inspect # => "2019-01-01 00:00:00-05:00[America/New_York]" # ``` # # If the given wall clock is a gap or fold in the target location, no @@ -582,10 +582,10 @@ struct Time # nyc = Time::Location.load("America/New_York") # # # gap on 2025-03-09 local time: 02:00:00 STD -> 03:00:00 DST - # Time.utc(2025, 3, 9, 2, 12, 34).to_local_in(nyc) # => 2025-03-09 01:12:34.0 -05:00 America/New_York + # Time.utc(2025, 3, 9, 2, 12, 34).to_local_in(nyc) # => 2025-03-09 01:12:34.0-05:00[America/New_York] # # # overlap on 2025-11-02 local time: 02:00:00 DST -> 01:00:00 STD - # Time.utc(2025, 11, 2, 1, 12, 34).to_local_in(nyc) # => 2025-11-02 01:12:34.0 -04:00 America/New_York + # Time.utc(2025, 11, 2, 1, 12, 34).to_local_in(nyc) # => 2025-11-02 01:12:34.0-04:00[America/New_York] # ``` def to_local_in(location : Location) : Time local_seconds = offset_seconds @@ -1046,8 +1046,8 @@ struct Time # time_de == time_ar # => true # # # both times represent the same instant: - # time_de.to_utc # => 2018-03-08 21:05:13 UTC - # time_ar.to_utc # => 2018-03-08 21:05:13 UTC + # time_de.to_utc # => 2018-03-08 21:05:13Z + # time_ar.to_utc # => 2018-03-08 21:05:13Z # ``` def ==(other : Time) : Bool total_seconds == other.total_seconds && nanosecond == other.nanosecond @@ -1098,29 +1098,29 @@ struct Time # Prints this `Time` to *io*. # - # The local date-time is formatted as date string `YYYY-MM-DD HH:mm:ss.nnnnnnnnn +ZZ:ZZ:ZZ`. - # Nanoseconds are omitted if *with_nanoseconds* is `false`. - # When the location is `UTC`, the offset is omitted. Offset seconds are omitted if `0`. + # It's formatted according to the Internet Extended Date/Time Format (IXDTF) + # as specified in [RFC 9557](https://datatracker.ietf.org/doc/html/rfc9557): + # An [RFC 3339](https://tools.ietf.org/html/rfc3339) formatted local date-time + # string with nanosecond precision followed by a time zone name suffix. # - # The name of the location is appended unless it is a fixed zone offset. + # It is similar to the format `%FT%T.%N%::z[%Z]`. Some parts may be omitted or + # shortened. + # + # Nanoseconds are omitted if *with_nanoseconds* is `false` or `nanoseconds` + # are zero. Zero offset seconds are omitted. The name of the location is + # omitted for fixed zone offset. + # + # ``` + # Time.utc(2014, 1, 2, 3, 4, 5) # => 2014-01-02 03:04:05Z + # Time.utc(2014, 1, 2, 3, 4, 5, nanosecond: 123_456) # => 2014-01-02 03:04:05.123456000Z + # + # Time.local(2014, 1, 2, 3, 4, 5, location: Time::Location.load("Europe/Berlin")) # => 2014-01-02 03:04:05+01:00[Europe/Berlin] + # Time.local(2014, 1, 2, 3, 4, 5, location: Time::Location.fixed(3600)) # => 2014-01-02 03:04:05+01:00 + # Time.local(2014, 1, 2, 3, 4, 5, location: Time::Location.fixed(3601)) # => 2014-01-02 03:04:05+01:00:01 + # ``` def inspect(io : IO, with_nanoseconds = true) : Nil - to_s io, "%F %T" - - if with_nanoseconds - if @nanoseconds == 0 - io << ".0" - else - to_s io, ".%N" - end - end - - if utc? - io << " UTC" - else - io << ' ' - zone.format(io) - io << ' ' << location.name unless location.fixed? - end + Format::RFC_3339.format(self, io, fraction_digits: (with_nanoseconds && !nanosecond.zero?) ? 9 : 0, preferred_separator: ' ') + io << '[' << location.name << ']' unless location.fixed? end # Prints this `Time` to *io*. @@ -1165,7 +1165,7 @@ struct Time # Format this time using the format specified by [RFC 3339](https://tools.ietf.org/html/rfc3339) ([ISO 8601](https://web.archive.org/web/20250306154328/http://xml.coverpages.org/ISO-FDIS-8601.pdf) profile). # # ``` - # Time.utc(2016, 2, 15).to_rfc3339 # => "2016-02-15T00:00:00Z" + # Time.utc(2016, 2, 15).to_rfc3339 # => "2016-02-15 00:00:00Z" # ``` # # ISO 8601 allows some freedom over the syntax and RFC 3339 exercises that @@ -1191,7 +1191,7 @@ struct Time # Parse time format specified by [RFC 3339](https://tools.ietf.org/html/rfc3339) ([ISO 8601](https://web.archive.org/web/20250306154328/http://xml.coverpages.org/ISO-FDIS-8601.pdf) profile). # # ``` - # Time.parse_rfc3339("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50.0 UTC + # Time.parse_rfc3339("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50Z # ``` def self.parse_rfc3339(time : String) : self Format::RFC_3339.parse(time) @@ -1205,7 +1205,7 @@ struct Time # Use `#to_rfc3339` to format a `Time` according to . # # ``` - # Time.parse_iso8601("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50.0 UTC + # Time.parse_iso8601("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50Z # ``` def self.parse_iso8601(time : String) Format::ISO_8601_DATE_TIME.parse(time) @@ -1235,7 +1235,7 @@ struct Time # This is also compatible to [RFC 882](https://tools.ietf.org/html/rfc882) and [RFC 1123](https://tools.ietf.org/html/rfc1123#page-55). # # ``` - # Time.parse_rfc2822("Mon, 15 Feb 2016 04:35:50 UTC") # => 2016-02-15 04:35:50.0 UTC + # Time.parse_rfc2822("Mon, 15 Feb 2016 04:35:50 UTC") # => 2016-02-15 04:35:50Z # ``` def self.parse_rfc2822(time : String) : self Format::RFC_2822.parse(time) @@ -1246,7 +1246,7 @@ struct Time # See `Time::Format` for details. # # ``` - # Time.parse("2016-04-05", "%F", Time::Location.load("Europe/Berlin")) # => 2016-04-05 00:00:00.0 +02:00 Europe/Berlin + # Time.parse("2016-04-05", "%F", Time::Location.load("Europe/Berlin")) # => 2016-04-05 00:00:00+02:00[Europe/Berlin] # ``` # # If there is no time zone information in the formatted time, *location* will @@ -1304,7 +1304,7 @@ struct Time end # Returns the number of seconds since the Unix epoch - # (`1970-01-01 00:00:00 UTC`). + # (`1970-01-01 00:00:00Z`). # # ``` # time = Time.utc(2016, 1, 12, 3, 4, 5) @@ -1315,7 +1315,7 @@ struct Time end # Returns the number of milliseconds since the Unix epoch - # (`1970-01-01 00:00:00 UTC`). + # (`1970-01-01 00:00:00Z`). # # ``` # time = Time.utc(2016, 1, 12, 3, 4, 5, nanosecond: 678_000_000) @@ -1326,7 +1326,7 @@ struct Time end # Returns the number of nanoseconds since the Unix epoch - # (`1970-01-01 00:00:00.000000000 UTC`). + # (`1970-01-01 00:00:00Z`). # # ``` # time = Time.utc(2016, 1, 12, 3, 4, 5, nanosecond: 678_910_123) @@ -1337,7 +1337,7 @@ struct Time end # Returns the number of seconds since the Unix epoch - # (`1970-01-01 00:00:00 UTC`) as `Float64` with nanosecond precision. + # (`1970-01-01 00:00:00Z`) as `Float64` with nanosecond precision. # # ``` # time = Time.utc(2016, 1, 12, 3, 4, 5, nanosecond: 678_000_000) @@ -1360,8 +1360,8 @@ struct Time # ``` # time_de = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin")) # time_ar = time_de.in Time::Location.load("America/Argentina/Buenos_Aires") - # time_de # => 2018-03-08 22:05:13 +01:00 Europe/Berlin - # time_ar # => 2018-03-08 18:05:13 -03:00 America/Argentina/Buenos_Aires + # time_de # => 2018-03-08 22:05:13+01:00[Europe/Berlin] + # time_ar # => 2018-03-08 18:05:13-03:00[America/Argentina/Buenos_Aires] # ``` # # In contrast, `#to_local_in` changes to a different location while @@ -1445,9 +1445,9 @@ struct Time # # ``` # now = Time.utc(2023, 5, 16, 17, 53, 22) - # now.at_beginning_of_week # => 2023-05-15 00:00:00 UTC - # now.at_beginning_of_week(:sunday) # => 2023-05-14 00:00:00 UTC - # now.at_beginning_of_week(:wednesday) # => 2023-05-10 00:00:00 UTC + # now.at_beginning_of_week # => 2023-05-15 00:00:00Z + # now.at_beginning_of_week(:sunday) # => 2023-05-14 00:00:00Z + # now.at_beginning_of_week(:wednesday) # => 2023-05-10 00:00:00Z # ``` # TODO: Ensure correctness in local time-line. def at_beginning_of_week(start_day : Time::DayOfWeek = :monday) : Time diff --git a/src/time/format/custom/http_date.cr b/src/time/format/custom/http_date.cr index 25847b21aa00..dd2268f5b760 100644 --- a/src/time/format/custom/http_date.cr +++ b/src/time/format/custom/http_date.cr @@ -10,10 +10,10 @@ struct Time::Format # * [asctime](http://en.cppreference.com/w/c/chrono/asctime) # # ``` - # Time::Format::HTTP_DATE.parse("Sun, 14 Feb 2016 21:00:00 GMT") # => 2016-02-14 21:00:00 UTC - # Time::Format::HTTP_DATE.parse("Sunday, 14-Feb-16 21:00:00 GMT") # => 2016-02-14 21:00:00 UTC - # Time::Format::HTTP_DATE.parse("Sun, 14-Feb-2016 21:00:00 GMT") # => 2016-02-14 21:00:00 UTC - # Time::Format::HTTP_DATE.parse("Sun Feb 14 21:00:00 2016") # => 2016-02-14 21:00:00 UTC + # Time::Format::HTTP_DATE.parse("Sun, 14 Feb 2016 21:00:00 GMT") # => 2016-02-14 21:00:00Z + # Time::Format::HTTP_DATE.parse("Sunday, 14-Feb-16 21:00:00 GMT") # => 2016-02-14 21:00:00Z + # Time::Format::HTTP_DATE.parse("Sun, 14-Feb-2016 21:00:00 GMT") # => 2016-02-14 21:00:00Z + # Time::Format::HTTP_DATE.parse("Sun Feb 14 21:00:00 2016") # => 2016-02-14 21:00:00Z # # Time::Format::HTTP_DATE.format(Time.utc(2016, 2, 15)) # => "Mon, 15 Feb 2016 00:00:00 GMT" # ``` diff --git a/src/time/format/custom/iso_8601.cr b/src/time/format/custom/iso_8601.cr index b6e634c7a4de..8da6ce6b06ac 100644 --- a/src/time/format/custom/iso_8601.cr +++ b/src/time/format/custom/iso_8601.cr @@ -118,7 +118,7 @@ struct Time::Format # The ISO 8601 date format. # # ``` - # Time::Format::ISO_8601_DATE.parse("2016-02-15") # => 2016-02-15 00:00:00.0 UTC + # Time::Format::ISO_8601_DATE.parse("2016-02-15") # => 2016-02-15 00:00:00Z # Time::Format::ISO_8601_DATE.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "2016-02-15" # ``` module ISO_8601_DATE @@ -147,8 +147,8 @@ struct Time::Format # The ISO 8601 date time format. # # ``` - # Time::Format::ISO_8601_DATE_TIME.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "2016-02-15T04:35:50Z" - # Time::Format::ISO_8601_DATE_TIME.parse("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50.0 UTC + # Time::Format::ISO_8601_DATE_TIME.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "2016-02-15 04:35:50Z" + # Time::Format::ISO_8601_DATE_TIME.parse("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50Z # ``` module ISO_8601_DATE_TIME # Parses a string into a `Time`. @@ -177,7 +177,7 @@ struct Time::Format # # ``` # Time::Format::ISO_8601_TIME.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "04:35:50Z" - # Time::Format::ISO_8601_TIME.parse("04:35:50Z") # => 0001-01-01 04:35:50.0 UTC + # Time::Format::ISO_8601_TIME.parse("04:35:50Z") # => 0001-01-01 04:35:50Z # ``` module ISO_8601_TIME # Parses a string into a `Time`. diff --git a/src/time/format/custom/rfc_2822.cr b/src/time/format/custom/rfc_2822.cr index 3397cce8e471..43236d616fd1 100644 --- a/src/time/format/custom/rfc_2822.cr +++ b/src/time/format/custom/rfc_2822.cr @@ -7,7 +7,7 @@ struct Time::Format # Time::Format::RFC_2822.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "Mon, 15 Feb 2016 04:35:50 +0000" # # Time::Format::RFC_2822.parse("Mon, 15 Feb 2016 04:35:50 +0000") # => 2016-02-15 04:35:50.0 +00:00 - # Time::Format::RFC_2822.parse("Mon, 15 Feb 2016 04:35:50 UTC") # => 2016-02-15 04:35:50.0 UTC + # Time::Format::RFC_2822.parse("Mon, 15 Feb 2016 04:35:50 UTC") # => 2016-02-15 04:35:50Z # ``` module RFC_2822 # Parses a string into a `Time`. diff --git a/src/time/format/custom/rfc_3339.cr b/src/time/format/custom/rfc_3339.cr index 3295d9ecacaf..37b35c780797 100644 --- a/src/time/format/custom/rfc_3339.cr +++ b/src/time/format/custom/rfc_3339.cr @@ -4,8 +4,8 @@ struct Time::Format # ``` # Time::Format::RFC_3339.format(Time.utc(2016, 2, 15, 4, 35, 50)) # => "2016-02-15T04:35:50Z" # - # Time::Format::RFC_3339.parse("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50.0 UTC - # Time::Format::RFC_3339.parse("2016-02-15 04:35:50Z") # => 2016-02-15 04:35:50.0 UTC + # Time::Format::RFC_3339.parse("2016-02-15T04:35:50Z") # => 2016-02-15 04:35:50Z + # Time::Format::RFC_3339.parse("2016-02-15 04:35:50Z") # => 2016-02-15 04:35:50Z # ``` module RFC_3339 # Parses a string into a `Time`. @@ -16,27 +16,27 @@ struct Time::Format end # Formats a `Time` into the given *io*. - def self.format(time : Time, io : IO, fraction_digits = 0) + def self.format(time : Time, io : IO, fraction_digits = 0, *, preferred_separator = 'T') formatter = Formatter.new(time, io) - formatter.rfc_3339(fraction_digits: fraction_digits) + formatter.rfc_3339(fraction_digits: fraction_digits, preferred_separator: preferred_separator) io end # Formats a `Time` into a `String`. - def self.format(time : Time, fraction_digits = 0) : String + def self.format(time : Time, fraction_digits = 0, *, preferred_separator = 'T') : String String.build do |io| - format(time, io, fraction_digits: fraction_digits) + format(time, io, fraction_digits: fraction_digits, preferred_separator: preferred_separator) end end end module Pattern - def rfc_3339(fraction_digits = 0) + def rfc_3339(fraction_digits = 0, preferred_separator = 'T') year_month_day - char 'T', 't', ' ' + char preferred_separator, 'T', 't', ' ' twenty_four_hour_time_with_seconds second_fraction?(fraction_digits: fraction_digits) - time_zone_z_or_offset(force_colon: true) + time_zone_z_or_offset(force_colon: true, format_seconds: :auto) end end end diff --git a/src/time/location.cr b/src/time/location.cr index 8bc66b9dcfef..4c56db2bbf0b 100644 --- a/src/time/location.cr +++ b/src/time/location.cr @@ -18,7 +18,7 @@ require "./location/loader" # location = Time::Location.load("Europe/Berlin") # location # => # # time = Time.local(2016, 2, 15, 21, 1, 10, location: location) -# time # => 2016-02-15 21:01:10 +01:00 Europe/Berlin +# time # => 2016-02-15 21:01:10+01:00[Europe/Berlin] # ``` # # A custom time zone database can be configured through the environment variable @@ -447,7 +447,7 @@ class Time::Location # Returns the time zone offset observed at *unix_seconds*. # # *unix_seconds* expresses the number of seconds since UNIX epoch - # (`1970-01-01 00:00:00 UTC`). + # (`1970-01-01 00:00:00Z`). def lookup(unix_seconds : Int) : Zone unless @cached_range[0] <= unix_seconds < @cached_range[1] @cached_zone, @cached_range = lookup_with_boundaries(unix_seconds) diff --git a/src/yaml/to_yaml.cr b/src/yaml/to_yaml.cr index 7c9fdb2c778e..949e81b7db46 100644 --- a/src/yaml/to_yaml.cr +++ b/src/yaml/to_yaml.cr @@ -276,7 +276,7 @@ end # end # # timestamp = Timestamp.from_yaml(%({"values":[1459859781,1567628762]})) -# timestamp.values # => [2016-04-05 12:36:21 UTC, 2019-09-04 20:26:02 UTC] +# timestamp.values # => [2016-04-05 12:36:21Z, 2019-09-04 20:26:02Z] # timestamp.to_yaml # => "---\nvalues:\n- 1459859781\n- 1567628762\n" # ``` # @@ -294,7 +294,7 @@ end # end # # timestamp = Timestamp.from_yaml(%({"values":["Apr 5, 2016","Sep 4, 2019"]})) -# timestamp.values # => [2016-04-05 00:00:00 UTC, 2019-09-04 00:00:00 UTC] +# timestamp.values # => [2016-04-05 00:00:00Z, 2019-09-04 00:00:00Z] # timestamp.to_yaml # => "---\nvalues:\n- Apr 5, 2016\n- Sep 4, 2019\n" # ``` #