Skip to content

Commit

Permalink
# This is a combination of 3 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

Add formatter and parser for standards ISO8601, RFC1123, RFC2822

# The commit message #2 will be skipped:

# Prefer RFC 3339 instead of ISO 8601
#
# see https://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats and http://docs.diesel.rs/chrono/struct.DateTime.html#method.parse_from_rfc3339

# The commit message crystal-lang#3 will be skipped:

# Remove RFC 1123 in favour of RFC 2822
  • Loading branch information
straight-shoota committed Oct 15, 2017
1 parent 00fc564 commit f593f56
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
8 changes: 8 additions & 0 deletions spec/std/time/time_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ describe Time do
t.to_s("%s").should eq("1388631845")
end

it "formats standard formats" do
time = Time.new(2016, 2, 15, kind: Time::Kind::Utc)
time.to_rfc3339.should eq "2016-02-15T00:00:00+00:00"
Time.parse_rfc3339(time.to_rfc3339).should eq time
time.to_rfc2822.should eq "Mon, 15 Feb 2016 00:00:00 +0000"
Time.parse_rfc2822(time.to_rfc2822).should eq time
end

it "parses empty" do
t = Time.parse("", "")
t.year.should eq(1)
Expand Down
1 change: 1 addition & 0 deletions src/http/common.cr
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ module HTTP
# ```
# HTTP.rfc1123_date(Time.new(2016, 2, 15)) # => "Sun, 14 Feb 2016 21:00:00 GMT"
# ```
# DEPRECATED: Use `Time#to_rfc2822` instead.
def self.rfc1123_date(time : Time) : String
Time::Format::HTTP_DATE.format(time)
end
Expand Down
2 changes: 1 addition & 1 deletion src/http/cookie.cr
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module HTTP
header << "#{URI.escape @name}=#{URI.escape value}"
header << "; domain=#{domain}" if domain
header << "; path=#{path}" if path
header << "; expires=#{HTTP.rfc1123_date(expires)}" if expires
header << "; expires=#{expires.to_utc.to_rfc2822}" if expires
header << "; Secure" if @secure
header << "; HttpOnly" if @http_only
header << "; #{@extension}" if @extension
Expand Down
50 changes: 50 additions & 0 deletions src/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,56 @@ struct Time
Format.new(format).format(self, io)
end

# Format this time using the format specified by [RFC 3339](https://tools.ietf.org/html/rfc3339) ([ISO 8601](http://xml.coverpages.org/ISO-FDIS-8601.pdf) profile).
#
# ```
# Time.new(2016, 2, 15).to_rfc3339 # => "2016-02-15T00:00:00+00:00"
# ```
#
# ISO 8601 allows some freedom over the syntax and RFC 3339 exercises that
# freedom to rigidly define a fixed format intended for use in internet
# protocols and standards.
def to_rfc3339
Format::RFC_3339.format(to_utc)
end

# Format this time using the format specified by [RFC 3339](https://tools.ietf.org/html/rfc3339) ([ISO 8601](http://xml.coverpages.org/ISO-FDIS-8601.pdf) profile).
# into the given *io*.
def to_rfc3339(io : IO)
Format::RFC_3339.format(to_utc, io)
end

# Parse time in format specified by [RFC 3339](https://tools.ietf.org/html/rfc3339) ([ISO 8601](http://xml.coverpages.org/ISO-FDIS-8601.pdf) profile).
def self.parse_rfc3339(time : String)
Format::RFC_3339.parse(time)
end

# Format this time using the format specified by [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt).
#
# ```
# Time.new(2016, 2, 15).to_rfc2822 # => "Mon, 15 Feb 2016 00:00:00 -0400"
# ```
#
# This is also compatible to [RFC 882](https://tools.ietf.org/html/rfc882) and [RFC 1123](https://tools.ietf.org/html/rfc1123#page-55).
def to_rfc2822
Format::RFC_2822.format(to_utc)
end

# Format this time using the format specified by [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt)
# into the given *io*.
#
# This is also compatible to [RFC 882](https://tools.ietf.org/html/rfc882) and [RFC 1123](https://tools.ietf.org/html/rfc1123#page-55).
def to_rfc2822(io : IO)
Format::RFC_2822.format(to_utc, io)
end

# Parse time in format specified by [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt).
#
# This is also compatible to [RFC 882](https://tools.ietf.org/html/rfc882) and [RFC 1123](https://tools.ietf.org/html/rfc1123#page-55).
def self.parse_rfc2822(time : String)
Format::RFC_2822.parse(time)
end

# Parses a Time in the given *time* string, using the given *pattern* (see
# `Time::Format`).
#
Expand Down
9 changes: 9 additions & 0 deletions src/time/format.cr
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ struct Time::Format
# :nodoc:
DAY_NAMES = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)

# The [RFC 3339](https://tools.ietf.org/html/rfc3339)/[ISO 8601](http://xml.coverpages.org/ISO-FDIS-8601.pdf) datetime format.
# This is just `"%FT%X%:z"`.
RFC_3339 = new "%FT%X%:z"

# The [RFC 2822](https://tools.ietf.org/html/rfc2822) datetime format.
#
# This is also compatible to [RFC 882](https://tools.ietf.org/html/rfc882) and [RFC 1123](https://tools.ietf.org/html/rfc1123#page-55).
RFC_2822 = new "%a, %d %b %Y %H:%M:%S %z"

# Error raised when an invalid pattern is used.
class Error < ::Exception
end
Expand Down

0 comments on commit f593f56

Please sign in to comment.