How to subtract military time between days with datetime module - python

I am working on a time lapse program and I would like to be able to pause overnight over multiple days. I am using military time and when I try say 18:00:00 as pause start and 08:00:00 as pause end I get a negative number. I could probably take the difference between 24:00:00 and 18:00:00 and 0:00:00 and 08:00:00 and add them to get the answer, but I'm wondering if there is something I'm missing in the datetime module that would allow me to do this?
from datetime import datetime
pause_start=input('Enter pause start time as 24 hrs (hh:mm:ss): ')
pause_end=input('Enter pause end time as 24 hrs (hh:mm:ss): ')
pause_start=datetime.strptime(pause_start, '%H:%M:%S')
pause_end=datetime.strptime(pause_end, '%H:%M:%S')
total_pause_time=(pause_end-pause_start).total_seconds()
print(total_pause_time)
input:18:00:00
input:08:00:00
output:-36000.0
I tried an input of 25:00:00 and received an error saying time data did not match format '%H:%M:%S' therefore I believe it is being read correctly as military time.

What you are missing, is that you are calculating with times on the same day. So you are subtracting the later time from the earlier time which gives a negative result. I see two solutions:
Add 24 hours to the final result to get the correct offset.
Create datetime objects so that 18:00:00 is today and 08:00:00 is tomorrow morning. Then subtract the dates.

Related

Get next midnight date and time using Python time library only

I have a timestamp generated from time.time().
Example: 1597316030
Converting to date and time this gives "Thursday, August 13, 2020 10:53:50 AM GMT+00:00".
Is it possible to get the timestamp that would correspond to "Thursday, August 14, 2020 12:00:00 AM GMT+00:00" (next midnight, or any other date and time), using only time library (without date or datetime, for example)?
Thanks!
using only time library (without date or datetime, for example)?
It is possible without any library and quite simple after you realize that: 0 is start of epoch is midnight 1 Jan 1970 and every 24 hour is 86400 second, therefore any midnight will be multiply of 86400, thus you just need to find smallest multiply of 86400 greater than your timestamp, which can be done following way:
t = 1597316030
t2 = ((t//86400)+1)*86400
print(t2)
Output:
1597363200
Keep in mind that this solution totally ignore existence of timezones.

Calculate time difference only considering hours

I want to calculate the time difference in hour not considering the date.
For example I want the difference between 22:00:00 and 01:00:00 to be 3.
The code I got so far:
time1 = datetime.strptime("22:00:00", '%H:%M:%S')
time2 = datetime.strptime("01:00:00", '%H:%M:%S')
res = time1-time2
print(res)
The output I got: 21:00:00
The output I want: 3
You cannot extract the hours directly from the resulting timedelta object, as they keep fraction-of-day as seconds, so a simple workaround is to take the seconds and calculate the hours from there.
Also note that you want to subtract time1 to time2, otherwise you will get 21 hours:
(time2 - time1).seconds/3600
# 3

How to suitably choose the correct unit for datetime?

I have a list of datetimes which I have converted to relative times since now. This gives me the time between the date in DateString and now, however this is in days.
(datetime.datetime.today() - datetime.datetime.strptime(DateString, '%d-%m-%Y %H:%M:%S')).days
There are instances where I have 0 days but also 100 days. How would I correctly choose the unit for any given DateString? The options of units must only include seconds, minutes, days and weeks.
Example:
>>> 10-03-2019 15:50:00
10 minutes ago
>>> 10-03-2019 08:00:00
8 hours ago

Why does timedelta work differently when working with datetime

I have this function where it calculates today. I am wondering why is the following results are happening.
today = datetime.datetime.now()
shows as 2018-06-13 17:13:42.372469
today = datetime.datetime.now().date()
shows as 2018-06-13
but when I try to use timedelta like this:
today = datetime.datetime.now().date() + datetime.timedelta(hours=-8)
it shows 2018-06-12. A full day back instead of 8 hours (should show 2018-06-13 9:13:42)
Can someone please explain why this happens and have timedelta correctly go back 8 hours instead of a day?
By reducing the timestamp to the date only, you have effectively set the time to 00:00:00 - substracting 8 hours from 2018-06-13 midnight correctly results in 2018-06-12.
Why not use the correct timestamps for calculation, and only convert them to dates after you have performed them?

What is the fastest way to detect when two timestamps produce the same local time in Python?

The UNIX timestamps 1289106000 and 1289109600 both represent 2010-11-07T01:00:00 in the US-East EST/EDT timezone, as a result of daylight savings time. I'm creating a dictionary-like object, keyed on timestamp, that needs to map any such pairs to the same value.
Additionally, as much as we want to avoid premature optimization, I happen to know that this operation is performed in an extremely tight loop. Any solution must be faster than using fromtimestamp to obtain the local time for each timestamp.
Is there a way to structure my object's back-end storage, or build some sort of lookup table in advance, that makes this possible?
You could build a table, stretching as far into the past or future as you wish, with the overlapping hour for each year. It's easy to convert the timestamp to an approximate year with a simple division. Look up the tuple (start_leap_hour,end_leap_hour) from the year; if the timestamp is between them, subtract an hour.
Regarding how one might generate a table of DST critical times:
This generates the datetimes when Daylight Savings Time "fall back" occurs:
import datetime as dt
import time
import itertools
def fall_dst_boundaries(date=None):
'''
Generates the datetimes when Daylight Savings Time "fall back" occurs after date.
'''
if date is None:
date=dt.datetime.now()
timestamp=time.mktime(date.timetuple())//3600 * 3600
previous_date=dt.datetime.fromtimestamp(timestamp)
while True:
timestamp+=3600
date=dt.datetime.fromtimestamp(timestamp)
if date==previous_date:
yield date
previous_date=date
for date in itertools.islice(fall_dst_boundaries(dt.datetime(1980,1,1)),15):
print(date)
yields:
1980-10-26 01:00:00
1981-10-25 01:00:00
1982-10-31 01:00:00
1983-10-30 01:00:00
1984-10-28 01:00:00
1985-10-27 01:00:00
1986-10-26 01:00:00
1987-10-25 01:00:00
1988-10-30 01:00:00
1989-10-29 01:00:00
1990-10-28 01:00:00
1991-10-27 01:00:00
1992-10-25 01:00:00
1993-10-31 01:00:00
1994-10-30 01:00:00
PS. DST ends at 2am, but the hour the gets repeated is 1am.
To generate both the "fall back" and "spring forward" datetimes, you could use something like this:
def DST_boundaries(date=None):
'''
Generates the datetimes when Daylight Savings Time "fall back" or "spring
forward" occurs after date.
'''
if date is None:
date=dt.datetime.now()
timestamp=time.mktime(date.timetuple())//3600 * 3600 + 3599
previous_date=dt.datetime.fromtimestamp(timestamp)
while True:
timestamp+=3600
date=dt.datetime.fromtimestamp(timestamp)
if date==previous_date or date.hour-previous_date.hour>1:
yield previous_date
previous_date=date

Categories

Resources