Python datetime function - one pending aspect still from my earlier question - python-datetime

Earlier someone answered my question on Python's datetime function which I am grateful to. However my followup comment/ question remains unanswered. Please help.
My followup question:
Thank you so much. Your answer helped. It works. However when you give 2 digit year with %y and you try to print the year with date.year, it prints prefix of 20xx (e.g. 2023 in my example below). If I wanted it to print 19xx what should I do?
Original question:
datetime.strptime not working as portrayed widely. Using Python 3.11
I see several posts talking about datetime.datetime.strptime that can be used to convert date string '12/13/23' to a datetime object. This doesn't work for me.
import datetime dt = datetime.datetime.strptime('12/13/2023', "%m/%d/%y") produces error as follows
Traceback (most recent call last): File "C:\Users\User\IdeaProjects\FirstTest\Scratchpad.py", line 3, in dt = datetime.datetime.strptime('12/13/2023', "%m/%d/%y") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib_strptime.py", line 568, in _strptime_datetime tt, fraction, gmtoff_fraction = _strptime(data_string, format) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib_strptime.py", line 352, in _strptime raise ValueError("unconverted data remains: %s" % ValueError: unconverted data remains: 64
Many people show the above code with output working as 2023-12-13 as a datetime object. Doesn't work for me
I was expecting dt.month() to return the month and print(dt) to print yyyy-mm-dd
Answer:
Your code doesn't show the same code that you're running as your traceback.
Your code, which works:
dt = datetime.datetime.strptime('12/13/23', "%m/%d/%y")
Your traceback, which doesn't work:
dt = datetime.datetime.strptime('12/13/2023', "%m/%d/%y")
The traceback is correct to produce an error here, the format string you've given is not valid for the date string you've given. %y parse 2-digit year, and 2023 is not a 2-digit year, you need %Y if you want to parse a 4-digit year.

Related

convert Calendar date to Julian Date in Unix

I have one requirement. in one of the source file I'm getting calendar date as input and while processing the file it has to convert Julian Date format. I just need a Script.
ex:Date: 10-Nov-2020
Julian Date: 2020314
The easiest way is
date -d 10-Nov-2020 +%Y%j
but it seems to count from 1, not 0, so it returns 2020315.
Perl's Time::Piece can be used to get the expected value:
perl -MTime::Piece -lwe '$t = localtime->strptime(shift, "%d-%b-%Y"); print $t->year, $t->yday' -- 10-Nov-2020
You might need sprintf "%03d", $t->yday instead of just $t->yday if you want 2020000 instead of 20200 for the first day.

Hanami validate year less than X

I want to check that a date object I have in a validator.rb file has a year field that is less than the year 10000.
required(:my_date_object).maybe(
:date?,
lt?: '10000-01-01'
)
When running system tests, the following error shows up:
ArgumentError:
comparison of Date with String failed
Should I look into converting the date field into a string using to_s or something similar and then doing a regexp format check? Or is there a more straightforward way of checking that the date is less than the year 10000?
You need to create a Date for the lt?.
You can write it like follows:
required(:my_date_object) { lt?(Date.new(10000, 1, 1)) }

Changing the format from a mySQL datetime format to a different type in ruby?

I am attempting to change an SQL datetime variable (2016-06-09 14:29:34) into a format that looks like this (00:00_20160601). I have tried to follow a couple of SO questions that will allow me to format a Time object.
This is what I have done so far:
start_datetime = "2016-06-09 14:29:34"
t =Time.new(start_datetime)
t.strftime("%H:%M_%Y%d%m")
This results in the time being formatted to 2016-01-01 00:00:00 +0000, which is obviously not what I want. I was wondering if someone could help me format the datetime object the way I specified?
You can do this with DateTime:
require 'datetime'
DateTime.parse("2016-06-09 14:29:34").strftime("%H:%M_%Y%d%m")
#=> "14:29_20160906"
The format you're feeding in is basically ISO-8601 so it's parsed by default.
Feeding that value into Time.new is completely incorrect. The first argument there is the year, the rest have to be supplied separately. That's why you get 2016-01-01, since everything else comes out as defaults.
Time.new is converting automatically and the result of "2016-06-09 14:29:34".to_i is 2016.
It's not entirely clear why your day value changes from 09 in the input to 01 in the desired output, so I'll use the normal thing and output the same as was input:
require 'time'
start_datetime = "2016-06-09 14:29:34"
t = Time.strptime(start_datetime, '%Y-%m-%d %H:%M:%S')
t.strftime('00:00_%Y%m%d') # => "00:00_20160609"
Since the hours and minutes are being thrown away there are a couple of other ways to go about this.
Ignore the hours and minutes when parsing:
t = Time.strptime(start_datetime, '%Y-%m-%d')
Or use a Date object instead of a Time object:
require 'date'
start_datetime = "2016-06-09 14:29:34"
t = Date.strptime(start_datetime, '%Y-%m-%d')
t.strftime('00:00_%Y%m%d') # => "00:00_20160609"

Ruby local_to_utc returns invalid year

I have the following date string ('US/Eastern'), which I need to convert to UTC:
date_src = '2014-07-07T23:10:00+0'
First I convert it to a "valid" format so I can operate it on later processes. I use the following to have an iso version of the date:
date = DateTime.parse(date_src).iso8601
At this point date is a nice '2014-07-07T23:10:00+00:00'. The last step on my process is to translate this date to UTC. I'm using the following:
TZInfo::Timezone.get('US/Eastern').local_to_utc(date)
The problem is this is giving me 20014 as output, instead of the UTC version of the original date. If I try:
TZInfo::Timezone.get('UTC').local_to_utc(date)
I get 2014, which is the correct year but still unexpected output.
Any ideas about what I'm doing wrong, and what I could use to solve the problem?
local_to_utc actually expects a Time or a DateTime instance:
TZInfo::Timezone.get('US/Eastern').local_to_utc(DateTime.parse(date_src))
# => #<DateTime: 2014-07-08T03:10:00+00:00 ((2456847j,11400s,0n),+0s,2299161j)>
From the documentation, you can have a hint on what actually happened:
All methods in TZInfo that operate on a time can be used with either Time or DateTime instances or with nteger timestamps (i.e. as returned by Time#to_i). The type of the values returned will match the the type passed in.
What actually happens is the local_to_utc calls to_i on the input parameter, which on a string returns the parsed integer from the beginning of the string (2014 in your case since date is the string 2014-07-07T23:10:00+00:00), and adds the time difference to it - 18000 for "US/Eastern" (5 hour difference), and 0 for UTC:
date.to_i
# => 2014
TZInfo::Timezone.get('US/Eastern').local_to_utc(date) - date.to_i
# => 18000
TZInfo::Timezone.get('UTC').local_to_utc(date) - date.to_i
# => 0
So the bottom line is - kind of serendipitously you saw this weird behavior, which stems from the compilation of some surprising quirks of the APIs you used...

How to split the string obtained from "Time.now" in ruby

A=Time.now
gives following output:
2012:05:18 12:20:50 +0530
I want to form a string like "May 18 , 2012". I tried changing A to string which was not possible. How can I achieve this?
Time.now.strftime('%b %e , %Y')
More info.
You can have a look at the Time Class, and method strftime.
It formats time according to the directives in the given format string.
http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime
For your current problem:
Time.now.strftime("%b %d, %Y")

Resources