loading...
Cover image for Python: Formatting dates and times

Python: Formatting dates and times

adamlombard profile image Adam Lombard ・5 min read

Formatting dates and times into human-readable strings is a common programming task, and Python has a comprehensive method for doing so.

Let's begin by importing the datetime and tz (timezone) libraries:

>>> import datetime
>>> from dateutil import tz

The datetime library has many useful (and advanced) classes and methods, but exploring them is beyond the scope of this article. To explore formatting dates and times in Python, we will begin by generating a specific datetime, far out in the future. This will provide us with uniquely recognizable string components in our examples below.

Python datetime objects contain the following information, in order: Year, Month, Day, Hour, Minute, Second, Millisecond, and Timezone. Let's generate the datetime for May 4, 9876, at exactly 1.001 seconds after 3:02AM, in Los Angeles. :

>>> location = tz.gettz('America/Los_Angeles')
>>> dt = datetime.datetime(9876, 5, 4, 3, 2, 1, 1, tzinfo=location)

To format our datetime, we use its strftime() method. Let's try a few examples.

Dates

Let's format our date per the ISO 8601 standard, which is my personal favorite and takes the form "YYYY-MM-DD":

>>> dt.strftime("%Y-%m-%d")
'9876-05-04'

You may notice that the formatting is controlled by characters preceded with a %. These are called "directives", and allow us to declare formatting for specific parts of the date and time, while mixing in other plaintext characters, like -. There is a reference chart of most strftime() directives at the end of this article.

Let's try another. In many parts of the world, it's common to format dates as "DD.MM.YY":

>>> dt.strftime("%d.%m.%y")
'04.05.76'

(You may notice that the lowercase y directive yields a two-character year, instead of the four-character year yielded by the uppercase Y directive.)

Finally, let's try a format like "Weekday Name, Month Name (Abbreviated) Date, Year":

>>> dt.strftime("%A, %b %d, %Y")
'Thursday, May 04, 9876'

Times

Now we'll format the time.

First, let's try 24-hour time, like "HH:MM:SS":

>>> dt.strftime("%H:%M:%S")
'03:02:01'

And let's also do 12-hour time, without seconds, showing whether it's AM or PM:

>>> dt.strftime("%-I:%M%p")
'3:02AM'

Directives

By mixing and matching the directives below, we can now freely format dates and times in Python:

(NOTE: Python implements strftime() by calling strftime() in the platform's C library. Not all directives are available on all platforms, and some platforms may have directives not shown here. These directives were tested in Python 3.8 on macOS 10.15.4.)

Dates

Directive Meaning Example
%C Century as a 2-digit decimal number (00-99). 98
%Y Year (with century) as a decimal number (0001-9999). 9876
%G ISO 8601 week-based year (with century) as a decimal number (0001-9999). Represents the year that contains the greater part of the ISO week. See %V. 9876
%y Year (without century) as a zero-padded decimal number (00-99). 76
%g ISO 8601 week-based year (without century) as a decimal number (00-99). 76
%m Month as a zero-padded decimal number (01-12). 05
%-m Month as a decimal number (1-12). 5
%B Locale's full month name. May
%b Locale's abbreviated month name. May
%h Equivalent to %b. May
%d Day of the month as a zero-padded decimal number (01-31). 04
%e Day of the month as a space-padded decimal number ( 1-31). ' 4'
%-d Day of the month as a decimal number (1-31). 4
%j Day of the year as a zero-padded decimal number (001-366). 125
%-j Day of the year as a decimal number (1-366). 125
%w Weekday as a decimal number, where Sunday is 0 and the first day of the week (0-6). 4
%u Weekday as a decimal number, where Monday is 1 and the first day of the week (1-7). 4
%A Locale's full weekday name. Thursday
%a Locale's abbreviated weekday name. Thu
%U Week of the year as a zero-padded decimal number. Treats Sunday as the first day of the week. All days in a new year preceding the first Sunday are considered to be in week 0. (00-53) 18
%W Week of the year as a zero-padded decimal number. Treats Monday as the first day of the week. All days in a new year preceding the first Monday are considered to be in week 0. (00-53) 18
%V ISO 8601 week of the year as a zero-padded decimal number. Treats Monday as the first day of the week. Week 01 is the week containing Jan 4. (01-53) 18

Times

Directive Meaning Example
%H Hour (24-hour clock) as a zero-padded decimal number (00-23). 03
%k Hour (24-hour clock) as a space-padded decimal number ( 0-23). ' 3'
%-H Hour (24-hour clock) as a decimal number (0-23). 3
%I Hour (12-hour clock) as a zero-padded decimal number (01-12). 03
%l Hour (12-hour clock) as a space-padded decimal number ( 1-12). ' 3'
%-I Hour (12-hour clock) as a decimal number (1-12). 3
%M Minute as a zero-padded decimal number (00-59). 02
%-M Minute as a decimal number (0-59). 2
%S Second as a zero-padded decimal number (00-59). 01
%-S Second as a decimal number (0-59). 1
%f Millisecond as a six-digit, zero-padded decimal number (000000-999999). 000001
%p Locale's equivalent of either AM or PM. AM
%z Locale's UTC offset in the form ±HHMM[SS[.ffffff]]. Empty string if the object is naive. -0800
%Z Locale's time zone name. PST

Short Codes

Directive Meaning Example
%c Locale's preferred date and time representation. Thu May 4 03:02:01 9876
%D Equivalent to %m/%d/%y. 5/04/76
%F Equivalent to %Y-%m-%d (the ISO 8601 format). 9876-05-04
%r Time in locale's preferred AM or PM notation. 03:02:01 AM
%R Time in 24-hour notation (without seconds). Equivalent to %H:%M. 03:02
%T Time in 24-hour notation (with seconds). Equivalent to %H:%M:%S. 03:02:01
%x Locale's preferred date representation (without time). 05/04/76
%X Locale's preferred time representation (without date). 03:02:01

Misc

Directive Meaning Example
%% A literal % character. %
%n A newline character.
%t A tab character.
%s The number of seconds since the Unix Epoch: 1970-01-01 00:00:00 +0000 (UTC) 249499998121

Documentation for strftime().

Posted on by:

Discussion

markdown guide