Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store time without date in Python so it's convenient to compare?

I have a simple task of storing a time in server's timezone and then comparing if current time if after or before the saved time.

I tried to store the time as a "Jan 1st 2008" date with the time I need. The problem is a daylight saving time gets in a way, if I save "16:00" on Jan 1st and try to compare it with "16:00" on April 1st I get an one hour difference. I want "16:00" to always mean current day's "16:00".

What would be an efficient and reliable way of storing and comparing time of the day and ignoring the date? I need it to also be json-serializable, so I can easily manipulate the value in python and JS if needed.

like image 506
serg Avatar asked Dec 05 '22 18:12

serg


2 Answers

I need it to also be json-serializable, so I can easily manipulate the value in python and JS if needed.

"16:00" string could be used to store the time (if you don't need seconds).

I want "16:00" to always mean current day's "16:00".

To compare it with the current time:

import time

if time.strftime('%H:%M') < '16:00':
    print('before 4pm')
else:
    print('after 4pm')

%H, %M produce zero-padded decimal numbers such as 07 and therefore the string comparison works correctly. It works in the presence of DST transitions too (as long as C localtime() works).

To parse it into time, datetime objects:

from datetime import datetime

four_pm_time = datetime.strptime('16:00', '%H:%M').time()
four_pm = datetime.combine(datetime.now(), four_pm_time)

To get a timezone-aware datetime object:

import tzlocal # $ pip install tzlocal

four_pm_aware = tzlocal.get_localzone().localize(four_pm, is_dst=None)

To get Unix time corresponding to 4pm (assuming mktime() works here):

import time

unix_time = time.mktime(time.localtime()[:3] + (16, 0, 0) + (-1,)*3)
like image 55
jfs Avatar answered Dec 08 '22 06:12

jfs


Just store it however you want, then use the .time() method of the datetime objects and make comparisons.

from datetime import datetime
dt1 = datetime(2008, 1, 1, 16, 0, 0)
dt2 = datetime(2008, 4, 7, 13, 30, 0)

print(dt1.time() > dt2.time())    # True

You can also just turn your datetimes into naive datetime objects if you want to do "wall clock" arithmetic on them (as opposed to "timeline" arithmetic, which should be done with UTC datetimes):

from dateutil import tz
from datetime import datetime
NEW_YORK = tz.gettz('America/New_York')
dt = datetime(2008, 1, 1, 16, 0, tzinfo=NEW_YORK)
dt_naive = dt.replace(tzinfo=None)   # datetime(2008, 1, 1, 16)
like image 29
Paul Avatar answered Dec 08 '22 06:12

Paul