convert String to DateTime - ruby

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

Related

How to convert UTC to EST/EDT in Ruby?

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"

Rails DateTime gives invalid date sometimes and not others

I've got a bunch of user-inputted dates and times like so:
date = "01:00pm 06/03/2015"
I'm trying to submit them to a datetime column in a database, and I'm trying to systemize them like this:
DateTime.strptime(date, '%m/%d/%Y %H:%M')
But I consistently get an invalid date error. What am I doing wrong? If I submit the string without strptime the record will save but it sometimes gets the date wrong.
Also, how can I append a timezone to a DateTime object?
Edit:
So .to_datetime and DateTime.parse(date) work for the date string and fail for date2. What's going on?
date2 = "03:30pm 05/28/2015"
Try using to_datetime:
date.to_datetime
# => Fri, 06 Mar 2015 13:00:00 +0000
Also if you read the documentation for DateTime#strptime, here. It states:
Parses the given representation of date and time with the given
template, and creates a date object.
Its important to note that the template sequence must match to that of input string sequence, which don't in your case - leading to error.
Update
Using to_datetime over second example will generate
ArgumentError: invalid date
This is because it expects the date to be in dd-mm-yy format. Same error will be raised for DateTime.parse as to_datetime is nothing but an api for the later. You should use strptime in-case of non-standard custom date formats. Here:
date2 = "03:30pm 05/28/2015"
DateTime.strptime(date2, "%I:%M%p %m/%d/%Y")
# => Thu, 28 May 2015 15:30:00 +0000
date = "01:00pm 06/03/2015"
DateTime.parse(date)
=> Fri, 06 Mar 2015 13:00:00 +0000
You haven't got your parameters in the correct order.
DateTime.strptime(date, '%H:%M%p %m/%d/%Y')
You'll also need to add %p for the am/pm suffix

convert ruby date to string without losing format

I'm trying to convert a Ruby Date object to a string. The format of the date is: Sun, 15 Sep 2013
However, when I convert it to a string using #to_s it gives me the following: "2013-09-15"
Instead, I want it to become: "Sun, 15 Sep 2013"
Use Date#strftime there are so many options
require 'date'
date = Date.parse("Sun, 15 Sep 2013") # => #<Date: 2013-09-15 ((2456551j,0s,0n),+0s,2299161j)>
date.strftime("%a, %d %b %Y") # => "Sun, 15 Sep 2013"
strftime works well, however, if you find that you're using the same format in multiple places, you will find using the Rails Date#to_formatted_s method a more appropriate option. You can use the built-in formats:
date.to_formatted_s(:short)
date.to_formatted_s(:long)
or, you can create your own formats, adding them to Date::DATE_FORMATS:
Date::DATE_FORMATS[:my_format] = '%a, %d %b %Y'
date.to_formatted_s(:my_format)
This will keep you from spreading formatting strings throughout your app.

Converting string to ruby datetime

I have the following string as a date
Thu 17 Jan
I want to convert this to a ruby date time object (to save in the database). I have tried chronic, but without luck.
Can someone help me out, thanks in advance
No need for chronic. Simple Date will do.
require 'date'
s = 'Thu 17 Jan'
Date.parse(s) # => #<Date: 2013-01-17 ((2456310j,0s,0n),+0s,2299161j)>
You may also use:
s = 'Thu 17 Jan'
date = DateTime.parse(s)

How do I get Ruby to parse time as if it were in a different time zone?

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

Resources