简体   繁体   中英

trouble understanding time conversions

I have some trouble understanding time conversions in python. I have two identical time_struct objects

In [22]: local_dt
Out[22]: datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
In [23]: local_dt.timetuple()                                                                                                                             
Out[24]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

When I feed it to the time.mktime function on one machine

time.mktime(local_dt.timetuple())

it returns 946681200.0

On a second machine I get a different answer

In [31]: local_dt.timetuple()                                                                                                                             
Out[31]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

In [32]: time.mktime(local_dt.timetuple())                                                                                                                
Out[32]: 946684800.0

The machines have different timezones, though:

In [44]: time.tzname                                                                                                                                      
Out[44]: ('Europe', 'Europe')

In [45]: time.tzname
Out[45]: ('CET', 'CEST')

The documentation on the time module says:

Use the following functions to convert between time representations: struct_time in local time seconds since the epoch mktime()

As I understand my local time is "America/Los_Angeles" so seconds since epoch should be exactly the same and not be depending on the system configuration.

What am I misunderstanding? How do I have to calculate the timestamp correctly then?

time.mktime() interprets the timetuple based on the local machine's timezone. Notice how your timetuple object doesn't contain any timezone info, so the timestamp created will always vary based on timezone set on the local machine. Thus it's entirely understandable why the same time.mktime(local_dt.timetuple()) returns different value on those two machines.

You can use local_dt.timestamp() instead, while both are essentially the same ...

Naive datetime instances are assumed to represent local time and this method relies on the platform C mktime() function to perform the conversion.

... But since you're creating the timestamp directly from the non-naive datetime object, it still retains the timezone info and can shift the time accordingly:

For aware datetime instances, the return value is computed as:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

Observe:

>>> est = datetime.datetime(1999, 12, 31, 19, 0).astimezone(pytz.timezone('EST'))
>>> utc = est.astimezone(pytz.timezone('UTC'))
>>> est
datetime.datetime(1999, 12, 31, 19, 0, tzinfo=<StaticTzInfo 'EST'>)
>>> utc
datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<UTC>)
>>> est.timestamp()
946684800.0           
>>> utc.timestamp()
946684800.0           # same as est
>>> time.mktime(est.timetuple())
946684800.0
>>> time.mktime(utc.timetuple())
946702800.0           # different than est

The last time.mktime() processed utc.timetuple() as a local time since the timezone info was not passed. You can notice it's offset by 18000 ( time.timezone for EST, my time zone).

As you said : "The machines have different timezones, though:" and doc said: "in local time".

Your "local time" is not the same on both machine : one is Europe/europe (probably GMT, so UTC+0), the other one is CEST (UTC +1).

see https://www.timeanddate.com/time/zones/eu

Central European Time (CET) is 1 hour ahead of Coordinated Universal Time (UTC). This time zone is in use during standard time in: Europe, Africa.

I think you want to convert your datetime into "UTC+0 datetime"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM