formatting date in ruby - ruby

I have a date in the format 05/22/2011 13:10 Eastern Time (US & Canada)
How can I convert that into a date object? This is what I used to parse the date from sting but I'm getting invalid date error.
str = "05/22/2011 13:10 Eastern Time (US & Canada)"
Date.strptime(str, "%d/%m/%Y %H:%M:%S %Z")

Your sting: 05/22/2011 13:10 Eastern Time (US & Canada).
Here is a number of mistakes in your pattern:
Month is a first argument
Day is a second
Here is no any seconds in your time, only hours and minutes
Also your string includes Date and Time as well, so you'd better to use DateTime class instead of Date class:
Date.strptime(str, "%m/%d/%Y %H:%M %Z")
#=> Sun, 22 May 2011
or
DateTime.strptime(str, "%m/%d/%Y %H:%M %Z")
#=> Sun, 22 May 2011 13:10:00 -0500
To work with datetime you should require it first:
require 'date'
dt = DateTime.strptime("05/22/2011 13:10 Eastern Time (US & Canada)", "%m/%d/%Y %H:%M %Z")
#=> #<DateTime: 353621413/144,-5/24,2299161>
dt.to_s
#=> "2011-05-22T13:10:00-05:00"
dt.hour
#=> 13
...

There are 2 bugs in your call to Date.strptime
1) The date and month are reversed
2) There is no seconds field in your string

Related

Convert a Ruby string to proper Date and Time

I have a Ruby variable containing Timestamp , I need to get Date and Time from it , I am able to get Date (but wrong) time is always 00:00 (note: li is a variable getting from a file)
li = 'Date: Wed, 25 Dec 2019 23:16:52 -0600'
date = li.delete("Date: ")
=> "Wd,25c2019231652-0600"
puts date
Wd,25c2019231652-0600
Date.parse(date).to_s
=> "2020-09-25"
Time.parse(date).to_s
=> "2020-09-25 00:00:00 +0530"
DateTime.parse(date).to_s
=> "2020-09-25T00:00:00+00:00"
DateTime.parse(date).strftime('%Y-%d-%m %H:%M:%S')
=> "2020-25-09 00:00:00"
I need to get correct date and Time (either in UTC or -0600)
li = 'Date: Wed, 25 Dec 2019 23:16:52 -0600'
require 'date'
Date.strptime(li, 'Date: %a, %d %b %Y %H:%M:%S %z')
#=> #<Date: 2019-12-25 ((2458843j,0s,0n),+0s,2299161j)>
See Date::strptime. Date-time formatting directives are given in the doc DateTime#strftime.

Take separate time and timezone strings, and convert into UTC

I know a bunch of ways to convert local times into UTC time with Ruby, but I'm not sure how to do this when the time and the zone are separate pieces of data. If I have something like "12:00 PM -0500", I can easily convert this into UTC with .getutc(). However, what if I have "12:00 PM" and "Eastern Time (US & Canada)"? How can I combine these two to find the UTC time?
The DateTime::parse method may be what you are looking for.
x = DateTime.parse("12:00 PM Eastern Time (US & Canada)")
will return a result of
#<DateTime: 2017-11-15T12:00:00-05:00 ((2458073j,61200s,0n),-18000s,2299161j)>
From there, there are many ways to convert the time to UTC. For example,
utc = x.new_offset(0)
will return a result of
#<DateTime: 2017-11-15T17:00:00+00:00 ((2458073j,61200s,0n),+0s,2299161j)>
If you are using Rails, or if you don't mind requiring ActiveSupport, you can use ActiveSupport::TimeZone to do this.
>> time_zone = "Eastern Time (US & Canada)"
>> time_without_zone = "12:00 PM"
>> ActiveSupport::TimeZone[time_zone].parse(time_without_zone)
#=> Wed, 15 Nov 2017 12:00:00 EST -05:00

Converting the time in IST to EST using ruby

I'm trying to convert the time which is in IST to EST using Ruby(NOT Rails). I tried different ways. But its returning the time in UTC. here is the example.
08/08/2014 01:45 AM
Is there any way to convert the above date into EST.
Try this
require 'time'
ist = Time.parse('08/08/2014 01:45 AM +05:30')
p ist
est = ist.getlocal("-05:00")
p est
Output
2014-08-08 01:45:00 +0530
2014-08-07 15:15:00 -0500
[Finished in 0.1s]
First I would check out a couple methods in the Time class in ruby's documentation http://ruby-doc.org/core-2.2.1/Time.html#method-i-2B
Specifically Time#now Time#strftime Time#-
To start off I am going to assume that you are in Indian Standard Time and would like to know what time it is for your friend in Eastern Standard Time. According to google.com.. IST is 9 and 1/2 hours ahead of EST. Which means you need to get your current time in IST and subtract 9.5 hours. See if this is what your looking for..
#Simple Method That Takes a Time Argument
#If you read correctly, Time#- uses seconds.
def to_est(ist)
(ist - 34200).strftime("%m/%d/%Y %I:%M%p")
end
#Calling the method
puts to_est(Time.now)
%m = Month
%d = Day
%Y = Year
%I = Hour
%M = Minute
%p = Meridian Indicator

Parse time with strptime using Time.zone

I am trying to parse a datetime with Time class in Ruby 2.0. I can't figure out how to parse date and get it in a specified timezone. I have used Time.zone.parse to parse a date where I first call Time.zone and set it to a specified timezone. In the below example, I set the zone but it does not effect strptime, I have tried doing Time.zone.parse(date) but I can't get it parse a date like the one below.
Time.zone = "Central Time (US & Canada)"
#=> "Central Time (US & Canada)"
irb(main):086:0> Time.strptime("08/26/2013 03:30 PM","%m/%d/%Y %I:%M %p")
#=> 2013-08-26 15:30:00 -0400
Time.zone isn’t a part of Ruby, it’s a part of ActiveSupport (which is included with Rails). As such, strptime does not know about Time.zone at all. You can, however, convert a normal Ruby Time into an ActiveSupport::TimeWithZone using in_time_zone, which uses Time.zone’s value by default:
require 'active_support/core_ext/time'
Time.zone = 'Central Time (US & Canada)'
time = Time.strptime('08/26/2013 03:30 PM', '%m/%d/%Y %I:%M %p')
#=> 2013-08-26 15:30:00 -0400
time.in_time_zone
#=> Mon, 26 Aug 2013 14:30:00 CDT -05:00
If you are only looking at Ruby2.0, you may find the time lib useful:
require 'time'
time.zone # return your current time zone
a = Time.strptime("08/26/2013 03:30 PM","%m/%d/%Y %I:%M %p")
# => 2013-08-26 15:30:00 +1000
a.utc # Convert to UTC
a.local # Convert back to local
# Or you can add/subtract the offset for the specific time zone you want:
a - 10*3600 which gives UTC time too
strptime gets its parameters from the time string. As such, the time string must contain time zone information.
If you are parsing time strings in a specific time zone, but the time strings that you receive do not have it embedded - then you can add time zone information before passing the time string to srtptime, and asking strptime to parse the time zone offset using %z or name using %Z.
In a nutshell, if you have a time string 08/26/2013 03:30 PM and you want it parsed in the UTC time zone, you would have:
str = '08/26/2013 03:30 PM'
Time.strptime("#{str} UTC}", "%m/%d/%Y %I:%M %p %Z")

How to get Rails to interpret a time as being in a specific time zone?

In Ruby 1.8.7, how to set the time zone of a time?
In the following examples, my system time zone is PST (-8:00 hours from UTC)
Given a time (21 Feb 2011, 20:45), presume that the time is in EST:
#this interprets the time as system time zone, i.e. PST
Time.local(2011,02,21,20,45)
#=> Mon Feb 21 20:45:00 -0800 2011
#this **converts** the time into EST, which is wrong!
Time.local(2011,02,21,20,45).in_time_zone "Eastern Time (US & Canada)"
#=> Mon, 21 Feb 2011 23:45:00 EST -05:00
But, the output I want is:
Mon Feb 21 20:45:00 -0500 2011 (Note the -0500 (EST) as opposed to -0800 (PST) and the hour is same, i.e. 20, not 23)
UPDATE (see the better version of this below)
I managed to get this to work, but I don't like it:
DateTime.new(2011,02,21,20,45).change :offset => -(300.0 / 1440.0)
# => Mon, 21 Feb 2011 20:45:00 +0500
Where
300 = 5 hrs x 60 minutes
1440 = number of minutes in a day
or the "right" way:
DateTime.civil(2011,02,21,20,45,0,Rational(-5, 24))
Question: Now, is there a way to determine the accurate(i.e. catering for daylight saving time etc) UTC offset from Time.zone so that I can pass it to the change method?
Reference: DateTime::change method
UPDATE (better version)
Thanks to #ctcherry for all the help!
Determine the accurate time zone info from Time.zone:
DateTime.civil(2011,02,21,20,45,0,Rational((Time.zone.tzinfo.current_period.utc_offset / 3600), 24))
In ruby 1.8.7 it doesn't appear to be very easy to do what are asking for according to the documentation:
http://www.ruby-doc.org/core-1.8.7/classes/Time.html
However in 1.9 it looks a lot easier by passing the timezone offset to the localtime() method on a Time object:
http://www.ruby-doc.org/core/classes/Time.html#M000346
UPDATE
The offset for Time.zone is easy since its an object on its own: (This is in a Rails console)
ruby-1.8.7-p248 :001 > Time.zone
=> #<ActiveSupport::TimeZone:0x103150190 #current_period=nil, #name="Central Time (US & Canada)", #tzinfo=#<TZInfo::TimezoneProxy: America/Chicago>, #utc_offset=nil>
ruby-1.8.7-p248 :002 > Time.zone.utc_offset
=> -21600
ruby-1.8.7-p248 :003 > Time.zone.formatted_offset
=> "-06:00"
So I think this will (almost) accomplish what you want:
require 'time'
t = "21 Feb 2011, 20:45"
Time.parse(t) # => Mon Feb 21 20:45:00 -0700 2011
t += " -05:00" # this is the trick
Time.parse(t) # => Mon Feb 21 18:45:00 -0700 2011
It still returns the time based on your system time zone, but the actual time is the correct time that you are seeking.
By the way, this is tested on 1.8.7-p334.

Resources