Python: UTC vs local timestamp - python

Why the followings return different timestamp? Is it because datetime.utcnow() doesn't have a timezone? It looks to me that tzinfo=utc is redudant, so I am probably not getting what is utcnow() and how an UTC number could not have a timezone. I guess there is a reason, so please enlight me :)
from datetime import datetime
from pytz import utc
local_seconds = int(datetime.utcnow().timestamp())
utc_seconds = int(datetime.utcnow().replace(tzinfo=utc).timestamp())
My goal is to get the UTC timestamp. It looks like the first method returns the local timestamp (correct me if I am wrong)
EDIT:
Where I live the timezone is GMT-5. In fact:
(utc_seconds-local_seconds)/3600 # is equal to -5.0

Following two statements would always return different result.
local_seconds = int(datetime.utcnow().timestamp())
utc_seconds = int(datetime.utcnow().replace(tzinfo=utc).timestamp())
Output:
1585584790
1585604590
You ask why? Because, by the time first statement executes, there is some time spent during execution and now the second statement would fetch you different result because datetime.utcnow() for 2nd statement has changed.
What I assume is, you want to see if both operations would give the same result or not? They definitely would have given the same results :
Had you provided them the same input?
Had you performed the similar operation from a common library.
To solve 1. change your code like this.
same_time_input = datetime.utcnow()
local_seconds = int(same_time_input.timestamp())
utc_seconds = int(same_time_input.replace(tzinfo=utc).timestamp())
Still the output would not be same, because you are using an external library, and the replace function is not working as you expected.
If you printout the tzinfo from same_time_input, you would see that it doesn't have any timezone info reason of which can be read here. --> Why does datetime.datetime.utcnow() not contain timezone information?
print(same_time_input.tzinfo)
Now, you are trying to give it a timezone info using a separate library which has different implementation internally resulting in slightly off results.

Related

How do I convert a struct_time output into DD/MM/YY, Hour:Minute:Second format?

I'm relatively uninitiated when it comes to Python, and I'm trying to figure out how to take an output I'm getting from a sensor into proper day, month, year and hour, minute, second format.
An example of the output, which also includes a basic counter (the first output), and a timestamp (the third output) is shown below:
(305, struct_time(tm_year=2022, tm_mon=11, tm_mday=9, tm_hour=16, tm_min=42, tm_sec=8, tm_wday=2, tm_yday=313, tm_isdst=-1), 7.036)
I've seen a lot of questions and answers for this, but I'm left feeling kind of stumped on all of them because I'm not sure how to take the output I have (real_time, which gives a struct_time output) and turn it into this format. Any help (and understanding about my lack of fluency in this field) would be really appreciated!
time.strftime exists for exactly this purpose:
import time
now_local = time.localtime()
fmt = "%d/%m/%Y %H:%M:%S"
out = time.strftime(fmt, now_local)
print(out)
However, two words of warning:
time.struct_time is not "timezone aware". This will turn out to matter when you least expect it. Unless you are very sure that you know the timezone of the incoming data, and have the correct safeguards in your application and database for managing time zone iformation, use the datetime.datetime class instead.
D/M/Y date format can be ambiguous. Y-M-D format is substantially safer. It is not ambiguous in any widely-used locale, and it has the extra benefit that lexical ordering of Y-M-D strings is also a correct ordering of the dates that they represent. This format is laid out by RFC 3339 and has become widely accepted as the standard, correct formatting for datetime strings.
So as it turns out, I was able to find a solution after all. Essentially I just used this function:
def _format_datetime(datetime):
return "{:02}/{:02}/{} {:02}:{:02}:{:02}".format(
datetime.tm_mon,
datetime.tm_mday,
datetime.tm_year,
datetime.tm_hour,
datetime.tm_min,
datetime.tm_sec,
)
And then applied it to the struct_time output as such (with real_time being said output):
real_time = time.localtime()
current_time = time.monotonic()
formatted_time = _format_datetime(real_time)
Hopefully this helps other people using CircuitPython for similar purposes!

How to force time in datetime field when saving a record in odoo?

In my odoo module, I have a datetime field (prefered_date). What I want to do is that, no matter what time the user enters, the time is always set at 10 am. I tried to do it with the following code. but is not working. The time is getting set to 6 am instead of 10. Maybe it has something to do with the timezone. What am I doing wrong?
#api.multi
def write(self, values):
if 'prefered_date' in values:
date = datetime.strptime(values.get('prefered_date'), '%Y-%m-%d %H:%M:%S')
newdate = date.replace(hour=10, minute=0)
new = newdate.strftime("%Y-%m-%d %H:%M:%S")
values['prefered_date'] = new
return super(PostabilidadRequest, self).write(values)
One thing I'm missing in your question is where you're seeing this 6 am value: do you see this in the browser, or in python?
I'm guessing you're seeing this value in the browser. Any date objects in the database are stored as UTC and the front-end will use the user's timezone to show the right (local) time. Could it be you are in a time zone that is in UTC-4? In that case a value of 10 am in your python code / database will show as 6 am in the browser.
What you can try is to enter 10 am as the value in the front-end and use a print(date) in your python code to see how this value is being received by your code. Then adjust this accordingly, so if you enter 10 am in the front-end and it turns into 6 am in the python code, you change your code to date.replace(hour=6, minute=0) to adjust for this time difference.
Do keep in mind this might give some odd results if you have users from different time zones as they won't all have a four hour offset.
As a unrelated side-note: the .get() function in values.get('preferred_date') is used to gracefully return None when the value does not exists (instead of throwing an exception). But as you already checked for the existence of the value (if 'preferred_date' in values) you know there will be some value there and you can safely use values['preferred_date'] directly.

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)

How does python know if daylight savings time is in effect?

Since the start and end times of DST in a timezone can change every year, so how does python tell if dst is in effect or not?
At the very top of the CPython source code for the datetime module, it gives the source of the data:
"""Concrete date/time and related types. See
http://www.iana.org/time-zones/repository/tz-link.html for time zone
and DST data sources. """
Presumably this may be variable over time.
Actually my old answer was wrong. In the python shell you can do:
>>> import time
>>>time.localtime()
here it will show a result
>>> _.tm_isdst
This question is actually a duplicate but the old post can be found here:
Python daylight savings time

timezone aware vs. timezone naive in 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.

Categories

Resources