Datetime - Basics

Time conversions are generally a pain, especially when daylight savings time is involved. Here a number of libraries and tools to deal with this in Python. Firstly, there are three libraries

The datetime module supplies classes for manipulating dates and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is on efficient attribute extraction for output formatting and manipulation. For related functionality, see also the time and calendar modules.

  • time - another standard module, with unclear delineation to the previous one

This module provides various time-related functions. For related functionality, see also the datetime and calendar modules.

This module allows you to output calendars like the Unix cal program, and provides additional useful functions related to the calendar.

  • pytz - an additional module that deals with proper timezones, along the lines of London/Europe

pytz brings the Olson tz database into Python. This library allows accurate and cross platform timezone calculations using Python.


In [1]:
from datetime import datetime as dt
import time as tm
import pytz as tz
import calendar as cal

Generating times from a string

The format definition is here. The result is either an object, or a timetuple struct, depending on the module.

dt.strptime(), tm.strptime(), [dt].timetuple()

In [2]:
dto = dt.strptime ('2014-09-06 07:16 +0000', "%Y-%m-%d %H:%M %z")
dto


Out[2]:
datetime.datetime(2014, 9, 6, 7, 16, tzinfo=datetime.timezone.utc)

In [3]:
tto = tm.strptime ('2014-09-06 07:16 +0000', "%Y-%m-%d %H:%M %z")
tto


Out[3]:
time.struct_time(tm_year=2014, tm_mon=9, tm_mday=6, tm_hour=7, tm_min=16, tm_sec=0, tm_wday=5, tm_yday=249, tm_isdst=-1)

In [4]:
dto.timetuple() == tto


Out[4]:
True

In [5]:
dt.fromtimestamp(tm.mktime(tto))


Out[5]:
datetime.datetime(2014, 9, 6, 7, 16)

Missing timezone information in the string

Timezone information can be added to the datetime after it has been created without it


In [6]:
dto = dt.strptime('2014:09:13 21:07:15', '%Y:%m:%d %H:%M:%S')
timezone = tz.timezone('Europe/London')
dto = timezone.localize(dto)
dto


Out[6]:
datetime.datetime(2014, 9, 13, 21, 7, 15, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
tm.gmtime(), tm.time(), tm.mtime()

In [7]:
epoch_time = 0
tm.gmtime(epoch_time)


Out[7]:
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)

In [8]:
epoch_time = tm.time()
tm.gmtime(epoch_time)


Out[8]:
time.struct_time(tm_year=2014, tm_mon=9, tm_mday=15, tm_hour=10, tm_min=10, tm_sec=44, tm_wday=0, tm_yday=258, tm_isdst=0)

In [9]:
tm.gmtime(tm.mktime(tto))


Out[9]:
time.struct_time(tm_year=2014, tm_mon=9, tm_mday=6, tm_hour=7, tm_min=16, tm_sec=0, tm_wday=5, tm_yday=249, tm_isdst=0)
time()

In [10]:
tm.time()


Out[10]:
1410775844.2894523

In [11]:
dt.now()


Out[11]:
datetime.datetime(2014, 9, 15, 10, 10, 44, 300490)

In [12]:
dt.now().strftime('%Y-%m-%d %H:%M:%S %Z%z')


Out[12]:
'2014-09-15 10:10:44 '

Time output

Depending on the library, strftime is either a function or a method. The format string is here

tm.strftime(), [dt].strftime()

In [13]:
tm.strftime("%Y-%m-%d %H:%M",tto)


Out[13]:
'2014-09-06 07:16'

In [14]:
dto.strftime("%Y-%m-%d %H:%M")


Out[14]:
'2014-09-13 21:07'

In [15]:
dto.hour, dto.minute, dto.second,


Out[15]:
(21, 7, 15)

In [16]:
dto.tzname()


Out[16]:
'BST'

Time Zones

tz.timezone(), [dt].astimezone(), [tz].normalize()

In [17]:
from datetime import datetime as dt
import pytz as tz

def change_tz(datetime_obj, tz_str):
    """ change the timezone
    
    datatime_obj - a datetime.datetime object representing the time
    tz_str - time zone string, eg 'Europe/London'
    
    return - a datetime.datetime object
    """
    the_tz = tz.timezone(tz_str)
    the_dt = the_tz.normalize(datetime_obj.astimezone(the_tz))
    return the_dt

In [18]:
ams = tz.timezone('Europe/Amsterdam')
dto_ams = ams.normalize(dto.astimezone(ams))
dto_ams.strftime('%Y-%m-%d %H:%M:%S %Z%z')


Out[18]:
'2014-09-13 22:07:15 CEST+0200'

In [19]:
dto_ams2 = change_tz(dto, "Europe/Amsterdam")
dto_ams2


Out[19]:
datetime.datetime(2014, 9, 13, 22, 7, 15, tzinfo=<DstTzInfo 'Europe/Amsterdam' CEST+2:00:00 DST>)

In [20]:
dto_ams2.timetuple()


Out[20]:
time.struct_time(tm_year=2014, tm_mon=9, tm_mday=13, tm_hour=22, tm_min=7, tm_sec=15, tm_wday=5, tm_yday=256, tm_isdst=1)