Error using strptime, strftime while converting date to epoch - ruby

I am trying to extract dates from csv file and convert them to epoch time
CSV.foreach(File.path("month.csv")) do |row|
dateper=row[0].split(',')[0]
p DateTime.strptime(dateper,"%m/%d/%y %I:%M:%S %p %z").strftime("%s")
end
I am getting invalid date (ArgumentError) as the result. However, if I print out dateper, choose one of the outputs randomly and cop-paste it in place of dateper in line 3, I get an epoch value. What am I doing wrong? dateper is of string value, and strptime minus strftime seems to give an output.
month.csv sample:
7/26/13 12:00:00 AM -05:00,62.2,63.02,62.07,63.02,5.00168E+07
8/23/13 12:00:00 AM -05:00,71.84,71.93,71.36,71.6,5.55304E+07
8/26/13 12:00:00 AM -05:00,71.56,72.91,71.52,71.87,8.26536E+07
8/27/13 12:00:00 AM -05:00,71.16,71.81,69.49,69.82,1.058488E+08
Could someone help me with this?

You have some malformed dates somewhere. Use rescue to avoid the script choking on them.
CSV.foreach(File.path("month.csv")) do |row|
dateper=row[0].split(',')[0]
p DateTime.strptime(dateper,"%m/%d/%y %I:%M:%S %p %z").strftime("%s") rescue p "malformed date:#{dateper} on line #{$.}"
end
This will allow the script to continue and show you the bad dates.

Related

Ruby Date Time Subtraction

I am trying to calculate the exact duration a process took from some log file result. After parsing the log, I reached at the following stage:
my_array = ["Some_xyz_process", "Start", "2018-07-12", "12:59:53,397", "End", "2018-07-12", "12:59:55,913"]
How can I subtract the start date and time from the end date and time in order to retrieve the exact duration the process took?
my_array = ["Some_xyz_process",
"Start", "2018-07-12", "12:59:53,397",
"End", "2018-07-12", "12:59:55,913"]
require 'date'
fmt = '%Y-%m-%d%H:%M:%S,%L'
is = my_array.index('Start')
#=> 1
ie = my_array.index('End')
#=> 4
DateTime.strptime(my_array[ie+1] + my_array[ie+2], fmt).to_time -
DateTime.strptime(my_array[is+1] + my_array[is+2], fmt).to_time
#=> 2.516 (seconds)
See DateTime#strptime and DateTime# (the latter for format directives). As long as the date and time formats are known I always prefer strptime to parse. Here's an example of why:
DateTime.parse 'Theresa May has had a bad week over Brexit'
#=> #<DateTime: 2018-05-01T00:00:00+00:00 ((2458240j,0s,0n),+0s,2299161j)>`.
You can concat the date and time field and use Time.parse to convert it to a time object and then calculate the difference in number of seconds
Time.parse('2018-07-12 12:59:55,397').to_i - Time.parse('2018-07-12 12:59:53,913').to_i
Hope this helps

Matching Date formatted: "January 17, 2017 10:30 AM" in Ruby

I have been trying to use Date/DateTime to validate that a given date is in the correct format.
str = "January 17, 2017 10:30 AM"
temp = DateTime.strptime(str, '%B %-d, %y %l:%M %p')
but am getting the error
`strptime': invalid date (ArgumentError)
I have been able to split the string into ""January 17," "2017 10:30 AM" and validate it without issue, but I would really like to know why I can't just use strptime on the whole string, or what I am doing wrong if it can be done.
This error is happening because according to the docs of DateTime#strptime:
Parses the given representation of date and time with the given template, and creates a date object. strptime does not support specification of flags and width unlike strftime.
And your format includes a value of %-d which is a width parameter, hence the exception. If you try a basic invocation like:
DateTime.strptime(str, '%B %d, %Y')
you'll see it works. Also, you'll want uppercase-Y for the full 4-digit year.
In a nutshell: you'll need to adjust your format string
This format works fine :
temp = DateTime.strptime(str, '%B %d, %Y %l:%M %p')
#<DateTime: 2017-01-17T10:30:00+00:00 ((2457771j,37800s,0n),+0s,2299161j)>

Rails 4 parse a date in a different language

I have a text_field :birthday_line in my user form, that I need to parse into the user's birthday attribute.
So I'm doing something like this in my User class.
attr_accessor :birthday_line
before_save :set_birthday
def set_birthday
self.birthday = Date.strptime(birthday_line, I18n.translate("date.formats.default")
end
But the problem is that for some reason it gives me an error saying Invalid date when I try to pass in a string 27 января 1987 г. wich should be parsed to 1987-01-27.
The format and month names in my config/locales/ru.yml
ru:
date:
formats:
default: "%d %B %Y г."
month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
seem to be correct.
Date.parse also doesn't help, it just parses the day number (27) and puts the month and year to todays date (so it'll be September 27 2013 instead of January 27 1987).
I had the same problem and what I can suggest:
string_with_cyrillic_date = '27 Января 1987'
1)create array of arrays like this
months = [["января", "Jan"], ["февраля", "Feb"], ["марта", "Mar"], ["апреля", "Apr"], ["мая", "May"], ["июня", "Jun"], ["июля", "Jul"], ["августа", "Aug"], ["сентября", "Sep"], ["октября", "Oct"], ["ноября", "Nov"], ["декабря", "Dec"]]
2) Now you can iterate this and find your cyrillic month:
months.each do |cyrillic_month, latin_month|
if string_with_cyrillic_date.match cyrillic_month
DateTime.parse string_with_cyrillic_date.gsub!(/#{cyrillic_month}/, latin_month)
end
end
And now you will receive the date that you expect
27 Jan 1987

ROR + Ruby Date From XML API

By using XML API, I got date-time as "2008-02-05T12:50:00Z". Now I wanna convert this text format into different format like "2008-02-05 12:50:00". But I am getting proper way.
I have tried this one :: #a = "2008-02-05T12:50:00Z"
Steps
1. #a.to_date
=> Tue, 05 Feb 2008
2. #a.to_date.strftime('%Y')
=> "2008"
3. #a.to_date.strftime('%Y-%m-%d %H:%M:%S')
=> "2008-02-05 00:00:00
Suggest some thing ?
The to_date method converts your string to a date but dates don't have hours, minutes, or seconds. You want to use DateTime:
require 'date'
d = DateTime.parse('2008-02-05T12:50:00Z')
d.strftime('%Y-%m-%d %H:%M:%S')
# 2008-02-05 12:50:00
Use Ruby's DateTime:
DateTime.parse("2008-02-05T12:50:00Z") #=> #<DateTime: 2008-02-05T12:50:00+00:00 (353448293/144,0/1,2299161)>
From there you can output the value in any format you want using strftime. See Time#strftime for more info.

What am I doing wrong with DateTime.strptime?

My ruby program says that my date is invalid when I do that:
format = "%D/%M/%Y %H:%M:%S:3N"
date = "21/03/2011 16:39:11.642"
DateTime.strptime(time, format)
I have also tried this one:
format = "%D/%M/%Y %H:%M:%S:3"
All I get is this:
ArgumentError: invalid date
from /usr/local/lib/ruby/1.9.1/date.rb:1688:in `new_by_frags'
from /usr/local/lib/ruby/1.9.1/date.rb:1713:in `strptime'
from (irb):12
from /usr/local/bin/irb:12:in `<main>'
It looks like you were getting strptime's format directives confused. Notice how %M is in format twice, once representing the month and the next time representing the minute?
%D means the date as %m / %d / %y.
%d means the day of the month [01,31]
%M means the minute [00,59]
%m means the month number [01,12]
This should work:
format = "%d/%m/%Y %H:%M:%S"
date_time = "21/03/2011 16:39:11.642"
puts DateTime.strptime(date_time, format) #=> 2011-03-21T16:39:11+00:00
Here's a strptime reference
Try to use
datetime.to_date.strftime(format)
or
datetime.to_time

Resources