Skip to content

Add to/from string methods to datetime.timedelta #85426

Open

Description

@tebeka
mannequin
BPO 41254
Nosy @tebeka, @abalkin, @ericvsmith, @vadmium, @pganssle

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2020-07-09.06:46:58.269>
labels = ['type-feature', 'library', '3.10']
title = 'Add to/from string methods to datetime.timedelta'
updated_at = <Date 2021-07-30.16:00:44.744>
user = 'https://github.com/tebeka'

bugs.python.org fields:

activity = <Date 2021-07-30.16:00:44.744>
actor = 'matthewkenigsberg'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2020-07-09.06:46:58.269>
creator = 'tebeka'
dependencies = []
files = []
hgrepos = []
issue_num = 41254
keywords = []
message_count = 5.0
messages = ['373380', '373400', '373439', '374017', '398564']
nosy_count = 6.0
nosy_names = ['tebeka', 'belopolsky', 'eric.smith', 'martin.panter', 'p-ganssle', 'matthewkenigsberg']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue41254'
versions = ['Python 3.10']

Activity

  1. tebeka commented on Jul 9, 2020

    tebekamannequin
    MannequinAuthor

    I suggest adding datetime.timedelta methods that convert to/from str.

    The reason is that I have several places where configuration contains various timeouts. I'd like to write '50ms' and not 0.05 which is more human readable.

    See https://golang.org/pkg/time/#ParseDuration for how Go does it.

  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    type-featureA feature request or enhancement
    on Jul 9, 2020
  3. vadmium commented on Jul 9, 2020

    @vadmium
    Member

    I don't know how much support this will get since there is already a str(timedelta) operation defined with a different format. But I don't like that format much. The day[s] part is too verbose, the H:MM:SS part could too easily be interpreted as D:HH:MM, and the result for negative deltas is horrible (-43 days, 23:59:55; see bpo-38701).

    My favourite format for a duration is usually the HTML 5 format like

    1w 0d 12h 0m 27s

    Another option is ISO 8601 format:

    P1W0DT12H0M27S

    But both of these standards only go down to the seconds unit, so 50 ms has to be 0.05s or PT0.05S.

  4. tebeka commented on Jul 10, 2020

    tebekamannequin
    MannequinAuthor

    I think the lack sub second parts in these formats is a disadvantage.
    There's a merit in using a standard but IMO it's more natural to write someting like "2s" in a configuration value than "P2S" which is more cryptic.

  5. pganssle commented on Jul 20, 2020

    @pganssle
    Member

    I think it is unlikely that we'll want to experiment with this directly in CPython. I don't think a fixed format (other than the annoying one that you already get from calling str on a timedelta) is appropriate, but designing a modular format for time differences is more complicated than it might seem. I have had an open issue on dateutil to implement this for ages, but I haven't seen or come up with any proposals for a DSL for specifying timedelta formats: dateutil/dateutil#444

    It is annoyingly complicated to do this, and I'd rather it be tried out in other libraries with more flexibility to make breaking changes and a shorter release cadence. Dateutil is a good choice, but a clear and thorough proposal (or at least examples of this done well in other ecosystems we can crib from) is necessary.

  6. matthewkenigsberg commented on Jul 30, 2021

    matthewkenigsbergmannequin
    Mannequin

    I think it would be nice to have a from str method that could reverse the behavior of str(timedelta). I'm trying to parse files that contain the output of str(timedelta), and there's no easy way to get them back to timedelta's

  7. transferred this issue fromon Apr 10, 2022
  8. StanFromIreland commented on Mar 16, 2025

    @StanFromIreland
    Member

    This should be closed as a duplicate of #86260 which has received a lot more discussion. It was originally one way of closing this issue but the discussion became more general too.

    On second thought it may be better to close the other one instead.

    This needs the extension-modules label ;-)

  9. added and removed on Mar 16, 2025
  10. picnixz commented on Mar 16, 2025

    @picnixz
    Member

    I think the other has more discussion so I don't know why we should close the other one. The disgressions were needed IMO. In addition, the other one is focused on isoformat() and fromisotimestamp(), while this one is another request IMO.

  11. StanFromIreland commented on Mar 16, 2025

    @StanFromIreland
    Member

    @picnixz

    I originally though of that, but I realized most of the discussion is off topic. (3rd party implementation links really, and the approach itself did not receive much support.)

    Same request, its just the other is proposes a certain way of doing it, if they were implemented it would close this. See the second post here.

  12. picnixz commented on Mar 16, 2025

    @picnixz
    Member

    3rd party implementation links really, and the approach itself did not receive much support.)

    3rd-party implementations are useful because they give you a precedent. So I think it's better to keep the other one rather than this one.

  13. StanFromIreland commented on Mar 16, 2025

    @StanFromIreland
    Member

    You are the core dev, I guess it's up to you anyway, close whichever one you think should be.

  14. picnixz commented on Mar 16, 2025

    @picnixz
    Member

    I think we can keep both opened because they are still different. Having to/fromtimestamp() does not necessarily mean we can't have a flexible format for parsing to/from strings. We could for instance have format specifiers. So I'm fine with keeping both issues opened.

  15. StanFromIreland commented on Oct 10, 2025

    @StanFromIreland
    Member

    From duplicate:

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirstdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions