Skip to content

Add format() method to datetime.timedelta for string formatting #139917

@Alihtt

Description

@Alihtt

Feature or enhancement

Proposal:

Add a format() method to datetime.timedelta objects to simplify formatting time durations for display, similar to how datetime objects have strftime().

Has this already been discussed elsewhere?

I have already searched and did not find an existing issue or discussion.

Links to previous discussion of this feature:

No response

The Problem

Currently, formatting a timedelta object for display requires manual arithmetic and is error-prone:

from datetime import timedelta

# Current approach - requires manual calculation
def format_timedelta(td):
    days = td.days
    hours, remainder = divmod(td.seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    
    if days:
        return f"{days}d {hours}h {minutes}m {seconds}s"
    elif hours:
        return f"{hours}h {minutes}m {seconds}s"
    else:
        return f"{minutes}m {seconds}s"

duration = timedelta(days=2, hours=3, minutes=30, seconds=45)
print(format_timedelta(duration))  # "2d 3h 30m 45s"

This pattern is repeated across many codebases, indicating a common need.

Proposed Solution

Add a format() method to timedelta that accepts a format string:

from datetime import timedelta

duration = timedelta(days=2, hours=3, minutes=30, seconds=45)

# Proposed new method
print(duration.format("%d days, %H:%M:%S"))     # "2 days, 03:30:45"
print(duration.format("%H hours %M minutes"))    # "51 hours 30 minutes"
print(duration.format("%d days"))                # "2 days"

# For durations less than a day
short_duration = timedelta(hours=1, minutes=30)
print(short_duration.format("%H:%M:%S"))         # "01:30:00"

Proposed Format Codes

Basic format codes (similar to strftime where applicable):

  • %d - days
  • %H - hours (00-23, remainder after days)
  • %M - minutes (00-59, remainder after hours)
  • %S - seconds (00-59, remainder after minutes)
  • %f - microseconds (000000-999999)

Total duration codes (useful for elapsed time):

  • %th - total hours (float)
  • %tm - total minutes (float)
  • %ts - total seconds (float)

Real-World Use Cases

Server/Application Monitoring:

uptime = datetime.now() - server_start
status = f"Uptime: {uptime.format('%d days, %H:%M:%S')}"

User-Friendly Task Duration:

elapsed = end_time - start_time
print(f"Backup completed in {elapsed.format('%H:%M:%S')}")

Video/Media Duration:

video_length = timedelta(seconds=7265)
display = video_length.format("%H:%M:%S")  # "02:01:05"

Benefits

  1. Reduces boilerplate - No more divmod arithmetic in application code
  2. Improves readability - Intent is clear from the format string
  3. Consistency - Similar API to datetime.strftime()
  4. Fewer bugs - Centralized, tested implementation

Questions for Core Developers

  1. Should the format codes exactly match strftime where possible, or use a simpler subset?
  2. How should negative timedeltas be handled in formatting?
  3. Would a simpler API be preferred (e.g., just common formats like to_hhmmss())?

I'm happy to implement this feature following the agreed-upon design, write tests, and update documentation. I have already set up the CPython development environment and am familiar with the datetime module structure.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions