Next Chapter: Python, Pandas and Timeseries
Python, Date and Time
Introduction
Python provides rich functionalities for dealing with date and time data. The standard libraries contains the modules
- time
- calendar
- datetime
These modules supply classes for manipulating dates and times in both simple and complex ways.
Especially, the datetime class will be very important for the timeseries of Pandas.
Python Standard Modules for Time Data
The most important modules of Python dealing with time are the modules time
,
calendar
and datetime
.
The datetime module provides various classes, methods and functions to deal with dates, times, and time intervals.
The datetime module provides the following classes:
- The instances of the date class represent dates, whereas the year can range between 1 and 9999.
- The instances of the datetime class are made up both by a date and a time.
- The time class implements time objects.
- The timedelta class is used to hold the differences between two times or two date objects.
- The tzinfo class is used to implement timezone support for time and datetime objects.
Let's start with a date object.
The Date Class
from datetime import date
x = date(1993, 12, 14)
print(x)
We can instantiate dates in the range from January 1, 1 to December 31, 9999. This can be inquired from the attributes min
and max
:
from datetime import date
print(date.min)
print(date.max)
We can apply various methods to the date instance above. The method toordinal returns the proleptic Gregorian ordinal. The proleptic Gregorian calendar is produced by extending the Gregorian calendar backward to dates preceding its official introduction in 1582. January 1 of year 1 is day 1.
x.toordinal()
It is possible to calculate a date from a ordinal by using the class method "fromordinal":
date.fromordinal(727911)
If you want to know the weekday of a certain date, you can calculate it by using the method weekday:
x.weekday()
date.today()
We can access the day, month and year with attributes:
print(x.day)
print(x.month)
print(x.year)
from datetime import time
t = time(15, 6, 23)
print(t)
The possible times range between:
print(time.min)
print(time.max)
Accessing 'hour', 'minute' and 'second':
t.hour, t.minute, t.second
Each component of a time instance can be changed by using 'replace':
t = t.replace(hour=11, minute=59)
t
We can render a date as a C-style like string, corresponding to the C ctime function:
x.ctime()
The datetime Class
The datetime module provides us with functions and methods for manipulating dates and times. It supplies functionalities for date and time arithmetic, i.e. addition and subtraction. Another focus of the implementation is on attribute extraction for output manipulation and formatting.
There are two kinds of date and time objects:
- naive
- aware
If a time or date object is naive it doesn't contain information to compare or locate itself relative to other date or time objects. The semantics, if such a naive object belongs to a certain time zone, e.g. Coordinated Universal Time (UTC), local time, or some other timezone is contained in the logic of the program.
An aware object on the other hand possesses knowledge of the time zone it belongs to or the daylight saving time information. This way it can locate itself relative to other aware objects.
How can you tell if a datetime object t is aware?
t is aware if t.tzinfo is not None and t.tzinfo.utcoffset(t) is not None. Both conditions have to be fulfilled
On the other hand an object t is naive if t.tzinfo is None or t.tzinfo.utcoffset(t) is None
Let's create a datetime object:
from datetime import datetime
t = datetime(2017, 4, 19, 16, 31, 0)
t
t is naive, because the following is True:
t.tzinfo == None
We will create an aware datetime object from the current date. For this purpose we need the module pytz. pytz is a module, which brings the Olson tz database into Python. The Olson timezones are nearly completely supported by this module.
from datetime import datetime
import pytz
t = datetime.now(pytz.utc)
We can see that both t.tzinfo and t.tzinfo.utcoffset(t) are different from None, so t is an aware object:
t.tzinfo, t.tzinfo.utcoffset(t)
from datetime import datetime, timedelta as delta
ndays = 15
start = datetime(1991, 4, 30)
dates = [start - delta(days=x) for x in range(0, ndays)]
dates
from datetime import datetime
delta = datetime(1993, 12, 14) - datetime(1991, 4, 30)
delta, type(delta)
The result of the subtraction of the two datetime objects is a timedelta object, as we can see from the example above.
We can get information about the number of days elapsed by using the attribute 'days':
delta.days
t1 = datetime(2017, 1, 31, 14, 17)
t2 = datetime(2015, 12, 15, 16, 59)
delta = t1 - t2
delta.days, delta.seconds
It is possible to add or subtract a timedelta to a datetime object to calculate a new datetime object by adding or subtracting the delta in days:
from datetime import datetime, timedelta
d1 = datetime(1991, 4, 30)
d2 = d1 + timedelta(10)
print(d2)
print(d2 - d1)
d3 = d1 - timedelta(100)
print(d3)
d4 = d1 - 2 * timedelta(50)
print(d4)
It is also possible to add days and minutes to t datetime object:
from datetime import datetime, timedelta
d1 = datetime(1991, 4, 30)
d2 = d1 + timedelta(10,100)
print(d2)
print(d2 - d1)
s = str(d1)
s
Conversion with strftime
The method call datetime.strftime(format) return a string representing the date and time, controlled by an explicit format string. A complete list of formatting directives can be found at strftime:
print(d1.strftime('%Y-%m-%d'))
print("weekday: " + d1.strftime('%a'))
print("weekday as a full name: " + d1.strftime('%A'))
# Weekday as a decimal number, where 0 is Sunday
# and 6 is Saturday
print("weekday as a decimal number: " + d1.strftime('%w'))
Formatting months:
# Day of the month as a zero-padded decimal number.
# 01, 02, ..., 31
print(d1.strftime('%d'))
# Month as locale’s abbreviated name.
# Jan, Feb, ..., Dec (en_US);
# Jan, Feb, ..., Dez (de_DE)
print(d1.strftime('%b'))
# Month as locale’s full name.
# January, February, ..., December (en_US);
# Januar, Februar, ..., Dezember (de_DE)
print(d1.strftime('%B'))
# Month as a zero-padded decimal number.
# 01, 02, ..., 12
print(d1.strftime('%m'))
from datetime import datetime
t = datetime.strptime("30 Nov 00", "%d %b %y")
print(t)
dt = "2007-03-04T21:08:12"
datetime.strptime( dt, "%Y-%m-%dT%H:%M:%S" )
dt = '12/24/1957 4:03:29 AM'
dt = datetime.strptime(dt, '%m/%d/%Y %I:%M:%S %p')
dt
We can create an English date string on a Linux machine with the Shell command
LC_ALL=en_EN.utf8 date
dt = 'Wed Apr 12 20:29:53 CEST 2017'
dt = datetime.strptime(dt, '%a %b %d %H:%M:%S %Z %Y')
print(dt)
Though datetime.strptime is an easy way to parse a date with a known format, it can be quote complicated and cumbersome to write every time a new specification string for new date formats.
Using the parse method from dateutil.parser:
from dateutil.parser import parse
parse('2011-01-03')
parse('Wed Apr 12 20:29:53 CEST 2017')
Next Chapter: Python, Pandas and Timeseries