timezone aware vs. timezone naive in python - python

I am working with datetime objects in python. I have a function that takes a time and finds the different between that time and now.
def function(past_time):
now = datetime.now()
diff = now - past_time
When I initialized past_time before passing it to this function I initialized it as datetime naive. And now is also a datetime naive object. However when I try to call this function I get the error: can't subtract offset-naive and offset-aware datetimes. How come this is the case if they are both theoretically datetime naive objects?
Any help would be appreciated. Thanks!

datetime doesn't do any cross time zone calculations, because it's a complex and involved subject.
I suggest converting dates to UTC universally and performing maths on those.
I recently completed a project using timezones in a large python/Django project and after investigation went with converting everything internally to UTC and converting only on display to the user.
You should look into pytz to do the conversions to/from UTC, and store Olson codes for the timezones you want in your app - perhaps associated with each user, or appropriate to your program.

Use :
now = now.replace(tzinfo=past_time.tzinfo)
before diff = now - past_time.
so that both now and past_time have same tzinfo.
only if now and past_time intended to be in same timezone.

Related

How can I convert a UTC 24 hour time to another timezone? (Python)

I get a 24-hour UTC time from an API which I need to convert to a different timezone. Both the year, month, day, and minutes are completely redundant and useless to me.
This function would basically be like this website: https://www.worldtimebuddy.com/utc-to-aest-converter (in 24-hour mode) but dynamic and programmatic. If somebody can share how to do this conversion I can extrapolate it and create the function myself.
The timezone that I am converting to has to be able to be changed as if it was a parameter in the function. The result does not need to be a DateTime object, could just be an integer of the converted hour.
Thanks for helping! Python 3.9
I found a really simple way to do it.
transformed_time = (utc_time + shift) % 24
I originally just didn't know this is how timezones worked, but it works perfectly, if you don't know the 'shift' of your timezone, look up "UTC offset to your timezone".

Timestamp to non UTC Datetime object is substracting hours twice

I have the following timestamp 1550588656 which translates to 2019-02-19 15:04:16+00:00 in UTC time convention.
I want to convert it to my country's time convention (UTC or GMT -3 in this time of the year) so it should translate to 2019-02-19 12:04:16+00:00
I have read on other SO questions that first I have to convert the timestamp to an UTC aware Datetime object and then localize it, I'm doing it like this
# string format time
naive_datetime = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
# string parse time
naive_datetime = datetime.strptime(naive_datetime, "%Y-%m-%d %H:%M:%S")
# make naive Datetime object UTC aware
utc_datetime = naive_datetime.replace(tzinfo=pytz.UTC)
So now it's not a naive Datetime object, from here I should be able to localize it to my country's timezone. In Python that is pytz.timezone('America/Santiago')
So it should go something like this
cltime = pytz.timezone('America/Santiago')
local_datetime = utc_datetime.astimezone(cltime)
But I'm getting 2019-02-19 09:04:16-03:00 (UTC or GTM -6 ) as a result and I don't know why.
Can someone explain? My intuition tells me it's probably a simple thing I'm not looking at, but I've spent some minutes in it and I haven't been able to tell yet.
If you look at the documentation for fromtimestamp:
Return the local date and time corresponding to the POSIX timestamp
So the problem is that it is already doing a conversion from UTC to the local time, and you're doing it a second time.
First of all you have epoc time (UTC timestamp). You need to convert it into datetime object (native) which is followed by converting native time to aware time and than finally convert it to your local time.
Convert your timestamp to native datetime object
native_datetime = datetime.fromtimestamp(1550588656)
convert native datetime object to aware time (add timezone info, will add timezone info to native timezone UTC for current)
import pytz
utc_time = native_datetime.replace(tzinfo=pytz.timezone("UTC"))
localising aware datetime to your local datetime
local_time = utc_time.astimezone(pytz.timezone("America/Santiago"))
You can replace "America/Santiago" with your local time zone
I think this would help you to solve your problem. Thanks!

Converting local time to Zulu time in order to compare times

I have a DB with time entries formatted as follow:
2018-11-05T08:58:00Z
I'm trying to generate SQL queries to compare "now()" with the time in the DB to determine which row(s) to return.
I'm battling to "convert" my local time (now()) to an equivalent time format so that I can use < or > operations against the DB values.
Additionally, I am not sure if the problem has two parts. The example fo the time above is not in a "Datetime" field in MySQL but stored simply as TEXT, leaving me to suspect that I would need to "convert" the DB entries into another format first?
The following code, using the datetime module, works for me (tested in Python 3.6):
import datetime
value = "2018-11-05T08:58:00Z"
dt = datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
# Result is: datetime.datetime(2018, 11, 5, 8, 58)
This will convert your string values to datetime instances, which you can then compare to now(). The values that get created should be naive (meaning they have no associated timezone information).
However, if you are sure that now() for you is not UTC (aka Zulu time), you may need to do a conversion. This could be possible if, for example, you are using Django's timezone.now() and your configured timezone is something other than UTC. In this case, I might convert the result of now() to UTC, so you only have to convert one value. The pytz module can easily handle this kind of thing.
Check this :
import time
time = time.strftime('%Y-%m-%dT%H:%M:%SZ')
print(time)

Find the daylight savings status of a naive datetime given the timezone [duplicate]

This question already has answers here:
How to make a timezone aware datetime object
(15 answers)
Closed 6 years ago.
I've got a datetime which has no timezone information. I'm now getting the timezone info and would like to add the timezone into the existed datetime instance, how can I do?
d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')
How to add the timezone info tz into datetime a
Use tz.localize(d) to localize the instance. From the documentation:
The first is to use the localize() method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information):
>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500
If you don't use tz.localize(), but use datetime.replace(), chances are that a historical offset is used instead; tz.localize() will pick the right offset in effect for the given date. The US Eastern timezone DST start and end dates have changed over time, for example.
When you try to localize a datetime value that is ambiguous because it straddles the transition period from summer to winter time or vice-versa, the timezone will be consulted to see if the resulting datetime object should have .dst() return True or False. You can override the default for the timezone with the is_dst keyword argument for .localize():
dt = tz.localize(naive, is_dst=True)
or even switch off the choice altogether by setting is_dst=None. In that case, or in the rare cases there is no default set for a timezone, an ambiguous datetime value would lead to a AmbiguousTimeError exception being raised. The is_dst flag is only consulted for datetime values that are ambiguous and is ignored otherwise.
To go back the other way, turn a timezone-aware object back to a naive object, use .replace(tzinfo=None):
naivedt = awaredt.replace(tzinfo=None)
If you know that your original datetime was "measured" in the time zone you are trying to add to it, you could (but probably shouldn't) use replace rather than localize.
# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)
I can imagine 2 times when this might make sense (the second one happened to me):
Your server locale is set to the incorrect time zone and you are trying to correct a datetime instance by making it aware of this incorrect timezone (and presumably later localizing it to the "correct" time zone so the values of now() match up to other times you are comparing it to (your watch, perhaps)
You want to "tag" a time instance (NOT a datetime) with a time zone (tzinfo) attribute so that attribute can be used later to form a full datetime instance.

Difference between Python datetime vs time modules

I am trying to figure out the differences between the datetime and time modules, and what each should be used for.
I know that datetime provides both dates and time. What is the use of the time module?
Examples would be appreciated and differences concerning timezones would especially be of interest.
The time module is principally for working with Unix time stamps; expressed as a floating point number taken to be seconds since the Unix epoch. the datetime module can support many of the same operations, but provides a more object oriented set of types, and also has some limited support for time zones.
Stick to time to prevent DST ambiguity.
Use exclusively the system time module instead of the datetime module to prevent ambiguity issues with daylight savings time (DST).
Conversion to any time format, including local time, is pretty easy:
import time
t = time.time()
time.strftime('%Y-%m-%d %H:%M %Z', time.localtime(t))
'2019-05-27 12:03 CEST'
time.strftime('%Y-%m-%d %H:%M %Z', time.gmtime(t))
'2019-05-27 10:03 GMT'
time.time() is a floating point number representing the time in seconds since the system epoch. time.time() is ideal for unambiguous time stamping.
If the system additionally runs the network time protocol (NTP) dæmon, one ends up with a pretty solid time base.
Here is the documentation of the time module.
The time module can be used when you just need the time of a particular record - like lets say you have a seperate table/file for the transactions for each day, then you would just need the time.
However the time datatype is usually used to store the time difference between 2 points of time.
This can also be done using datetime, but if we are only dealing with time for a particular day, then time module can be used.
Datetime is used to store a particular data and time for a record. Like in a rental agency. The due date would be a datetime datatype.
Just noticed that time is more precise than datetime with an extra digit.
import time as tm
from datetime import datetime as dt
restime = tm.time()
resdtime = dt.timestamp(dt.now())
print("TIME:".rjust(10," "),restime)
print("DATETIME:".rjust(10," "),resdtime)
Output
TIME: 1637357103.7650678
DATETIME: 1637357103.765067

Categories

Resources