Python datetime Formatting with f-strings
last modified May 11, 2025
This tutorial explores formatting datetime objects using Python's f-strings, a concise and readable approach introduced in Python 3.6. F-strings simplify date and time formatting while offering advantages over legacy methods.
Effectively formatting date and time information is crucial in many applications,
from generating human-readable timestamps in logs and reports to preparing
date strings for APIs and databases. Python's built-in datetime
module provides a comprehensive set of tools for date and time manipulation,
including classes for representing dates, times, and time intervals.
While older methods like strftime()
have long been used for
datetime formatting, f-strings (formatted string literals) offer a more modern,
intuitive, and often more performant way to achieve the same results.
F-strings allow embedding expressions inside string literals by prefixing the
string with an 'f' and placing expressions in curly braces {}
.
When an expression is a datetime
object, you can include a format
specifier after a colon to control its string representation. This makes the
code cleaner and easier to understand at a glance.
Throughout this tutorial, we will delve into various aspects of datetime
formatting using f-strings. We will cover common formatting codes, how to
extract and display specific components of a datetime object (like year, month,
day, hour, minute), and how to handle more advanced scenarios such as
locale-specific formatting and timezone conversions. All examples leverage the
power and flexibility of the datetime
module combined with the
syntactic sugar of f-strings.
We'll cover essential datetime formatting techniques with f-strings, including
custom formats, localization, and timezone management. All examples utilize
Python's built-in datetime
module, which provides robust tools for
handling and manipulating date and time data.
Datetime Format Specifiers in Python
Python's strftime
and f-string formatting provide a flexible way to
represent date and time values. Format specifiers define how datetime objects
are displayed, making it easy to adjust output for different applications,
locales, and readability preferences.
The table below lists common format specifiers supported by Python's
datetime
module:
Specifier | Description | Example |
---|---|---|
%Y | Year with century (0000-9999) | 2025 |
%y | Year without century (zero-padded, 00-99) | 25 |
%m | Month as zero-padded decimal (01-12) | 02 |
%B | Full month name (locale-dependent) | February |
%b | Abbreviated month name (locale-dependent) | Feb |
%d | Day of the month (zero-padded, 01-31) | 09 |
%A | Full weekday name (locale-dependent) | Monday |
%a | Abbreviated weekday name (locale-dependent) | Mon |
%w | Weekday as decimal (0-6, Sunday=0) | 1 |
%u | ISO 8601 weekday (1-7, Monday=1) | 2 |
%H | Hour (24-hour format, zero-padded, 00-23) | 14 |
%I | Hour (12-hour format, zero-padded, 01-12) | 02 |
%p | AM/PM marker (locale-dependent) | PM |
%M | Minute (zero-padded, 00-59) | 05 |
%S | Second (zero-padded, 00-59) | 07 |
%f | Microsecond (zero-padded, 000000-999999) | 123456 |
%z | UTC offset in ±HHMM[SS[.ffffff]] format (empty if naive) | +0100 |
%Z | Time zone name (empty if naive) | CET |
%j | Day of the year (zero-padded, 001-366) | 040 |
%U | Week number (Sunday as start of week, 00-53) | 06 |
%W | Week number (Monday as start of week, 00-53) | 06 |
%V | ISO 8601 week number (01-53) | 07 |
%G | ISO 8601 week-based year (0000-9999) | 2025 |
%c | Locale's full date and time representation | Tue Feb 15 14:30:45 2025 |
%x | Locale's date format | 02/15/25 |
%X | Locale's time format | 14:30:45 |
%% | Literal % character | % |
Using these format specifiers, you can customize datetime output for various use cases, such as logging, reporting, and localization. Python's f-strings provide a convenient way to apply these specifiers dynamically within formatted strings.
Basic datetime formatting with f-strings
The simplest way to format a datetime object with f-strings is to use the default string representation. This shows the date and time in ISO format. The example below demonstrates basic formatting.
from datetime import datetime now = datetime.now() print(f"Current datetime: {now}") print(f"Date only: {now:%Y-%m-%d}") print(f"Time only: {now:%H:%M:%S}")
This code shows three different f-string formats. The first uses the default string representation. The second formats just the date portion. The third formats only the time portion. The format specifiers after the colon define the output format.
$ python main.py Current datetime: 2025-02-15 14:30:45.123456 Date only: 2025-02-15 Time only: 14:30:45
Custom date formats with f-strings
F-strings allow complete control over datetime formatting. You can combine any valid format codes to create custom date and time displays. The example shows several common formatting options.
from datetime import datetime now = datetime.now() print(f"Full month name: {now:%B %d, %Y}") print(f"Short month name: {now:%b %d, %Y}") print(f"Weekday name: {now:%A, %B %d}") print(f"12-hour clock: {now:%I:%M %p}")
This example demonstrates different date and time formatting options. %B shows the full month name, %b the abbreviated month name. %A displays the full weekday name. %I formats hours in 12-hour clock with %p for AM/PM.
$ python main.py Full month name: February 15, 2025 Short month name: Feb 15, 2025 Weekday name: Saturday, February 15 12-hour clock: 02:30 PM
Formatting datetime components individually
You can access individual components of a datetime object directly in f-strings. This provides flexibility when you need to combine date parts with other text. The example shows how to format components separately.
from datetime import datetime now = datetime.now() print(f"Today is {now.year}/{now.month:02d}/{now.day:02d}") print(f"The time is {now.hour:02d}:{now.minute:02d}:{now.second:02d}") print(f"Day of year: {now.timetuple().tm_yday}") print(f"Week number: {now.isocalendar().week}")
This code accesses year, month, and day attributes directly. The :02d format ensures two-digit formatting with leading zeros. We also show the day of year and week number using additional datetime methods.
$ python main.py Today is 2025/02/15 The time is 14:30:45 Day of year: 46 Week number: 7
Combining datetime with other variables
F-strings make it easy to combine datetime formatting with other variables. You can mix date formatting with string text and other variable values. This example shows several combinations.
from datetime import datetime now = datetime.now() user = "John" items = 3 total = 45.50 print(f"Receipt for {user} on {now:%Y-%m-%d %H:%M}") print(f"Order #{12345:06d} - {now:%A %B %d}") print(f"{items} items purchased for ${total:.2f} at {now:%I:%M %p}")
This example combines datetime formatting with string variables, integers, and floats. The f-string automatically converts all values to strings. Number formatting (:06d for zero-padded int, :.2f for currency) works alongside datetime formatting.
$ python main.py Receipt for John on 2025-02-15 14:30 Order #012345 - Saturday February 15 3 items purchased for $45.50 at 02:30 PM
Formatting timedelta objects
Timedelta objects represent durations and can also be formatted with f-strings. This is useful for displaying time differences or elapsed time. The example shows several formatting options.
from datetime import datetime, timedelta start = datetime(2025, 2, 15, 9, 0) end = datetime.now() duration = end - start print(f"Elapsed time: {duration}") print(f"Hours: {duration.total_seconds()/3600:.1f}") print(f"Working time: {duration.seconds//3600}h {(duration.seconds%3600)//60}m") print(f"Days: {duration.days}, Seconds: {duration.seconds}")
This code calculates the duration between two datetime objects. We show the raw timedelta, total hours, formatted hours and minutes, and access to individual components. Note the difference between total_seconds() and seconds attribute.
$ python main.py Elapsed time: 5:30:45.123456 Hours: 5.5 Working time: 5h 30m Days: 0, Seconds: 19845
Locale-aware datetime formatting
For international applications, you may need locale-specific formatting. While f-strings don't directly support locales, you can combine them with strftime. This example shows locale-aware formatting.
from datetime import datetime import locale now = datetime.now() # Set to German locale locale.setlocale(locale.LC_TIME, 'de_DE') print(f"German format: {now:%A, %d. %B %Y}") # Set to French locale locale.setlocale(locale.LC_TIME, 'fr_FR') print(f"French format: {now:%A %d %B %Y}") # Reset to default locale.setlocale(locale.LC_TIME, '') print(f"Local format: {now:%x %X}")
This example demonstrates locale-specific date formatting. The locale module changes how month and day names appear. %x and %X are locale- specific date and time formats. Note that locale availability depends on the system.
$ python main.py German format: Samstag, 15. Februar 2025 French format: samedi 15 février 2025 Local format: 02/15/2025 02:30:45 PM
Timezone-aware datetime formatting
When working with timezones, f-strings can format aware datetime objects. This example uses the zoneinfo module (Python 3.9+) for timezone handling.
from datetime import datetime from zoneinfo import ZoneInfo utc_time = datetime.now(ZoneInfo('UTC')) ny_time = utc_time.astimezone(ZoneInfo('America/New_York')) tokyo_time = utc_time.astimezone(ZoneInfo('Asia/Tokyo')) print(f"UTC: {utc_time:%Y-%m-%d %H:%M %Z}") print(f"New York: {ny_time:%Y-%m-%d %I:%M %p %Z}") print(f"Tokyo: {tokyo_time:%Y年%m月%d日 %H時%M分}")
This code shows the same moment in time in three different timezones. Each f-string includes the timezone abbreviation (%Z). The Tokyo format demonstrates using f-strings with non-ASCII characters in format specs.
$ python main.py UTC: 2025-02-15 14:30 UTC New York: 2025-02-15 09:30 AM EST Tokyo: 2025年02月15日 23時30分
Formatting datetime in logging messages
F-strings are particularly useful for including timestamps in log messages. This example shows how to create formatted log entries with datetime.
from datetime import datetime def log_message(level, message): now = datetime.now() print(f"[{now:%Y-%m-%d %H:%M:%S.%f}] [{level.upper():<7}] {message}") log_message("info", "System started") log_message("warning", "Low disk space") log_message("error", "Connection failed")
This logging function uses f-strings to format consistent log messages. The timestamp includes microseconds (%f). The log level is left-aligned and padded to 7 characters. This creates neatly aligned log output.
$ python main.py [2025-02-15 14:30:45.123456] [INFO ] System started [2025-02-15 14:30:45.123456] [WARNING] Low disk space [2025-02-15 14:30:45.123456] [ERROR ] Connection failed
Advanced datetime formatting with conditionals
F-strings can include conditional expressions for dynamic formatting. This example shows how to change the format based on datetime values.
from datetime import datetime, time now = datetime.now() current_time = now.time() greeting = ( f"Good {'morning' if time(5,0) <= current_time < time(12,0) else 'afternoon' " f"if time(12,0) <= current_time < time(18,0) else 'evening'}" ) print(f"{greeting}! It's {now:%A, %B %d}") print(f"{'🌞' if current_time.hour < 18 else '🌜'} {now:%I:%M %p}")
This code determines the appropriate greeting based on the time of day. It uses nested conditional expressions within the f-string. The second line shows an emoji based on whether it's daytime or evening.
$ python main.py Good afternoon! It's Saturday, February 15 🌞 02:30 PM
Formatting datetime in data structures
F-strings work well when formatting datetime objects in lists or dictionaries. This example shows formatting multiple dates in a loop.
from datetime import datetime, timedelta today = datetime.now() dates = [today + timedelta(days=i) for i in range(-2, 3)] print("Upcoming dates:") for date in dates: print(f"- {date:%a %b %d}: {'Past' if date < today else 'Today' if date == today else 'Future'}") events = { "Meeting": today.replace(hour=14, minute=0), "Deadline": today + timedelta(days=2), "Reminder": today.replace(hour=9, minute=0) + timedelta(days=1) } print("\nEvents:") for name, when in events.items(): print(f"{name:<10} {when:%Y-%m-%d %I:%M %p} ({'Today' if when.date() == today.date() else when.strftime('%A')})")
This example demonstrates datetime formatting in loops and dictionaries. The first part shows relative date descriptions. The second part formats events with different datetime formats based on whether they're today.
$ python main.py Upcoming dates: - Thu Feb 13: Past - Fri Feb 14: Past - Sat Feb 15: Today - Sun Feb 16: Future - Mon Feb 17: Future Events: Meeting 2025-02-15 02:00 PM (Today) Deadline 2025-02-17 02:30 PM (Monday) Reminder 2025-02-16 09:00 AM (Sunday)
Parsing date strings and formatting
Often, you receive dates as strings and need to convert them into
datetime
objects before you can format them. Python's
datetime.strptime()
method is used for this parsing.
Once parsed, you can format the datetime
object using f-strings.
from datetime import datetime date_string = "2024-07-26 10:30:00" dt_object = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S") print(f"Parsed datetime: {dt_object}") print(f"Formatted date: {dt_object:%A, %B %d, %Y}") print(f"Formatted time: {dt_object:%I:%M %p}") another_date_string = "15/Mar/2023" dt_object_date_only = datetime.strptime(another_date_string, "%d/%b/%Y").date() print(f"Parsed date object: {dt_object_date_only}") print(f"Formatted: {dt_object_date_only:%d %B, %Y}")
The first example parses a full datetime string, and the second parses a
string into a date object. strptime
requires a format string
that matches the input string's structure.
$ python main.py Parsed datetime: 2024-07-26 10:30:00 Formatted date: Friday, July 26, 2024 Formatted time: 10:30 AM Parsed date object: 2023-03-15 Formatted: 15 March, 2023
Formatting date and time objects
The datetime
module also provides separate date
and time
objects. These can be created and formatted
independently if you only need to work with dates or times.
F-strings handle these objects just as well.
from datetime import date, time today_date = date(2025, 8, 15) specific_time = time(16, 45, 30) print(f"Date: {today_date:%A, %d %B %Y}") print(f"ISO Date: {today_date:%Y-%m-%d}") print(f"Time: {specific_time:%I:%M:%S %p}") print(f"24-hour Time: {specific_time:%H.%M}")
This example shows creating specific date
and time
objects and formatting them using various f-string directives.
$ python main.py Date: Friday, 15 August 2025 ISO Date: 2025-08-15 Time: 04:45:30 PM 24-hour Time: 16.45
Working with Unix timestamps
Unix timestamps (seconds since the epoch, January 1, 1970, UTC) are a
common way to represent time. Python's datetime
module can
convert timestamps to datetime
objects and vice versa.
These datetime
objects can then be formatted using f-strings.
from datetime import datetime timestamp = 1678886400 # Represents 2023-03-15 12:00:00 UTC # Convert timestamp to datetime object (UTC) dt_object_utc = datetime.utcfromtimestamp(timestamp) # For local time, use fromtimestamp() dt_object_local = datetime.fromtimestamp(timestamp) print(f"UTC from timestamp: {dt_object_utc:%Y-%m-%d %H:%M:%S %Z}") print(f"Local from timestamp: {dt_object_local:%Y-%m-%d %H:%M:%S %Z%z}") # %Z%z for timezone info # Convert datetime object back to timestamp now = datetime.now() current_timestamp = now.timestamp() print(f"Current datetime: {now:%Y-%m-%d %H:%M:%S}") print(f"Current timestamp: {current_timestamp}")
This code demonstrates converting a Unix timestamp to a datetime
object (both UTC and local time) and then formatting it. It also shows
converting a current datetime
object back to a timestamp.
Note that %Z
might be empty for naive objects on some systems;
using timezone-aware objects is better for full timezone name display.
$ python main.py UTC from timestamp: 2023-03-15 12:00:00 UTC Local from timestamp: 2023-03-15 13:00:00 CET+0100 Current datetime: 2025-02-15 14:30:45 Current timestamp: 1739629845.123456
Source
Python datetime - Documentation
This tutorial has shown various ways to format datetime objects using Python's f-strings. F-strings provide a clean, readable syntax for datetime formatting that's often more intuitive than traditional methods.
Author
List all Python tutorials.