5

How can I force the Time.rfc2822 function to spit out +0000?

Ruby lets me parse RFC2822 formatted times pretty easily:

require 'time'
time = Time.parse('14 Aug 2009 09:28:32 +0000')
puts time
=> "2009-08-14 05:28:32 -0400"

But what about displaying times? Notice that the time it parsed is a local time. No worries, I can convert it back to a UTC time with gmtime:

puts time.gmtime
=> "2009-08-14 09:28:32 UTC"

I can then put it back into RFC2822 format:

puts time.gmtime.rfc2822
=> "Fri, 14 Aug 2009 09:28:32 -0000"

Unfortunately, this is not quite what I want. Notice that the +0000 is now -0000. According to RFC2822, this is because:

The form "+0000" SHOULD be used to indicate a time zone at Universal Time. Though "-0000" also indicates Universal Time, it is used to indicate that the time was generated on a system that may be in a local time zone other than Universal Time and therefore indicates that the date-time contains no information about the local time zone.

Great - so how can I force +0000 other than monkey-patching the rfc2822 function?

Bkkbrad
  • 3,087
  • 24
  • 30
  • If you set the time zone to universal time before calling gmtime.rfc2882 do you get the appropriate output? It seems like it's reporting what it should be reporting, as I think Time.zone should be set to your local zone, by default. – Bill D Aug 18 '09 at 01:28
  • I'm not sure exactly what you mean. However, I did find that the DateTime class is much nicer; `DateTime.parse('14 Aug 2009 09:28:32 +0000').rfc2822` yields `"Fri, 14 Aug 2009 09:28:32 +0000"`. – Bkkbrad Aug 18 '09 at 03:02
  • Boy, that's strange... and yes: my thinking on the timezone thing got a bit muddied. Screwing around in the console to think up something for you helped straighten me out... didn't give me anything to share with you, unfortunately. – Bill D Aug 18 '09 at 03:05

2 Answers2

4

Here's my monkeypatch solution:

class Time
  alias_method :old_rfc2822, :rfc2822
  def rfc2822
    t = old_rfc2822
    t.gsub!("-0000", "+0000") if utc?
    t
  end
end

If you have a non-monkeypatch solution, I would love to see it!

Bkkbrad
  • 3,087
  • 24
  • 30
0

simplest way if you don't need to use on multiple places

 Time.now.gmtime.rfc2822.sub(/(-)(0+)$/, '+\2')
 => "Fri, 31 Mar 2017 08:39:04 +0000"

or as a static (singleton) method version

require 'time'
module MyCustomTimeRFC
  def custom_rfc2822(time)
    time.gmtime.rfc2822.sub(/(-)(0+)$/, '+\2')
  end

  module_function :custom_rfc2822
end

t = Time.now
p MyCustomTimeRFC.custom_rfc2822(t)
#=> "Fri, 31 Mar 2017 08:43:15 +0000"

or as module extension if you like the oop style with ruby flexibility.

require 'time'
module MyCustomTimeRFC
  def custom_rfc2822
    gmtime.rfc2822.sub(/(-)(0+)$/, '+\2')
  end
end

t = Time.now
t.extend(MyCustomTimeRFC)
p t.custom_rfc2822
#=> "Fri, 31 Mar 2017 08:43:15 +0000"
Adam
  • 81
  • 2
  • 3