getmtime() vs datetime.now():
The posted fragment can be easily improved by switching from local to UTC time. There are no summer (daylight saving) time changes in UTC. Just replace these two datetime functions now()
-> utcnow()
(docs) and fromtimestamp()
-> utcfromtimestamp()
(docs).
However, if the only expected output is a file age in seconds, we can directly use the timestamps (seconds from an "epoch") without any conversion:
import time
import os.path
...
age = time.time() - os.path.getmtime(file_name)
both your datetime objects are 'naive', meaning that they don't know about DST. datetime.now()
returns the current time your machine runs on, and that might include DST. Same goes for datetime.fromtimestamp(os.path.getmtime())
.
#1 - localizing your datetime objects could be an option; something like
from datetime import datetime
import tzlocal
now_aware = tzlocal.get_localzone().localize(datetime.now())
file_mtime = datetime.fromtimestamp(os.path.getmtime(file))
# assuming the file was created on a machine in the same timezone (!):
file_mtime_aware = now_aware.tzinfo.localize(file_mtime)
age = now_aware - file_mtime_aware
#2 - another option, using UTC conversion with datetime
:
now = datetime.utcnow()
age = now - datetime.utcfromtimestamp(os.path.getmtime(file_name))
if (age.seconds + age.days * 24 * 3600) < -180:
print(f'WARN: file has timestamp from future?: {age} s')
#3 - as VPfB points out in his answer, os.path.getmtime
returns a UTC timestamp (check os module docs and time module docs). So the easiest solution could be to skip conversion to datetime
in the first place and use only UTC timestamps; e.g. getting the current UTC timestamp as time.time()
.
Working with timezones can drive you mad... but there're some good resources out there, e.g. this medium post.