I have a time in the format 2020-03-15 02:00:00 UTC, and I was curious how in Ruby I could convert this into something readable and in PST time, such as March 15th, 2020 7:00:00 PM PST? Preferably without any gems in plain Ruby.
You can use DateTime.strptime(string, format) to parse the utc string into a datetime object and then use strftime(format) to format it how you want. Something like:
date = DateTime.strptime("2020-03-15 02:00:00 UTC", "%Y-%m-%d %H:%M:%S UTC")
formatted_date = date.strftime("...")
https://apidock.com/ruby/DateTime/strftime
Related
How do I convert UTC timestamp in the format '2009-02-02 00:00:00' to EST/EDT in Ruby? Note that I am not using Rails, instead it is a simple Ruby script.
1If the date range falls between EST (usually Jan-Mid March) it needs to to UTC-5hrs. For EDT it is UTC-4hrs.
So far I have the following function to convert UTC to EST/EDT.
def utc_to_eastern(utc)
eastern = Time.parse(utc) # 2009-02-02 00:00:00 -0500
offset_num = eastern.to_s.split(" -")[1][1].to_i # 5
eastern_without_offset = (eastern-offset_num*60*60).strftime("%F %T") # 2009-02-01 19:00:00
return eastern_without_offset
end
puts utc_to_eastern("2009-02-02 00:00:00") # 2009-02-01 19:00:00
puts utc_to_eastern("2009-04-02 00:00:00") # 2009-04-01 20:00:00
The above code does what I want, however there's two issues with my solution:
I do not want to reinvent the wheel, meaning I do not wish to write the time conversion functionality instead use existing methods provided by Ruby. Is there a more intuitive way to do this?
The parsing uses my local timezone to convert UTC to EST/EDT, however I would like to explicitly define the timezone conversion ("America/New_York"). Because this means someone running this on a machine on central time would not be using EST/EDT.
The best approach would be to use TZInfo.
require 'tzinfo'
require 'time'
def utc_to_eastern utc
tz = TZInfo::Timezone.get("America/New_York")
tz.to_local(Time.parse(utc)).strftime('%Y-%m-%d %H:%M:%S')
end
utc_to_eastern "2020-02-02 00:00:00 UTC" => "2020-02-01 19:00:00"
utc_to_eastern "2020-04-02 00:00:00 UTC" => "2020-04-01 20:00:00"
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
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")
I'm parsing something like this:
11/23/10 23:29:57
which has no time zone associated with it, but I know it's in the UTC time zone (while I'm not). How can I get Ruby to parse this as if it were in the UTC timezone?
You could just append the UTC timezone name to the string before parsing it:
require 'time'
s = "11/23/10 23:29:57"
Time.parse(s) # => Tue Nov 23 23:29:57 -0800 2010
s += " UTC"
Time.parse(s) # => Tue Nov 23 23:29:57 UTC 2010
credit from https://rubyinrails.com/2018/05/30/rails-parse-date-time-string-in-utc-zone/,
Time.find_zone("UTC").parse(datetime)
# => Wed, 30 May 2018 18:00:00 UTC +05:30
If your using rails you can use the ActiveSupport::TimeZone helpers
current_timezone = Time.zone
Time.zone = "UTC"
Time.zone.parse("Tue Nov 23 23:29:57 2010") # => Tue, 23 Nov 2010 23:29:57 UTC +00:00
Time.zone = current_timezone
It is designed to have the timezone set at the beginning of the request based on user timezone.
Everything does need to have Time.zone on it, so Time.parse would still parse as the servers timezone.
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
Note: the time format you have above was no longer working, so I changed to a format that is supported.
If you are using ActiveSupport [from Rails, e.g], you can do this:
ActiveSupport::TimeZone["GMT"].parse("..... date string")
Another pure Ruby (no Rails) solution if you don't want/need to load ActiveSupport.
require "time"
ENV['TZ'] = 'UTC'
Time.parse("2019/10/01 23:29:57")
#=> 2019-10-01 23:29:57 +0000
An aliter to #Pete Brumm's answer without Time.zone set/unset
Time.zone.parse("Tue Nov 23 23:29:57 2010") + Time.zone.utc_offset
Without rails dependencies: Time parses in local time but DateTime parses in UTC. Then you can transform it to a Time class if that's what you want:
require 'date'
DateTime.parse(string_to_parse).to_time
Rails adds utc method on datetime objects to return the utc time:
Time.parse('10:10').utc
I need to parse following String into a DateTime Object:
30/Nov/2009:16:29:30 +0100
Is there an easy way to do this?
PS: I want to convert the string above as is. The colon after the year is not a typo. I also want to solve the problem with Ruby and not RoR.
Shouldn't this also work for Rails?
"30/Nov/2009 16:29:30 +0100".to_datetime
DateTime.strptime allows you to specify the format and convert a String to a DateTime.
I have had success with:
require 'time'
t = Time.parse(some_string)
This will convert the string in date to datetime, if using Rails:
"05/05/2012".to_time
Doc Reference: https://apidock.com/rails/String/to_time
I used Time.parse("02/07/1988"), like some of the other posters.
An interesting gotcha was that Time was loaded by default when I opened up IRB, but Time.parse was not defined. I had to require 'time' to get it to work.
That's with Ruby 2.2.
convert string to date:
# without timezone
DateTime.strptime('2012-12-09 00:01:36', '%Y-%m-%d %H:%M:%S')
=> Sun, 09 Dec 2012 00:01:36 +0000
# with specified timezone
DateTime.strptime('2012-12-09 00:01:36 +8', '%Y-%m-%d %H:%M:%S %z')
=> Sun, 09 Dec 2012 00:01:36 +0800
refer to:
https://ruby-doc.org/stdlib-3.1.1/libdoc/date/rdoc/Date.html
in Ruby 1.8, the ParseDate module will convert this and many other date/time formats. However, it does not deal gracefully with the colon between the year and the hour. Assuming that colon is a typo and is actually a space, then:
#!/usr/bin/ruby1.8
require 'parsedate'
s = "30/Nov/2009 16:29:30 +0100"
p Time.mktime(*ParseDate.parsedate(s)) # => Mon Nov 30 16:29:30 -0700 2009
You can parse a date time string with a given timezone as well:
zone = "Pacific Time (US & Canada)"
ActiveSupport::TimeZone[zone].parse("2020-05-24 18:45:00")
=> Sun, 24 May 2020 18:45:00 PDT -07:00