Skip to content Skip to sidebar Skip to footer

How To Not Start The Next Day With Datetime While Adding A Timedelta?

Given a current time of 23:30:00 and I add two hours (7200 seconds). How can I get the time of the same day? So I want as a result 25:30:00. Currently I am only able to get the tim

Solution 1:

If you are just wanting to increment hours minutes, seconds and create a string:

def weird_time(current_time,duration):
    start = datetime.strptime(current_time, "%H:%M:%S")
    st_hr, st_min, st_sec = start.hour, start.minute, start.second
    mn, secs = divmod(duration, 60)
    hour, mn = divmod(mn, 60)
    mn, secs = st_min+mn, st_sec+secs
    if secs > 59:
        m, secs = divmod(secs,60)
        mn += m
    if mn > 59:
        h, mn = divmod(mn,60)
        hour += h
    return "{:02}:{:02}:{:02}".format(st_hr+hour, mn, secs)

Output:

In [19]: weird_time("23:30:00",7200)
Out[19]: '25:30:00'

In [20]: weird_time("23:30:00",3600)
Out[20]: '24:30:00'

In [21]: weird_time("23:30:59",7203)
Out[21]: '25:31:02'

In [22]: weird_time("23:30:59",3601)
Out[22]: '24:31:00'

Instead of doing all the calculations ourselves we can also use timedelta to calculate the total seconds and do our calculations from that:

from datetime import datetime,timedelta


def weird_time(current_time,duration):
    start = datetime.strptime(current_time, "%H:%M:%S")
    st_hr, st_min, st_sec = start.hour, start.minute, start.second
    comb = timedelta(minutes=st_min,seconds=st_sec) + timedelta(seconds=duration)
    mn, sec = divmod(comb.total_seconds(), 60)
    hour, mn = divmod(mn, 60)
    return "{:02}:{:02}:{:02}".format(int(st_hr+hour), int(mn), int(sec))

Which outputs the same:

In [29]: weird_time("23:30:00",7200)
Out[29]: '25:30:00'

In [30]: weird_time("23:30:00",3600)
Out[30]: '24:30:00'

In [31]: weird_time("23:30:59",7203)
Out[31]: '25:31:02'

In [32]: weird_time("23:30:59",3601)
Out[32]: '24:31:00'

In [33]:  weird_time("05:00:00",3600)
Out[33]: '06:00:00'

The hours just need to be incremented, the part that we need to catch is when either the combined total of either seconds, minutes or both is greater than 59.


Solution 2:

Seems to me like what you want is to just add two timedeltas to get another timedelta... right?

from datetime import timedelta as td

t0 = td(hours=23, minutes=30)
t1 = t0 + td(seconds=7200)
print(t1)  # prints "1 day, 1:30:00"
print("Hours: {}".format(t1.days*24 + int(t1.seconds/3600)))  # prints "Hours: 25"

Solution 3:

I want to generate a valid GTFS dataset. Google defines that a trip that goes into the next day requires a time like this: http://developers.google.com/transit/gtfs/reference#stop_times_fields

To get the correct time you have to take into account daylight savings time changes:

#!/usr/bin/env python
from datetime import datetime, time, timedelta
from tzlocal import get_localzone # $ pip install tzlocal

local_timezone = get_localzone()
current_time = datetime.now(local_timezone)
noon_naive = datetime.combine(current_time, time(12,0))
noon = local_timezone.localize(noon_naive, is_dst=None)

departure_time = (current_time - noon + timedelta(hours=12))
duration = timedelta(hours=2)
arrival_time = departure_time + duration
# -> datetime.timedelta(1, 5400)

To convert timedelta to HH:MM:SS format:

hours, seconds = divmod(arrival_time.total_seconds(), 3600)
minutes, seconds = divmod(seconds, 60)
print("%(hours)02d:%(minutes)02d:%(seconds)02d" % vars())
# -> 25:30:00

Post a Comment for "How To Not Start The Next Day With Datetime While Adding A Timedelta?"