2. Parsing and Formatting

2.1. Date formats

2.1.1. Date format in USA

Listing 165. Formal date format in USA [Wik19d]
4/12/61
April 12, 1961

2.1.2. Date format in Japan

Listing 166. Formal date format in Japan [Wik19c]
20/12/31

2.1.3. Date format in Germany

Listing 167. Formal date format in Germany
12.04.1961

2.1.4. Date format 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. Time formats

2.2.1. 24 and 12 hour clock

  • What AM stands for?

  • What PM stands for?

17:00
5:00 PM

2.2.2. Noon and Midnight

  • Which time is a midnight?

  • Which time is a noon?

  • Confusion at noon and midnight

  • 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.3. Times after 24:00

23:59:59
23:59:60
24:00
24:01
25:00
27:45
14:00-30:00

2.2.4. Military time

1200J
1200Z

2.3. ISO 8601 Standard

2.3.1. Dates

1961-04-12

2.3.2. Date and time

  • "Z" (Zulu) means UTC

  • "T" separates date and time

Listing 168. Date and time with second precision
1961-04-12T06:07:00Z
Listing 169. Date and time with with millisecond precision
1961-04-12T06:07:00.123Z
Listing 170. Date and time with microsecond precision
1961-04-12T06:07:00.123456Z

2.3.3. 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.3.4. Weeks

Listing 171. 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.3.5. Timezone

  • "Z" (Zulu) means UTC

Listing 172. Time zone notation
<time>Z
<time>±hh:mm
<time>±hhmm
<time>±hh

2.3.6. Duration

  • Format: P[n]Y[n]M[n]DT[n]H[n]M[n]S

Table 34. Duration format

Format

Designator

Description

P

duration (period)

placed at the start of the duration representation

Y

year

number of years

M

month

number of months

W

week

number of weeks

D

day

number of days

T

time

precedes the time components of the representation

H

hour

number of hours

M

minute

number of minutes

S

second

number of seconds

Listing 173. Example
P8Y3M8DT20H49M15S

# Period of:
#   8 years
#   3 months
#   8 days
#   20 hours
#   49 minutes
#   15 seconds

2.4. Date and time parsing and formatting parameters

Note

Almost any programming language has very similar date formatting parameters. There are only some minor differences like in JavaScript minutes are i, not M.

Table 35. Date and time parsing and formatting parameters

Directive

Example

Meaning

%a

Sun, Mon, …, Sat

Weekday as locale's abbreviated name

%A

Sunday, Monday, …, Saturday (en_US)

Weekday as locale's full name

%w

0, 1, …, 6

Weekday as a decimal number, where 0 is Sunday and 6 is Saturday

%d

01, 02, …, 31

Day of the month as a zero-padded decimal number

%b

Jan, Feb, …, Dec (en_US)

Month as locale's abbreviated name

%B

January, February, …, December (en_US)

Month as locale’s full name

%m

01, 02, …, 12

Month as a zero-padded decimal number

%y

00, 01, …, 99

Year without century as a zero-padded decimal number

%Y

0001, 0002, …, 2013, 2014, …, 9998, 9999

Year with century as a decimal number

%H

00, 01, …, 23

Hour (24-hour clock) as a zero-padded decimal number

%I

01, 02, …, 12

Hour (12-hour clock) as a zero-padded decimal number

%p

AM, PM (en_US)

Locale’s equivalent of either AM or PM

%M

00, 01, …, 59

Minute as a zero-padded decimal number

%S

00, 01, …, 59

Second as a zero-padded decimal number

%f

000000, 000001, …, 999999

Microsecond as a decimal number, zero-padded on the left

%z

(empty), +0000, -0400, +1030

UTC offset in the form +HHMM or -HHMM (empty string if the object is naive)

%Z

(empty), UTC, EST, CST

Time zone name (empty string if the object is naive)

%j

001, 002, …, 366

Day of the year as a zero-padded decimal number

%U

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

%W

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

%c

Tue Aug 16 21:30:00 1988 (en_US)

Locale’s appropriate date and time representation

%x

08/16/1988 (en_US); 16.08.1988 (de_DE)

Locale’s appropriate date representation

%X

21:30:00

Locale’s appropriate time representation

%%

%

A literal % character

%G

0001, 0002, …, 2013, 2014, …, 9998, 9999

ISO 8601 year with century representing the year that contains the greater part of the ISO week (%V)

%u

1, 2, …, 7

ISO 8601 weekday as a decimal number where 1 is Monday

%V

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.5. Date formatting

2.5.1. ISO Format

Listing 174. Datetime formatting to ISO format
from datetime import datetime

dt = datetime(1969, 7, 21, 2, 56, 15)

dt.isoformat()
# 1969-07-21T02:56:15
Listing 175. Date formatting to ISO format
from datetime import date

d = date(1969, 7, 21)

d.isoformat()
# 1969-07-21

2.5.2. f-string formatting

Listing 176. 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
Listing 177. 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
Listing 178. 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.5.3. Format to string

Listing 179. 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.6. Parsing dates

  • Parsing - analyze (a sentence) into its parts and describe their syntactic roles.

Listing 180. Datetime parsing from string
from datetime import datetime

sputnik = '4 October 1957, 19:28:34 [UTC]'

output = datetime.strptime(sputnik, '%d %B %Y, %H:%M:%S [%Z]')
# datetime.datetime(1957, 10, 4, 19, 28, 34)

print(output)
# 1957-10-04 19:28:34

2.7. Example

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.8. Assignments

2.8.1. From ISO date format

English
  1. The date and time is given in ISO format:

  2. Convert it to datetime object

Polish
  1. Dana jest data w formacie ISO

  2. Przedstaw datę jako obiekt datetime

Input
1969-07-21T02:56:15.123Z

2.8.2. To ISO date format

Enlish
  1. Create datetime object by parsing the given date

  2. Using formatting parameters print the date and time in ISO format

Polish
  1. Podaną datę przekonwertuj do obiektu datetime

  2. Używając parametrów formatujących wyświetl datę i czas w formacie ISO

Input
gagarin = 'April 12, 1961 6:07 local time'
Output
1969-04-12T06:07:00.000Z

2.8.3. US date and time format

English
  1. Using given date and time from below (copy with quotes inside)

  2. Create datetime object by parsing the date

  3. Using formatting parameters print american short date format

  4. Make sure, that hour is without leading zero

Polish
  1. Używając podaną poniżej datę i czas (skopiuj z cudzysłowami)

  2. Parsując stwórz obiekt datetime

  3. Używając parametrów formatowania wyświetl datę w formacie amerykańskim krótkim

  4. Upewnij się, że godzina jest bez wiodącego zera

Input
armstrong = '"July 21st, 1969 2:56:15 AM UTC"'
Output
7/21/69 2:56 AM
Hint
  • Add quote sign " like normal text to fmt parameter of .strptime()

  • Use %-I or %_I on *nix systems (macOS, BSD, Linux) to remove leading zero

  • Use %#I on Windows to remove leading zero

2.8.4. Log parsing

  • Complexity level: medium

  • Lines of code to write: 25 lines

  • Estimated time of completion: 20 min

  • Filename: solution/datetime_logs.py

English
  1. Save input data to file apollo11-timeline.log

  2. Extract datetime object, level name and message from each line

  3. Collect data to OUTPUT: List[dict] (see below)

  4. Print OUTPUT

Polish
  1. Zapisz dane wejściowe do pliku apollo11-timeline.log

  2. Wyciągnij obiekt datetime, poziom logowania oraz wiadomość z każdej linii

  3. Zbierz dane do OUTPUT: List[dict] (patrz poniżej)

  4. Wyświetl OUTPUT

Input
1969-07-14T21:00:00 [INFO] Terminal countdown started
1969-07-16T13:31:53 [WARNING] S-IC engine ignition (#5)
1969-07-16T13:33:23 [DEBUG] Maximum dynamic pressure (735.17 lb/ft^2)
1969-07-16T13:34:44 [WARNING] S-II ignition
1969-07-16T13:35:17 [DEBUG] Launch escape tower jettisoned
1969-07-16T13:39:40 [DEBUG] S-II center engine cutoff
1969-07-16T16:22:13 [INFO] Translunar injection
1969-07-16T16:56:03 [INFO] CSM docked with LM/S-IVB
1969-07-16T17:21:50 [INFO] Lunar orbit insertion ignition
1969-07-16T21:43:36 [INFO] Lunar orbit circularization ignition
1969-07-20T17:44:00 [INFO] CSM/LM undocked
1969-07-20T20:05:05 [WARNING] LM powered descent engine ignition
1969-07-20T20:10:22 [ERROR] LM 1202 alarm
1969-07-20T20:14:18 [ERROR] LM 1201 alarm
1969-07-20T20:17:39 [WARNING] LM lunar landing
1969-07-21T02:39:33 [DEBUG] EVA started (hatch open)
1969-07-21T02:56:15 [WARNING] 1st step taken lunar surface (CDR) "That's one small step for [a] man... one giant leap for mankind"
1969-07-21T03:05:58 [DEBUG] Contingency sample collection started (CDR)
1969-07-21T03:15:16 [INFO] LMP on lunar surface
1969-07-21T05:11:13 [DEBUG] EVA ended (hatch closed)
1969-07-21T17:54:00 [WARNING] LM lunar liftoff ignition (LM APS)
1969-07-21T21:35:00 [INFO] CSM/LM docked
1969-07-22T04:55:42 [WARNING] Transearth injection ignition (SPS)
1969-07-24T16:21:12 [INFO] CM/SM separation
1969-07-24T16:35:05 [WARNING] Entry
1969-07-24T16:50:35 [WARNING] Splashdown (went to apex-down)
1969-07-24T17:29 [INFO] Crew egress
Output
OUTPUT: List[dict] = [

    {'date': datetime.datetime(1969, 7, 14, 21, 0, tzinfo=datetime.timezone.utc),
     'level': 'INFO',
     'message': 'Terminal countdown started'},

    {'date': datetime.datetime(1969, 7, 16, 13, 31, 53, tzinfo=datetime.timezone.utc),
     'level': 'WARNING',
     'message': 'S-IC engine ignition (#5)'},

...]