Working with Time and Dates in Python
written on Wednesday, September 14, 2011
When working with time and date values, Python provides more than one interface.
| Module | Description |
|---|---|
| time | Low-level time methods. Supports struct_time format, simple date string IO, conversion to UNIX epoch time. |
| datetime | High-level date and time methods. This provides a proper interface for adding or subtracting time and dates. Many of the same methods from the time module are supported, but objects are not compatible between the two. |
Until you spend some time with both modules, it will be a little unclear how to make the best use of each feature set. Here are a few examples that will demonstrate some of the available techniques.
Convert 'Naive' Datetime to Unix Epoch
This conversion works if you are working in your local time zone.
>>> from datetime import datetime
>>> import time
>>> time.time()
1316032256.260053
>>> now = datetime.now()
>>> int( time.mktime(now.timetuple()) )
1316032260
Convert 'Aware' Datetime to Unix Epoch
In a more advanced case, you might want to compute a Unix time value of a datetime that is outside of your local timezone. For this example 'US/Eastern' is not my local timezone.
>>> from datetime import datetime
>>> from calendar import timegm
>>> from pytz import timezone
>>> import time
>>> time.time()
1317696751.797751
>>> est = timezone('US/Eastern') # non-local time zone
>>> now_naive = datetime.now()
>>> now_aware = datetime.now(tz=est)
>>> time.mktime(now_aware.timetuple()) # wrong, ignores TZ info
1317718351.0
>>> time.mktime(now_aware.utctimetuple()) # wrong, ignores TZ info
1317732751.0
>>> timegm(now.timetuple()) # wrong, no TZ info set
1317660506
>>> timegm(now.utctimetuple()) # wrong, no TZ info set
1317660506
>>> timegm(now_aware.timetuple()) # wrong, expects UTC time
1317682351
>>> timegm(now_aware.utctimetuple()) # correct
1317696751
The results show that even though now_naive and now_aware are created at the same time, there is only one valid method to convert now_aware back to the correct Unix time value.
Find Last Occurrence of a Specific Day
This examples demonstrates how to get the date of "Last Sunday" or "Last Tuesday". This could be easily modified to other relative dates.
from datetime import datetime,timedelta
import time
def last_day(day_name):
days_of_week = ['sunday','monday','tuesday','wednesday',
'thursday','friday','saturday']
target_day = days_of_week.index(day_name.lower())
delta_day = target_day - datetime.now().isoweekday()
if delta_day >= 0: delta_day -= 7 # go back 7 days
return datetime.now() + timedelta(days=delta_day)
Output of the above method is shown when current date was Wednesday, 9/14/2011:
>>> datetime.now()
datetime.datetime(2011, 9, 14, 10, 45, 55, 958258)
>>> for d in ['sunday','monday','tuesday','wednesday',
... 'thursday','friday','saturday']:
... last_day(d)
...
datetime.datetime(2011, 9, 11, 10, 47, 1, 851355)
datetime.datetime(2011, 9, 12, 10, 47, 1, 851425)
datetime.datetime(2011, 9, 13, 10, 47, 1, 851446)
datetime.datetime(2011, 9, 7, 10, 47, 1, 851466)
datetime.datetime(2011, 9, 8, 10, 47, 1, 851486)
datetime.datetime(2011, 9, 9, 10, 47, 1, 851506)
datetime.datetime(2011, 9, 10, 10, 47, 1, 851526)