How can I get the ctime and/or mtime of a file in Python including timezone?

3.4k Views Asked by At

Based on this related question and answer I asked, it has become obvious that datetime.fromtimestamp(os.path.getctime()) in Python 3.4 doesn't return a timezone-aware datetime object, However, based on some investigation, I've also discovered that OS X 10.9 on an HFS+ filesystem (for example) does seem to maintain the timezones along with ctimes (unless gls is inferring the timezone from my local timezone and daylight-savings time):

$ gls -l --full-time -c

-rw-------  1 myuser staff 538 2015-01-04 17:12:57.000000000 +0100 fileone
-rwxr-xr-x 17 myuser staff 578 2015-05-20 06:41:07.000000000 +0200 filetwo

(I am using the GNU version of ls)

How can I get the timezone from the ctime and insert/combine it into a datetime object?

(I'd also like the same answer for the mtime, I assume it will be similar).

3

There are 3 best solutions below

10
On BEST ANSWER

Both ctime and mtime are available as "seconds since epoch" (values returned by time.time()).

To get the local timezone, you could use tzlocal module:

#!/usr/bin/env python
import os
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal

local_timezone = get_localzone()
aware_dt = datetime.fromtimestamp(os.path.getctime(path), local_timezone)

You might see the timezone info because ls converts the timestamps into corresponding broken-down time with timezone offset using the local timezone.

6
On

If you only want to rely on Python Standard Library, you can only use the timezone subclass of tzinfo :

tz = datetime.timezone(datetime.timedelta(seconds=-time.timezone), time.tzname[0]) \
    if (time.daylight == 0 || time.localtime(os.path.getctime(path)).tm_isdst == 0) \
    else datetime.timezone(datetime.timedelta(seconds=-time.altzone), time.tzname[1])
dt = datetime.fromtimestamp(os.path.getctime(path), tz)

Then you could have (in France) :

>>> dt
datetime.datetime(2015, 6, 9, 13, 43, 3, 791255, tzinfo=datetime.timezone(datetime.timedelta(0, 7200), 'Paris, Madrid (heure d\x92été)'))
>>> dt.utctimetuple()
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=9, tm_hour=11, tm_min=43, tm_sec=3, tm_wday=1, tm_yday=160, tm_isdst=0)

Of course, mtime would work exactly the same

You should consult J.F. Sebastian's post for references. Here is an extract :

To get the current UTC offset in a way that workarounds the time.daylight issue and that works even if tm_gmtoff is not available, [this] can be used:

import time
from datetime import datetime

ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
              datetime.utcfromtimestamp(ts)).total_seconds()
0
On

This works for me:

import os, datetime, time

modified_time = os.path.getmtime(file)
mtime_obj = datetime.datetime(*time.localtime(modified_time)[:6])
# (or)
mtime_obj = datetime.datetime.fromtimestamp(modified_time)
print(mtime_obj.strftime('%Y-%m-%d_%H-%M-%S'))

No external packages. Just the standard python libraries. (Python 3.6)