I have some timestamp data from a database and I need to convert it to a Python datetime (in tuple format). How can I do that?
For instance, I need to convert 2013-04-16 16:31:35.649+05:30 format to datetime(2013, 4, 16, 16, 31, 35).
I am trying to do the, Django, new user registration part of the project and whenever the user submits the data and registers then he gets an verification email but whenever the user clicks the verification link then, it produces the following error:
can't compare offset-naive and offset-aware datetimes
from dateutil import parser
dt = parser.parse("2013-04-16 16:31:35.649+05:30")
# dt == datetime.datetime(2013, 4, 16, 16, 31, 35, 649000, tzinfo=tzoffset(None, 19800))
dt.astimezone(pytz.utc).replace(tzinfo=None)
returns datetime.datetime(2013, 4, 16, 11, 1, 35, 649000) which is the same instant in UTC and without tzinfo (offset-naive).
If you want to store datetime objects without tzinfo, then store it in UTC.
Large parts of the world use daylight saving time, which makes some offset-naive datetimes ambiguous. UTC does not have these problems.
Related
The dateutil.rrule module has an rrule class which has a custom __str__ method to convert its instances to strings, and a rrulestr function which does the opposite, namely, convert the string back to an object.
It seems, however, that the _dtstart attribute of the rrule loses its timezone information when converting to a string and back. For example, in the following script:
from dateutil.rrule import rrule, rrulestr, DAILY
from dateutil.parser import parse
start = parse("8 Feb 2017 14:00 UTC")
my_rrule = rrule(DAILY, dtstart=start)
my_rrule2 = rrulestr(str(my_rrule))
assert my_rrule._dtstart == my_rrule2._dtstart
the assertion leads to a
TypeError: can't compare offset-naive and offset-aware datetimes
Specifically, I noticed that my_rrule.dtstart has the representation
datetime.datetime(2017, 2, 8, 14, 0, tzinfo=tzutc())
whereas my_rrule2._dtstart is
datetime.datetime(2017, 2, 8, 14, 0)
Why is the timezone information lost? Is this not a deficiency in the __str__/rrulestr combination?
I want to convert a string into datetime, the string is parsed as such:
Metatime = datetime.datetime.strptime(metadata.get("FileModifyDate"), "%y:%m:%d %H:%M:%S")
Where metadata.get returns something like this:
2012:11:19 14:53:44-05:00
I have another datatime element that I want to compare with, so the formating should be the same. The other datetime element is like this:
(datetime.datetime(2014, 3, 26, 23, 22, 21)
How can I format things to be able to do a logical comparison?
Python's standard datetime.strptime() method does not support parsing timezone info in hh:mm format. There is an open feature request for that.
Meanwhile, you can use the following work-around:
>>> FileModifyDate = '2012:11:19 14:53:44-05:00'
>>> datetime.strptime(FileModifyDate.replace(':', ''), '%Y%m%d %H%M%S%z')
datetime.datetime(2012, 11, 19, 14, 53, 44, tzinfo=datetime.timezone(datetime.timedelta(-1, 68400)))
>>> print(_)
2012-11-19 14:53:44-05:00
Note that you need to us Python version 3.3 or later for this to work.
Now, if you want to compare the result to
>>> another_date = datetime(2014, 3, 26, 23, 22, 21)
you need to know what timezone that date is in. If it is in UTC - do
>>> file_date = datetime.strptime(FileModifyDate.replace(':', ''), '%Y%m%d %H%M%S%z')
>>> another_date.replace(tzinfo=timezone.utc) > file_date
True
If it is in some other zone, you will need to use a third party library such as pytz to convert it to an aware instance before you can compare.
I am using db.time property to save time required for a conversion:
my_model.conversion_time = time_taken = datetime.datetime.strptime(str(conversion_end - conversion_start), "%H:%M:%S.%f").time()
but when i see the data in datastore viewer , it is stored as datetime object with date of 1970-01-01. Does anybody know how I can just save the time in the datastore
I'm not sure why you have two inline assignments, but to get time out of a timedelta object:
>>> b
datetime.datetime(2013, 7, 15, 10, 21, 31, 599402)
>>> a
datetime.datetime(2013, 7, 15, 10, 18, 11, 251477)
>>> str(b-a)
'0:03:20.347925'
>>> (datetime.datetime.min + (b-a)).time()
datetime.time(0, 3, 20, 347925)
In order to store only the time, you need to use TimeProperty in your datastore. It will be represented internally as datetime, but will store datetime.time() objects.
I have come across the following code:
datetime.datetime.utcnow().replace(tzinfo=tzutc())
I can't see what the replace() call is doing, from reading the docs it seems to convert it into a UTC timestamp - but surely utcnow() would return a UTC timestamp.
datetime.datetime.utcnow()
# returns datetime.datetime(2013, 4, 4, 10, 39, 1, 303329)
gives you the current datetime in UTC without tzinfo information:
.replace(tzinfo=tzutc())
# returns datetime.datetime(2013, 4, 4, 10, 39, 1, 303329, tzinfo=<UTC>)
adds this tzinfo information to the datetime object.
You can get the same (current datetime in UTC with UTC tzinfo) using:
datetime.datetime.now(pytz.utc)
# returns datetime.datetime(2013, 4, 4, 10, 39, 1, 303329, tzinfo=<UTC>)
This just calls datetime.replace(), this particular usage is mentioned a lot on that documentation page.
It's useful since datetime.datetime.utcnow() returns a datetime without time zone information (tzinfo will be None): the replace() call is used to change that.
I'm implementing feature with scheduled publishing of object.
User chooses the time to publish and i created a cron task to run every minute and check if it's the time to publish.
Users are from different timezones.
So i need to compare two datetimes:
>>user_chosen_time
datetime.datetime(2012, 12, 4, 14, 0, tzinfo=tzinfo(120))
>>curdate=datetime.datetime.now()
datetime.datetime(2012, 12, 4, 18, 4, 20, 17340)
>>user_chosen_time==curdate
*** TypeError: can't compare offset-naive and offset-aware datetimes
Sorry for rather stupid question but i need to discuss this. Thanks
As the error suggests you "can't compare offset-naive and offset-aware datetimes". It means that you should compare two datetimes that are both timezone-aware or both timezone-naive (not timezone-aware). In your codes, curdate has no timezone info and thus could not be compared with user_chosen_time which is timezone-aware.
First you should assign correct timezone to each datetime. And then you could directly compare two datetimes with different timezones.
Example (with pytz):
import pytz
import datetime as dt
# create timezone
nytz=pytz.timezone('America/New_York')
jptz=pytz.timezone('Asia/Tokyo')
# randomly initiate two timestamps
a=dt.datetime(2018,12,13,11,2)
b=dt.datetime(2018,12,13,22,45)
# assign timezone to timestamps
a=nytz.localize(a)
b=jptz.localize(b)
# a = datetime.datetime(2018, 12, 13, 11, 2, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
# b = datetime.datetime(2018, 12, 13, 22, 45, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
a>b # True
b>a # False
For other methods you could refer to Convert a python UTC datetime to a local datetime using only python standard library?.
http://pytz.sourceforge.net/ is where you want to look when you want to eliminate the timezone differencies :)
edit: just found this post on SO that may give you a lot more informations on your problem