I have added timezones to my datetime column in my postgreSQL DB.
Now I have the error above everytime I want to compare dates.
On some points I have JSON requests, datetime objects are passed as strings, so I need to parse them, with the additonal timezone info I get:
ValueError: time data '2018-05-02 11:52:26.108540+02:00'
does not match format '%Y-%m-%d %H:%M:%S.%f+%Z'
Earlier I had:
2018-05-02 11:52:26.108540
which worked perfectly with:
%Y-%m-%d %H:%M:%S.%f
The new information which has been added is: +02:00
In the strptime docu it is telling me to use %z or %Z but it does not work.
EDIT:
I am using Python 3
The issue is the offset +02:00 you need to remove the colon ':' then it will work:
In[48]:
dt.datetime.strptime('2018-05-02 11:52:26.108540+0200', '%Y-%m-%d %H:%M:%S.%f%z')
Out[48]: datetime.datetime(2018, 5, 2, 11, 52, 26, 108540, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
So you would need to go through all your datetime strings and remove this in order for strptime to parse it correctly
You need to remove the colon and use the small %z for this to work.
>>> s = '2018-05-02 11:52:26.108540+02:00'
>>> fmt = %Y-%m-%d %H:%M:%S.%f%z'
>>> time.strptime(s, fmt)
time.struct_time(tm_year=2018, tm_mon=5, tm_mday=2, tm_hour=11, tm_min=52, tm_sec=26, tm_wday=2, tm_yday=122, tm_isdst=-1)
Related
Trying to parse a datetime string to unix:
from calendar import timegm
from datetime import datetime
print(timegm(datetime.strptime(('2021-07-21 00:00:07.223977216+00:00'), '%Y-%m-%d %H:%M:%S.%f')))
Results in
ValueError: time data '2021-07-21 00:00:07.223977216+00:00' does not match format '%Y-%m-%d %H:%M:%S.%f+00:00'
Tried a lot, cant get anywhere so far ...
Your date is in ISO format, so you can use datetime.fromisoformat:
>>> from datetime import datetime
>>> datetime.fromisoformat("2021-07-21 00:00:07+00:00")
datetime.datetime(2021, 7, 21, 0, 0, 7, tzinfo=datetime.timezone.utc)
So if you look at the format of the date time you are providing, it does not have the fractional seconds the formatter is looking for:
# '2021-07-21 00:00:07+00:00' <- this date time
# '%Y-%m-%d %H:%M:%S.%f' <- in this format, is parsing like below
# 'YYYY-MM-DD HH:MM:SS.ff' (note the ff part is missing, then there's a +00:00 part leftover so the format is breaking)
If you don't need the microseconds, remove the '.%f' part from your format string. Otherwise, if you're parsing a series of values where some have the fractional part, you're going to need to give both options:
try:
timestamp = datetime.strptime(your_string_here, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
timestamp = datetime.strptime(your_string_here, '%Y-%m-%d %H:%M:%S')
I tried this:
timestamp = "2021-01-22T11:36:52.387000+01:00"
timestampObject = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S')
But gave me error:
ValueError: unconverted data remains: .150000+01:00
What is the rest reprisenting and how do I convert the rest? Also what does the 'T' mean?
Because you also have to supply a format specifier to take care of the trailing microseconds and timezone specifier, like the error is telling you, see Conversion of datetime string with microseconds and ...milliseconds. Probably you need '.fZ'. See the datetime doc.
Also, the 'T' just stands for 'Time'; it separates the date-field from the time-field, for ease in parsing (with sed/perl/grep/regex/etc.). Makes it easy if you wanted to a) locate datetimes within a log or b) throw away/separate the time part from the date part.
The string format you have is actually a datetime in ISO format. Luckily datetime has a function for handling that, you don't have to worry about supplying a format specifier for the trailing time objects...
Do you want only the date?
>>> datetime.datetime.fromisoformat("2021-01-22T11:36:52.387000+01:00").date()
datetime.date(2021, 1, 22)
Or do you want datetime?
>>> datetime.datetime.fromisoformat("2021-01-22T11:36:52.387000+01:00")
datetime.datetime(2021, 1, 22, 11, 36, 52, 387000, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))
This worked for me:
timestampObject = datetime.fromisoformat(
"2021-01-22T11:36:52.387000+01:00" ).date()
print('timestampObject.year: ', timestampObject.year)
timestampObject.year: 2021
I have the following python snippet:
from datetime import datetime
timestamp = '05/Jan/2015:17:47:59:000-0800'
datetime_object = datetime.strptime(timestamp, '%d/%m/%y:%H:%M:%S:%f-%Z')
print datetime_object
However when I execute the code, I'm getting the following error:
ValueError: time data '05/Jan/2015:17:47:59:000-0800' does not match format '%d/%m/%y:%H:%M:%S:%f-%Z'
what's wrong with my matching expression?
EDIT 2: According to this post, strptime doesn't support %z (despite what the documentation suggests). To get around this, you can just ignore the timezone adjustment?:
from datetime import datetime
timestamp = '05/Jan/2015:17:47:59:000-0800'
# only take the first 24 characters of `timestamp` by using [:24]
dt_object = datetime.strptime(timestamp[:24], '%d/%b/%Y:%H:%M:%S:%f')
print(dt_object)
Gives the following output:
$ python date.py
2015-01-05 17:47:59
EDIT: Your datetime.strptime argument should be '%d/%b/%Y:%H:%M:%S:%f-%z'
With strptime(), %y refers to
Year without century as a zero-padded decimal number
I.e. 01, 99, etc.
If you want to use the full 4-digit year, you need to use %Y
Similarly, if you want to use the 3-letter month, you need to use %b, not %m
I haven't looked at the rest of the string, but there are possibly more mismatches. You can find out how each section can be defined in the table at https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
And UTC offset is lowercase z.
I am trying to parse and extract values from my time data 2018-03-11 13:15:31.734874+01:00.
I'm using strptime() to do this with the %Y %m %d %H:%M:%S.%f %Z format but I am getting this error:
ValueError: time data '2018-03-11 13:15:31.734874+01:00' does not match format '%Y %m %d %H:%M:%S.%f %Z'
Also, I don't know how to handle the +1:00 in my time data. Can anyone help?
There are two problems here to solve.
First is the format string. It should be %Y-%m-%d %H:%M:%S.%f%z to match exact date separators and timezone sequence (without space).
From strftime and strptime Behavior:
%z (lower case) UTC offset in the form +HHMM or -HHMM (empty string if the object is naive). (empty), +0000, -0400, +1030
Second is the colon (:) in timezone offset '+01:00'. That can be left out using substring: s[:-3]+s[-2:] or string substitute.
So the final answer is as below.
from datetime import datetime
s = '2018-03-11 13:15:31.734874+01:00'
datetime.strptime(s[:-3]+s[-2:], '%Y-%m-%d %H:%M:%S.%f%z')
%Y %m %d should be changed to %Y-%m-%d to match with the time string. Also, you need to remove the last : from the input to use with %z.
Here is how you should do:
import datetime
s = '2018-03-11 13:15:31.734874+01:00'
print(datetime.datetime.strptime(''.join(s.rsplit(':', 1)), '%Y-%m-%d %H:%M:%S.%f%z'))
# 2018-03-11 13:15:31.734874+01:00
At first:
%Y %m %d will not match 2018-03-11. You need to adapt it to the time string! %Y-%m-%d instead should work.
Secondly:
IF you are in python3, the %z was added for time stamps. However the timestamp has to be without the colon, e.g. +0100instead of +01:00. Therefore, if you use python3 this works:
>>> time_string = '2018-03-11 13:15:31.734874+01:00'
>>> time_string = ''.join(time_string.rsplit(':', 1))
>>> datetime.datetime.strptime(time_string, '%Y-%m-%d %H:%M:%S.%f%z')
datetime.datetime(2018, 3, 11, 13, 15, 31, 734874, tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))
Btw the time_string after the editing looks like that:
>>> time_string
'2018-03-11 13:15:31.734874+0100'
IF you are in python2, the %z won't work, here you have to use the parse function of the dateutil module, which is straight forward.
>>> from dateutil.parser import parse
>>> parse('2018-03-11 13:15:31.734874+01:00')
datetime.datetime(2018, 3, 11, 13, 15, 31, 734874, tzinfo=tzoffset(None, 3600))
I have a datetime object with integer number of seconds (ex: 2010-04-16 16:51:23). I am using the following command to extract exact time
dt = datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S.%f
(generically, I have decimals (ex: 2010-04-16 16:51:23.1456) but sometimes I don't. So when I run this command, I get an error message
ValueError: time data '2010-04-16 16:51:23' does not match format '%Y-%m-%d %H:%M:%S.%f'
How do I go about resolving this?
It's because you don't have the format you specified. You have the format:
'%Y-%m-%d %H:%M:%S'
There are multiple solutions. First, always generate the data in the same format (adding .00 if you need to).
A second solution is that you try to decode in one format and if you fail, you decode using the other format:
try:
dt = datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
dt = datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S')
Another way avoiding using the exception handling mechanism is to default the field if not present and just try processing with the one format string:
from datetime import datetime
s = '2010-04-16 16:51:23.123'
dt, secs = s.partition('.')[::2]
print datetime.strptime('{}.{}'.format(dt, secs or '0'), '%Y-%m-%d %H:%M:%S.%f')
if you're using the latest python (3.2+) simple-date will do this kind of thing for you:
>>> from simpledate import *
>>> SimpleDate('2010-04-16 16:51:23.1456')
SimpleDate('2010-04-16 16:51:23.145600', tz='America/Santiago')
>>> SimpleDate('2010-04-16 16:51:23')
SimpleDate('2010-04-16 16:51:23', tz='America/Santiago')
it works by extending the python template format. so you could also write (it's not needed because ISO8601-like formats are handled by default):
>>> SimpleDate('2010-04-16 16:51:23', format='Y-m-d H:M:S(.f)?')
SimpleDate('2010-04-16 16:51:23', tz='America/Santiago')
see how the fractional seconds are (.f)? like a regexp - means it's optional (also, it will add % signs if there are none).
PS and you can access the datetime via an attribute. if you wanted to discard the tzinfo (which is taken from the locale by default - i live in chile, hence America/Santiago above) to get a naive datetime:
>>> SimpleDate('2010-04-16 16:51:23').naive.datetime
datetime.datetime(2010, 4, 16, 16, 51, 23)