0

I am wondering how to take a user-inputted string (i.e. 1 day, 5 hours, 15 minutes, 2 seconds) and convert it to either a timedelta object or (preferably) the number of seconds in that interval.

Note that:

  • This is not a question about s, it is about s. I don’t need “Tomorrow” or “In 5 minutes”, I need “1 day” or “5 minutes.”
  • All fields are optional
  • These are the possible fields:
    • year, years, or y
    • month, months, or m
    • week, weeks, or w
    • day, days, or d
    • hour, hours, or h
    • minute, minutes, or m
    • second, seconds, or s
  • If you can get me started, I can probably do the rest
  • The input can either be delimited by , or whitespace

Thank you!

Jed Fox
  • 2,979
  • 5
  • 28
  • 38

2 Answers2

1

You could use parsedatetime module:

#!/usr/bin/env python
from datetime import date, datetime
import parsedatetime as pdt # $ pip install parsedatetime

cal = pdt.Calendar()
midnight = datetime.fromordinal(date.today().toordinal())
for s in "1 day, 5 hours, 15 minutes, 2 seconds".split(', '):
    print(repr(cal.parseDT(s, midnight)[0] - midnight))

Output

datetime.timedelta(1)
datetime.timedelta(0, 18000)
datetime.timedelta(0, 900)
datetime.timedelta(0, 2)

To get number of seconds, call .total_seconds() or if you don't need fractions of a second; you could truncate it:

integer_seconds = td // timedelta(seconds=1)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

Thank you @y0prst for the answer!

Here it is, converted to a program:

import re, datetime
def get_seconds(text):
    splitted_input = filter(None, re.split('[, ]', text))
    assert len(splitted_input) % 2 == 0
    grouped_input = zip(*(iter(splitted_input),) * 2)
    # ⬆︎ This is tricky; see https://stackoverflow.com/questions/1624883/alternative-way-to-split-a-list-into-groups-of-n
    kwargs = {
        'year':0,
        'month':0,
        'day':0,
        'hour':0,
        'minute':0,
        'second':0,
        'microsecond':0,
    }
    for n, unit in grouped_input:
        n = int(n)
        if unit.startswith('y'):
            kwargs['year'] += n
        elif unit.startswith('mo'):
            kwargs['month'] += n
        elif unit.startswith('w'):
            kwargs['day'] += 7*n
        elif unit.startswith('d'):
            kwargs['day'] += n
        elif unit.startswith('h'):
            kwargs['hour'] += n
        elif unit.startswith('m'):
            kwargs['minute'] += n
        elif unit.startswith('s'):
            kwargs['second'] += n
        else:
            assert False, unit
    for k, v in kwargs:
        kwargs[k] += getattr(now, k)
    now = datetime.datetime.now()
    return (datetime.datetime(**kwargs) - now).total_seconds()
Community
  • 1
  • 1
Jed Fox
  • 2,979
  • 5
  • 28
  • 38