10

I want to be able to parse a Time from a string in Ruby (1.8.7), where the string does not contain any time zone information. I would like to treat the string as though it were in any of a number of time zones specified in this type of format: 'America/New_York'.

Time string example:

'2010-02-05 01:00:01'

I have spent quite a while trying to figure this one out.

I did find a similar question, but its answer does not apply in my case: How do I get Ruby to parse time as if it were in a different time zone?

The problem with the above solution is that my time zones cannot all be represented in the 3-letter format supported by Time.parse (http://www.ruby-doc.org/stdlib-1.8.7/libdoc/time/rdoc/classes/Time.html#M004931).

Is there a good way to accomplish what I'm trying to do here?

Edit: Made my answer actually appear as an answer.

Community
  • 1
  • 1
cpass
  • 121
  • 1
  • 7
  • Thanks, I updated my post with a stab at using that gem for my problem. – cpass Jul 07 '11 at 21:09
  • It's absurd to me that plain Ruby doesn't have a means of doing this. It would be nice not to have to rely on a chunky Rails library/gem. Not sure why the `tzinfo` gem wouldn't provide a way to parse. – Pistos Aug 09 '19 at 02:58

3 Answers3

11
require 'active_support/all'
time = ActiveSupport::TimeZone.new('UTC').parse('2010-02-05 01:00:01')

puts time
puts time.in_time_zone('EST')
user454339
  • 155
  • 1
  • 4
  • Thanks for this, exactly what I needed to get unstuck, where I want to parse a string in a given timezone, and then convert to utc timestamp: `ActiveSupport::TimeZone.new('Pacific Time (US & Canada)').parse("May 12, 2015 10:27:48 AM").utc.to_i` – Nick B May 12 '15 at 21:24
  • Thank you, I must have wasted 2 hours trying to sort out an ETL job that was generating wrong time records.. Cheers! – Nick M Oct 25 '16 at 11:42
2

Here's what I came up with using the tzinfo gem as suggested, though it seems rather complicated and unintuitive to me. As an end result I get the time parsed as though it were in the time zone I wanted, though represented by a Time object in UTC. I can also display it in the time zone I want using tzinfo's strftime:

jruby-1.6.1 :003 > time = '2010-05-01 01:00:00'
 => "2010-05-01 01:00:00" 
jruby-1.6.1 :004 > tz = TZInfo::Timezone.get('America/New_York')
 => #<TZInfo::DataTimezone: America/New_York> 
jruby-1.6.1 :005 > time += ' UTC'
 => "2010-05-01 01:00:00 UTC" 
jruby-1.6.1 :006 > time = Time.parse(time)
 => Sat May 01 01:00:00 UTC 2010 
jruby-1.6.1 :007 > time = tz.local_to_utc(time)
 => Sat May 01 05:00:00 UTC 2010 
jruby-1.6.1 :010 > tz.strftime('%Y-%m-%d %H:%M:%S %Z', time)
 => "2010-05-01 01:00:00 EDT" 

I believe this will suit my needs, but I wonder if I can get the Time to actually be in the timezone above (instead of just UTC).

cpass
  • 121
  • 1
  • 7
  • While I think this code will work, might I suggest improving the organization? Try setting up the tz object, and then the date, and then combining, instead of jumping back and forth between the two logic chains – RonLugge Apr 27 '14 at 23:18
1

You have two options the way I see it. On the one hand you could map the format you wish to use in an array (or any other structure you wish) to the 3-letter format used by Time.parse.

The other option is using the tzinfo gem as specified by my which seems to do the job quite nicely.

>> tz = TZInfo::Timezone.get("America/New_York")
=> #<TZInfo::DataTimezone: America/New_York>
>> tz.now
=> Thu Jul 07 16:29:13 UTC 2011
>> tz = TZInfo::Timezone.get("Europe/Rome")
=> #<TZInfo::DataTimezone: Europe/Rome>
>> tz.now
=> Thu Jul 07 22:30:03 UTC 2011
Maran
  • 2,751
  • 15
  • 12
  • 2
    Yeah, this is close. The trick is that I need to parse a date represented as a string. I added an attempt at this in my post. – cpass Jul 07 '11 at 21:09