A detailed explanation of time zone processing in Python

Source: Internet
Author: User
Tags current time datetime documentation time zones sunrise time what timezone timedelta in python

When a user of an application is spread all over the world, the Code of the program is not necessarily dealing with the time zone. The server-side timing task for the user needs to be set to the time zone of the user.

In glow nurture, a typical example is: If the user does not record the prenatal vitamin, two days later 9 o'clock to send the user a notification in the program to take vitamin. A straightforward program requirement is to get a timestamp of the time zone of the corresponding server in the time zone of a user's 21.

What does Python offer?

Python provides datetime, time, calendar modules, and then thanks to Stuart Bishop Stuart@stuartbishop.net
, we still have pytz to use.

Due to the existence of DateTime module, Time module, in the DateTime module and the existence of DateTime class, a time class, in order to avoid the misunderstanding of the reading, the following says, DateTime refers to the module, Datetime.time, Datetime.datetime refers to the time class and the DateTime class under the DateTime module.

The DateTime module defines the following classes:

Datetime.date-Idealized Date object, assuming the use of Gree Gaolei, has year, month, day three attributes

Datetime.time-idealized time object, regardless of leap seconds (that is, think the day is always 24*60*60 seconds), there are hour, minute, second, microsecond, tzinfo five attributes

Combination of Datetime.datetime-datetime.date and datetime.time

Datetime.timedelta-A class that we'll use later, representing the difference between two datetime.date, Datetime.time or Datetime.datetime.

Datetime.tzinfo-time zone information

*python 3.2 started with the Datetime.timezone class, but we still use 2.7 for the time being, and the following code is run with the 2.7 version test.

The time module provides a variety of methods for changing the timing of operations.

The Calendar module is a method that provides calendars related.

The Pytz module, using Olson TZ database, solves the problem of time zone compute consistency across platforms and solves the computational problems of daylight savings. Because countries and regions can choose their own time zones and whether to use daylight savings, the Pytz module will have to update its own time zone and daylight savings-related information if necessary. For example, the current Pytz version of Olson_verson = ' 2013g ', is included Morocco can use daylight saving time.

How to be right for what you're using

This is not a digression, the client must properly collect the user's timezone information. A more common mistake is to save the offset value of the time zone where the user is in. For example, for China's time zone, save +8. In fact, the area where the user is located (the same time offset, may correspond to more than one country or region). And if the user's time zone has daylight saving time, the offset value is going to change at the start and end of daylight saving year.

We can use the Pytz module to see what timezone are currently in the world. This is a very long list. We can find our own ' Asia/shanghai '. Using Pytz.timezone

(' Asia/shanghai ') constructs a Tzinfo object.
>>> Import Pytz
>>> Pytz.all_timezones
[... ' Asia/shanghai ', ...]
>>> pytz.timezone (' Asia/shanghai ')
<dsttzinfo ' Asia/shanghai ' lmt+8:06:00 std>
We're starting to put timezone into the transition of time.

First, the conversion of Timestamp and DateTime. Timestamp, a number that represents the number of seconds since the UTC time of 1970/01/01.

>>> from datetime import datetime
>>> datetime.fromtimestamp (0, Pytz.timezone (' UTC '))
Datetime.datetime (1970, 1, 1, 0, 0, tzinfo=<utc>)
>>> tz  = Pytz.timezone (' Asia/shanghai ')
& gt;>> tz2 = Pytz.timezone (' Us/eastern ')
>>> datetime.fromtimestamp (0, TZ)
Datetime.datetime ( 1970, 1, 1, 8, 0, Tzinfo=<dsttzinfo ' Asia/shanghai ' cst+8:00:00 std>)
>>> datetime.fromtimestamp (0, TZ 2)
Datetime.datetime (1969, 0, Tzinfo=<dsttzinfo ' us/eastern ' EST-1 day, 19:00:00 std>)
We can see Tim Estamp is bound in UTC. Given a timestamp, the corresponding result is the same time, regardless of the time zone in which the DateTime is built. But there's a hole in Python.

>>> ts = 1408071830
>>> dt = datetime.fromtimestamp (ts, TZ)
Datetime.datetime (2014, 8, 3, Tzinfo=<dsttzinfo ' Asia/shanghai ' cst+8:00:00 std>)
>>> Time.mktime (Dt.timetuple ())
>>> Dt.timetuple ()
Time.struct_time (tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=11, tm_min=3, tm_sec=50, tm_wday=4, tm_yday=227, TM_ISDST =0)
>>> Dt.astimezone (PYTZ.UTC)
Datetime.datetime (2014, 8, 3, 3, M, tzinfo=<utc>)
>>> Time.mktime (Dt.astimezone (PYTZ.UTC). Timetuple ())
The Mktime method of time module supports obtaining Timestamp,datetime objects from Timetuple can be directly converted to timetuple. The direct use of Time.mktime (Dt.timetuple ()) appears to be a natural way to get timestamp. But we notice that the Timetuple method is to directly take the current time of the month and a minute directly from the date. So this conversion process loses time zone information in the timetuple of this method. According to timestamp's definition, the correct approach is to explicitly convert a DateTime object to UTC time using Asttimezone.

Second, datetime and date, and Time's relational datetime modules also provide a DateTime object, a Date object, or an objects. The relationship between them can be easily seen from the following code.

>>> d = datetime.date (2014, 8, 20)
>>> t = datetime.time (11, 30)
>>> dt = Datetime.datetime.combine (d, T)
Datetime.datetime (2014, 8, 20, 11, 30)
>>> Dt.date ()
Datetime.date (2014, 8, 20)
>>> Dt.time ()
Datetime.time (11, 30)
>>> dt = Datetime.datetime.fromtimestamp (1405938446, Pytz.timezone (' UTC '))
Datetime.datetime (2014, 7, tzinfo=<utc>)
>>> Dt.date ()
Datetime.date (2014, 7, 21)
>>> Dt.time ()
Datetime.time (10, 27, 26)
>>> Dt.timetz ()
Datetime.time (tzinfo=<utc>)
>>> Datetime.datetime.combine (Dt.date (), Dt.time ())
Datetime.datetime (2014, 7, 21, 10, 27, 26)
>>> Datetime.datetime.combine (Dt.date (), Dt.timetz ())
Datetime.datetime (2014, 7, tzinfo=<utc>)
Simply put, DateTime can get date and time objects, and datetime and time objects can take timezone information. The date and time objects can be merged using Datetime.datetime.combine to obtain a DateTime object.

Third, the date of the addition and subtraction Datetime,date objects can be used to timedelta.

Look at the code directly

>>> D1 = Datetime.datetime (2014, 5, 20)
>>> D2 = D1+datetime.timedelta (Days=1, hours=2)
>>> D1
Datetime.datetime (2014, 5, 20, 0, 0)
>>> D2
Datetime.datetime (2014, 5, 21, 2, 0)
>>> x = d2-d1
>>> x
Datetime.timedelta (1, 7200)
>>> X.seconds
>>> x.days
How to correctly set timezone information on a DateTime object

Look at the code first.

>>> DDT1 = Datetime.datetime (2014, 8, 0, 0, 0, pytz.timezone (' Asia/shanghai '))
>>> DDT1
Datetime.datetime (2014, 8, 0, Tzinfo=<dsttzinfo ' Asia/shanghai ' lmt+8:06:00 std>)
>>> DDT2
Datetime.datetime (2014, 8, 20, 11, 0)
>>> Ddt1.astimezone (PYTZ.UTC)
Datetime.datetime (2014, 8, 1, tzinfo=<utc>)
>>> Ddt2.astimezone (PYTZ.UTC)
Valueerror:astimezone () cannot is applied to a naive datetime
>>> TZ = TimeZone (' Asia/shanghai ')
>>> tz.localize (DDT1)
Valueerror:not naive datetime (Tzinfo is already set)
>>> tz.localize (DDT2)
Datetime.datetime (2014, 8, one, 0, tzinfo=<dsttzinfo ' Asia/shanghai ' cst+8:00:00 std>)
The valueerror thrown out here introduces the concept of a naive datetime. Simply put, naive datetime is a DateTime object that does not know the time zone information. DateTime without timezone information is theoretically unable to locate a specific point in time. So for a DateTime object that has a timezone set, you can use the Astimezone method to set the timezone to another. For datetime objects that do not contain timezone, use the Timezone.localize method to set the timezone.

But did you find a problem here? We clearly set the 11 o'clock, the use of Astimezone after running out a 54 points is how to do?

We note that the DateTime object constructed with the timezone datetime directly into the TimeZone object and the DateTime objects constructed using the Locallize method are displayed differently when printed tzinfo, and one is LMT +8:06, one is cst+8:00, needless to say, 54 points on the left here. The LMT is a scientific name for local Mean times, which is used to compare the average sunrise time. Interested can look at the Shanghai and Urumqi LMT time. CST is Standard time, no need to explain. According to Pytz's documentation,

Unfortunately using the Tzinfo argument of the standard datetime constructors ' does not work ' with Pytz for many Es.

It is safe for timezones without daylight saving transitions though, such as UTC:

The preferred way of dealing with the times are to always work in UTC, converting to localtime only if generating output to B e read by humans.


You can take shortcuts when dealing with the UTC side of timezone conversions. Normalize () and localize () are not really necessary when there are no daylight saving time transitions to deal with.

Let's try it again, like this, this time Pytz.timezone (' Asia/shanghai ') has no more moths to play with.

>>> x = Datetime.datetime (2014, 8, 0, 0, 0, PYTZ.UTC)
>>> x
Datetime.datetime (2014, 8, 0, tzinfo=<utc>)
>>> X.astimezone (Pytz.timezone (' Asia/shanghai '))
Datetime.datetime (2014, 8, 0, Tzinfo=<dsttzinfo ' Asia/shanghai ' cst+8:00:00 std>)
So the safest way to do this is to use the Locallize method to construct the time zone.

Incidentally, it is mentioned that the normalize is used to correct the time that the calculation occurred across DST, or to see the documentation, the key part of the excerpt is as follows:

This library differs the documented Python API for TZINFO implementations; If you want to create local Wallclock t IMEs you need to use the localize () method documented in this document. In addition, if your perform date arithmetic on the local times that cross DST boundaries, the Mezone (ie. subtract 1 minute from 2002-10-27 1:00 est and/get 2002-10-27 0:59 est instead of the correct 2002-10-27 1 : () EDT). A normalize () method was provided to correct this. Unfortunately these issues cannot are resolved without modifying the Python datetime implementation.
back to the original question, my program needs to give users two days after 21 points to send a notice, how to calculate this time?

>>> Import Pytz
>>> Import Time
>>> Import datetime
>>> TZ = Pytz.timezone (' Asia/shanghai ')
>>> user_ts = Int (Time.time ())
>>> D1 = Datetime.datetime.fromtimestamp (user_ts)
>>> d1x = tz.localize (D1)
>>> d1x
Datetime.datetime (2015, 5, 1, tzinfo=<dsttzinfo, Asia/shanghai ' cst+8:00:00 std>)
>>> D2 = d1x + Datetime.timedelta (days=2)
>>> D2
Datetime.datetime (2015, 5, 1, tzinfo=<dsttzinfo, Asia/shanghai ' cst+8:00:00 std>)
>>> d2.replace (hour=21, minute=0)
>>> D2
Datetime.datetime (2015, 5, 0, Tzinfo=<dsttzinfo, Asia/shanghai ' cst+8:00:00 std>)
The basic step is to build the correct time d1x based on the timestamp and time zone information, use Timedelta to add and subtract the time, and replace the hour information with the Replace method.

Summing up, basically time related to these methods, most of you can directly according to their own needs encapsulated into a separate utility module, and then no longer need to take care of it. What you have to do is to have at least one person take care of the right thing first.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.