Python, Datum und Zeit

Einführung

Python, Date and Time

Python bietet reichlich Funktionalität um mit Datums und Zeit-Daten umzugehen. Die Standard-Bibliotheken enthalten folgende Module:

Diese Module bieten Klassen zur Manipulation von simplen und komplexen Datums- und Zeit-Daten.

Speziell die datetime-Klasse ist sehr wichtig für die Timeseries in Pandas.

Python Standard Module für Zeit-Daten

Die wichtigesten Module in Python um mit Zeiten zu arbeiten sind time, calendar und datetime.

Das datetime-Modul bietet diverse Klassen, Methoden und Funktionen für die Arbeit mit Datums, Zeiten und Zeit-Intervallen. Dafür stehen folgende Klassen zur Verfügung:

Wir starten mit dem date-Objekt.

Die Date Klasse

from datetime import date
x = date(1993, 12, 14)
print(x)
1993-12-14

Wir können Datums-Objekte instanziieren zwischen dem 01. Januar 0001 und 31. Dezember 9999. Über die Attribute min und max kann dies ermittelt werden:

from datetime import date
print(date.min)
print(date.max)
0001-01-01
9999-12-31

Wir können auf diverse Methoden auf das Date-Objekt von oeben anwenden. Die Methode toordinal() liefert das proleptische Gregorianische Ordinal. Der proleptische Gregorianische Kalender ...

Hier nochmal Übersetzen!!!

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()
Der obige Python-Code liefert Folgendes:
727911

Aus dem Ordinal kann das Datum wieder herausgerechnet werden mit der Klassen-Methode fromordinal():

date.fromordinal(727911)
Der obige Python-Code liefert Folgendes:
datetime.date(1993, 12, 14)

Wenn Sie den Wochentag eines bestimmten Tages wissen möchten, kann dies berechnet werden mit der Methode weekday():

x.weekday()
Der obige Python-Code führt zu folgender Ausgabe:
1
date.today()
Der obige Code liefert folgendes Ergebnis:
datetime.date(2018, 7, 24)

Über die Attribute können wir auf den Tag, den Monat und das Jahr eines Date-Objektes zugreifen:

print(x.day)
print(x.month)
print(x.year)
14
12
1993

Die time-Klasse

Die time-Klasse ist gleich organisiert wie die date-Klasse.

from datetime import time
t = time(15, 6, 23)
print(t)
15:06:23

Die möglichen Zeiten liegen zwischen:

print(time.min)
print(time.max)
00:00:00
23:59:59.999999

Der Zugriff auf Stunde, Minute und Sekunde:

t.hour, t.minute, t.second
Führt man obigen Code aus, erhält man folgende Ausgabe:
(15, 6, 23)

Jede Komponente eines Zeit-Objektes can durch replace() geändert werden:

t = t.replace(hour=11, minute=59)
t
Der obige Code liefert folgendes Ergebnis:
datetime.time(11, 59, 23)

Wir können ein Datum-String in C-Style generieren, entsprechend der ctime-Funktion in C:

x.ctime()
Wir können die folgenden Ergebnisse erwarten, wenn wir den obigen Python-Code ausführen:
'Tue Dec 14 00:00:00 1993'

Die datetime-Klasse

Das datetime-Modul bietet uns Funktionen und Methoden zur Manipulation von Datums- und Zeit-Objekten. Weiterhin stellt es Funktionalitäten zur Verfügung für arithmetische Operationen für Datums- und Zeit-Objekte, z.B. Addition und Subtraktion. Ein weiterer Fokus der Implementierung liegt auf der Extrahierung von Attributen.

Es gibt zwei Arten von Datums- und Zeit-Objekten:

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
Der obige Python-Code liefert Folgendes:
datetime.datetime(2017, 4, 19, 16, 31)

t is naive, because the following is True:

t.tzinfo == None
Der obige Python-Code führt zu folgender Ausgabe:
True

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)
Wir erhalten die folgende Ergebnisse:
(<UTC>, datetime.timedelta(0))
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
Der obige Code führt zu folgendem Ergebnis:
[datetime.datetime(1991, 4, 30, 0, 0),
 datetime.datetime(1991, 4, 29, 0, 0),
 datetime.datetime(1991, 4, 28, 0, 0),
 datetime.datetime(1991, 4, 27, 0, 0),
 datetime.datetime(1991, 4, 26, 0, 0),
 datetime.datetime(1991, 4, 25, 0, 0),
 datetime.datetime(1991, 4, 24, 0, 0),
 datetime.datetime(1991, 4, 23, 0, 0),
 datetime.datetime(1991, 4, 22, 0, 0),
 datetime.datetime(1991, 4, 21, 0, 0),
 datetime.datetime(1991, 4, 20, 0, 0),
 datetime.datetime(1991, 4, 19, 0, 0),
 datetime.datetime(1991, 4, 18, 0, 0),
 datetime.datetime(1991, 4, 17, 0, 0),
 datetime.datetime(1991, 4, 16, 0, 0)]

Differences between Times

Let's see what happens, if we subtract to datetime objects:

from datetime import datetime
delta = datetime(1993, 12, 14) - datetime(1991, 4, 30)
delta, type(delta)
Führt man obigen Code aus, erhält man folgendes Ergebnis:
(datetime.timedelta(959), datetime.timedelta)

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
Der obige Code liefert folgendes Ergebnis:
959
t1 = datetime(2017, 1, 31, 14, 17)
t2 = datetime(2015, 12, 15, 16, 59)
delta = t1 - t2
delta.days, delta.seconds
Der obige Python-Code liefert folgendes Ergebnis:
(412, 76680)

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)
1991-05-10 00:00:00
10 days, 0:00:00
1991-01-20 00:00:00
1991-01-20 00:00:00

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)
1991-05-10 00:01:40
10 days, 0:01:40

Convert datetime Objects to Strings

The easiest way to convert a datetime object into a string consists in using str.

s = str(d1)
s
Der obige Code liefert folgendes Ergebnis:
'1991-04-30 00:00:00'

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'))
1991-04-30
weekday: Tue
weekday as a full name: Tuesday
weekday as a decimal number: 2

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'))
30
Apr
April
04

Creating datetime Objects from Strings

We can use strptime to create new datetime object by parsing a string containing a data and time. The arguments of strptime are the string to be parsed and a format specification.

from datetime import datetime
t = datetime.strptime("30 Nov 00", "%d %b %y")
print(t)
2000-11-30 00:00:00
dt = "2007-03-04T21:08:12"
datetime.strptime( dt, "%Y-%m-%dT%H:%M:%S" )
Wir können die folgenden Ergebnisse erwarten, wenn wir den obigen Python-Code ausführen:
datetime.datetime(2007, 3, 4, 21, 8, 12)
dt = '12/24/1957 4:03:29 AM'
dt = datetime.strptime(dt, '%m/%d/%Y %I:%M:%S %p')
dt
Der obige Python-Code führt zu folgender Ausgabe:
datetime.datetime(1957, 12, 24, 4, 3, 29)

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)
2017-04-12 20:29:53

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')
Der obige Code liefert folgendes Ergebnis:
datetime.datetime(2011, 1, 3, 0, 0)
parse('Wed Apr 12 20:29:53 CEST 2017')
Der obige Python-Code liefert folgendes Ergebnis:
datetime.datetime(2017, 4, 12, 20, 29, 53, tzinfo=tzlocal())