2.2. Datetime Parsing and Formatting¶
2.2.1. Date formats¶
2.2.5. Date format in Poland¶
Which format is a formal standard in Poland?
12.4.1961
12.04.1961
12 IV 1961
12.IV.1961
12/4/1961
12/04/1961
12 kwietnia 1961
12 kwiecień 1961
2.2.6. Time formats¶
2.2.8. Noon and Midnight¶
Which time is a midnight?
Which time is a noon?
Is 12:00 a noon (in 24h format), or someone just simply forgot to put AM/PM?
12:00 am
12:00 pm
12:00
24:00
00:00
0:00
2.2.11. ISO 8601 Standard¶
2.2.12. Dates¶
1961-04-12
2.2.13. Date and time¶
"Z" (Zulu) means UTC
"T" separates date and time
Date and time:
1961-04-12T06:07:00Z
1961-04-12T06:07:00.123Z
1961-04-12T06:07:00.123456Z
2.2.14. Noon and Midnight¶
"00:00" - midnight, at the beginning of a day
"24:00" - midnight, at the end of a day (not recommended)
"2007-04-05T24:00" is equal to "2007-04-06T00:00"
2.2.15. Weeks¶
Note year/month changes during the week:
2009-W01 # First week of 2009
2009-W01-1 # Monday 29 December 2008
2009-W53-7 # Sunday 3 January 2010
2.2.16. Timezone¶
"Z" (Zulu) means UTC
Time zone notation:
<time>UTC
<time>Z
<time>±hh:mm
<time>±hhmm
<time>±hh
2.2.17. Duration¶
Format:
P[n]Y[n]M[n]DT[n]H[n]M[n]S
Format |
Designator |
Description |
---|---|---|
|
duration (period) |
placed at the start of the duration representation |
|
year |
number of years |
|
month |
number of months |
|
week |
number of weeks |
|
day |
number of days |
|
time |
precedes the time components of the representation |
|
hour |
number of hours |
|
minute |
number of minutes |
|
second |
number of seconds |
Example:
P8Y3M8DT20H49M15S
Period of:
8 years
3 months
8 days
20 hours
49 minutes
15 seconds
2.2.18. Date and time parsing and formatting parameters¶
https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
%-I
or%_I
on *nix systems (macOS, BSD, Linux) to remove leading zero%#I
on Windows to remove leading zero*nix:
%-d
,%-H
,%-I
,%-j
,%-m
,%-M
,%-S
,%-U
,%-w
,%-W
,%-y
,%-Y
Windows:
%#d
,%#H
,%#I
,%#j
,%#m
,%#M
,%#S
,%#U
,%#w
,%#W
,%#y
,%#Y
Almost any programming language has very similar date formatting parameters. There are only some minor differences like in JavaScript minutes are i
, not M
.
Directive |
Example |
Meaning |
---|---|---|
|
Sun, Mon, …, Sat |
Weekday as locale's abbreviated name |
|
Sunday, Monday, …, Saturday (en_US) |
Weekday as locale's full name |
|
0, 1, …, 6 |
Weekday as a decimal number, where 0 is Sunday and 6 is Saturday |
|
01, 02, …, 31 |
Day of the month as a zero-padded decimal number |
|
Jan, Feb, …, Dec (en_US) |
Month as locale's abbreviated name |
|
January, February, …, December (en_US) |
Month as locale’s full name |
|
01, 02, …, 12 |
Month as a zero-padded decimal number |
|
00, 01, …, 99 |
Year without century as a zero-padded decimal number |
|
0001, 0002, …, 2013, 2014, …, 9998, 9999 |
Year with century as a decimal number |
|
00, 01, …, 23 |
Hour (24-hour clock) as a zero-padded decimal number |
|
01, 02, …, 12 |
Hour (12-hour clock) as a zero-padded decimal number |
|
AM, PM (en_US) |
Locale’s equivalent of either AM or PM |
|
00, 01, …, 59 |
Minute as a zero-padded decimal number |
|
00, 01, …, 59 |
Second as a zero-padded decimal number |
|
000000, 000001, …, 999999 |
Microsecond as a decimal number, zero-padded on the left |
|
(empty), +0000, -0400, +1030 |
UTC offset in the form +HHMM or -HHMM (empty string if the object is naive) |
|
(empty), UTC, EST, CST |
Time zone name (empty string if the object is naive) |
|
001, 002, …, 366 |
Day of the year as a zero-padded decimal number |
|
00, 01, …, 53 |
Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0 |
|
00, 01, …, 53 |
Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0 |
|
Tue Aug 16 21:30:00 1988 (en_US) |
Locale’s appropriate date and time representation |
|
08/16/1988 (en_US); 16.08.1988 (de_DE) |
Locale’s appropriate date representation |
|
21:30:00 |
Locale’s appropriate time representation |
|
% |
A literal |
|
0001, 0002, …, 2013, 2014, …, 9998, 9999 |
ISO 8601 year with century representing the year that contains the greater part of the ISO week ( |
|
1, 2, …, 7 |
ISO 8601 weekday as a decimal number where 1 is Monday |
|
01, 02, …, 53 |
ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4 |
2.2.19. Date formatting¶
2.2.20. ISO Format¶
Datetime formatting to ISO format:
from datetime import datetime
dt = datetime(1969, 7, 21, 2, 56, 15)
dt.isoformat()
# 1969-07-21T02:56:15
Date formatting to ISO format:
from datetime import date
d = date(1969, 7, 21)
d.isoformat()
# 1969-07-21
2.2.21. f-string
formatting¶
Datetime formatting as string with f'...'
:
from datetime import datetime
gagarin = datetime(1961, 4, 12, 6, 7)
print(f'Gagarin launched on {gagarin:%Y-%m-%d}')
# Gagarin launched on 1961-04-12
Datetime formatting as string with f'...'
:
from datetime import datetime
gagarin = datetime(1961, 4, 12, 6, 7)
print(f'Gagarin launched on {gagarin:%Y-%m-%d %H:%M}')
# Gagarin launched on 1961-04-12 06:07
Datetime formatting as string with f'...'
:
from datetime import datetime
gagarin = datetime(1961, 4, 12, 6, 7)
format = '%Y-%m-%d %H:%M'
print(f'Gagarin launched on {gagarin:{format}}')
# Gagarin launched on 1961-04-12 06:07
2.2.22. Format to string¶
Datetime formatting as string with .strftime()
:
from datetime import datetime
gagarin = datetime(1961, 4, 12, 6, 7)
formatted = gagarin.strftime('%Y-%m-%d %H:%M')
print(f'Gagarin launched on {formatted}')
# Gagarin launched on 1961-04-12 06:07
2.2.23. Parsing dates¶
Parsing - analyze (a sentence) into its parts and describe their syntactic roles.
Datetime parsing from string:
from datetime import datetime
sputnik = '4 October 1957, 19:28:34 [UTC]'
result = datetime.strptime(sputnik, '%d %B %Y, %H:%M:%S [%Z]')
# datetime.datetime(1957, 10, 4, 19, 28, 34)
print(result)
# 1957-10-04 19:28:34
2.2.24. Examples¶
from datetime import datetime
log = '1969-07-21T02:56:15.123 [WARNING] First step on the Moon'
date, level, message = log.split(maxsplit=2)
format = '%Y-%m-%dT%H:%M:%S.%f'
date = datetime.strptime(date, format)
print(date)
# 1969-07-21 02:56:15.123000
print(level)
# [WARNING]
print(message)
# First step on the Moon
2.2.25. Assignments¶
"""
* Assignment: Datetime Parse ISO
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min
English:
1. Use data from "Given" section (see below)
2. The date and time is given in ISO format:
3. Convert it to `datetime` object
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Dana jest data w formacie ISO
3. Przedstaw datę jako obiekt `datetime`
Tests:
>>> type(result)
<class 'datetime.datetime'>
>>> result
datetime.datetime(1969, 7, 21, 2, 56, 15, 123000)
"""
# Given
from datetime import datetime
DATA = '1969-07-21T02:56:15.123Z'
"""
* Assignment: Datetime Parse Local
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min
English:
1. Use data from "Given" section (see below)
2. Create `datetime` object by parsing the given date
3. Using formatting parameters print the date and time in ISO format
4. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Podaną datę przekonwertuj do obiektu `datetime`
3. Używając parametrów formatujących wyświetl datę i czas w formacie ISO
4. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Hints:
* Add string `local time` to format statement
Tests:
>>> type(result)
<class 'str'>
>>> result
'1961-04-12T06:07:00.000000Z'
"""
# Given
from datetime import datetime
DATA = 'April 12, 1961 6:07 local time'
"""
* Assignment: Datetime Parse US
* Complexity: easy
* Lines of code: 5 lines
* Time: 3 min
English:
1. Use data from "Given" section (see below)
3. Create `datetime` object by parsing `DATA`
4. Using date formatting converts `DATA` to string and assign to `result`
in american short date format (np. '07/21/69 2:56 AM')
5. Make sure, that hour is without leading zero
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
3. Stwórz obiekt `datetime` parsując `DATA`
4. Używając parametrów formatowania daty przekonwertuj `DATA` do stringa
i zapisz do `result` w formacie amerykańskim krótkim (np. '07/21/69 2:56 AM')
5. Upewnij się, że godzina jest bez wiodącego zera
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Hints:
* Add quote sign `"` like normal text to `fmt` parameter of `.strptime()`
* `%dst`
* Use `%-I` or `%_I` on \*nix systems (macOS, BSD, Linux) to remove leading zero
* Use `%#I` on Windows to remove leading zero
Tests:
>>> type(result)
<class 'str'>
>>> result
'07/21/69 2:56 AM'
"""
# Given
from datetime import datetime
DATA = '"July 21st, 1969 2:56:15 AM UTC"'
result = ''
"""
* Assignment: Datetime Parse Logs
* Complexity: medium
* Lines of code: 15 lines
* Time: 13 min
English:
1. Use data from "Given" section (see below)
2. Save input data to file `apollo11-timeline.log`
3. Extract `datetime` object, level name and message from each line
4. Collect data to `result: list[dict]`
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Zapisz dane wejściowe do pliku `apollo11-timeline.log`
3. Wyciągnij obiekt `datetime`, poziom logowania oraz wiadomość z każdej linii
4. Zbierz dane do `result: list[dict]`
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
References:
* Apollo 11 timeline https://history.nasa.gov/SP-4029/Apollo_11i_Timeline.htm
Hints:
* `str.splitlines()`
* `str.split(maxsplit)`
* ` try ... except ValueError: ...`
Tests:
>>> result # doctest: +NORMALIZE_WHITESPACE
[{'date': datetime.datetime(1969, 7, 14, 21, 0), 'level': 'INFO', 'message': 'Terminal countdown started'},
{'date': datetime.datetime(1969, 7, 16, 13, 31, 53), 'level': 'WARNING', 'message': 'S-IC engine ignition (#5)'},
{'date': datetime.datetime(1969, 7, 16, 13, 33, 23), 'level': 'DEBUG', 'message': 'Maximum dynamic pressure (735.17 lb/ft^2)'},
{'date': datetime.datetime(1969, 7, 16, 13, 34, 44), 'level': 'WARNING', 'message': 'S-II ignition'},
{'date': datetime.datetime(1969, 7, 16, 13, 35, 17), 'level': 'DEBUG', 'message': 'Launch escape tower jettisoned'},
{'date': datetime.datetime(1969, 7, 16, 13, 39, 40), 'level': 'DEBUG', 'message': 'S-II center engine cutoff'},
{'date': datetime.datetime(1969, 7, 16, 16, 22, 13), 'level': 'INFO', 'message': 'Translunar injection'},
{'date': datetime.datetime(1969, 7, 16, 16, 56, 3), 'level': 'INFO', 'message': 'CSM docked with LM/S-IVB'},
{'date': datetime.datetime(1969, 7, 16, 17, 21, 50), 'level': 'INFO', 'message': 'Lunar orbit insertion ignition'},
{'date': datetime.datetime(1969, 7, 16, 21, 43, 36), 'level': 'INFO', 'message': 'Lunar orbit circularization ignition'},
{'date': datetime.datetime(1969, 7, 20, 17, 44), 'level': 'INFO', 'message': 'CSM/LM undocked'},
{'date': datetime.datetime(1969, 7, 20, 20, 5, 5), 'level': 'WARNING', 'message': 'LM powered descent engine ignition'},
{'date': datetime.datetime(1969, 7, 20, 20, 10, 22), 'level': 'ERROR', 'message': 'LM 1202 alarm'},
{'date': datetime.datetime(1969, 7, 20, 20, 14, 18), 'level': 'ERROR', 'message': 'LM 1201 alarm'},
{'date': datetime.datetime(1969, 7, 20, 20, 17, 39), 'level': 'WARNING', 'message': 'LM lunar landing'},
{'date': datetime.datetime(1969, 7, 21, 2, 39, 33), 'level': 'DEBUG', 'message': 'EVA started (hatch open)'},
{'date': datetime.datetime(1969, 7, 21, 2, 56, 15), 'level': 'WARNING', 'message': '1st step taken lunar surface (CDR)'},
{'date': datetime.datetime(1969, 7, 21, 2, 56, 15), 'level': 'WARNING', 'message': "That's one small step for [a] man... one giant leap for mankind"},
{'date': datetime.datetime(1969, 7, 21, 3, 5, 58), 'level': 'DEBUG', 'message': 'Contingency sample collection started (CDR)'},
{'date': datetime.datetime(1969, 7, 21, 3, 15, 16), 'level': 'INFO', 'message': 'LMP on lunar surface'},
{'date': datetime.datetime(1969, 7, 21, 5, 11, 13), 'level': 'DEBUG', 'message': 'EVA ended (hatch closed)'},
{'date': datetime.datetime(1969, 7, 21, 17, 54), 'level': 'WARNING', 'message': 'LM lunar liftoff ignition (LM APS)'},
{'date': datetime.datetime(1969, 7, 21, 21, 35), 'level': 'INFO', 'message': 'CSM/LM docked'},
{'date': datetime.datetime(1969, 7, 22, 4, 55, 42), 'level': 'WARNING', 'message': 'Transearth injection ignition (SPS)'},
{'date': datetime.datetime(1969, 7, 24, 16, 21, 12), 'level': 'INFO', 'message': 'CM/SM separation'},
{'date': datetime.datetime(1969, 7, 24, 16, 35, 5), 'level': 'WARNING', 'message': 'Entry'},
{'date': datetime.datetime(1969, 7, 24, 16, 50, 35), 'level': 'WARNING', 'message': 'Splashdown (went to apex-down)'},
{'date': datetime.datetime(1969, 7, 24, 17, 29), 'level': 'INFO', 'message': 'Crew egress'}]
"""
# Given
from datetime import datetime
DATA = """1969-07-14, 21:00:00, INFO, Terminal countdown started
1969-07-16, 13:31:53, WARNING, S-IC engine ignition (#5)
1969-07-16, 13:33:23, DEBUG, Maximum dynamic pressure (735.17 lb/ft^2)
1969-07-16, 13:34:44, WARNING, S-II ignition
1969-07-16, 13:35:17, DEBUG, Launch escape tower jettisoned
1969-07-16, 13:39:40, DEBUG, S-II center engine cutoff
1969-07-16, 16:22:13, INFO, Translunar injection
1969-07-16, 16:56:03, INFO, CSM docked with LM/S-IVB
1969-07-16, 17:21:50, INFO, Lunar orbit insertion ignition
1969-07-16, 21:43:36, INFO, Lunar orbit circularization ignition
1969-07-20, 17:44:00, INFO, CSM/LM undocked
1969-07-20, 20:05:05, WARNING, LM powered descent engine ignition
1969-07-20, 20:10:22, ERROR, LM 1202 alarm
1969-07-20, 20:14:18, ERROR, LM 1201 alarm
1969-07-20, 20:17:39, WARNING, LM lunar landing
1969-07-21, 02:39:33, DEBUG, EVA started (hatch open)
1969-07-21, 02:56:15, WARNING, 1st step taken lunar surface (CDR)
1969-07-21, 02:56:15, WARNING, That's one small step for [a] man... one giant leap for mankind
1969-07-21, 03:05:58, DEBUG, Contingency sample collection started (CDR)
1969-07-21, 03:15:16, INFO, LMP on lunar surface
1969-07-21, 05:11:13, DEBUG, EVA ended (hatch closed)
1969-07-21, 17:54:00, WARNING, LM lunar liftoff ignition (LM APS)
1969-07-21, 21:35:00, INFO, CSM/LM docked
1969-07-22, 04:55:42, WARNING, Transearth injection ignition (SPS)
1969-07-24, 16:21:12, INFO, CM/SM separation
1969-07-24, 16:35:05, WARNING, Entry
1969-07-24, 16:50:35, WARNING, Splashdown (went to apex-down)
1969-07-24, 17:29, INFO, Crew egress"""
result = []