python конвертирует filetime в datetime для дат до 1970 года

Мне нужно преобразовать filetime в datetime. Я использую этот код filetime.py, из здесь, как указано в этот поток Datetime to filetime (Python).

В коде

EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS file time
HUNDREDS_OF_NANOSECONDS = 10000000

def filetime_to_dt(ft):
    """Converts a Microsoft filetime number to a Python datetime. The new datetime object is time zone-naive but is equivalent to tzinfo=utc.

    >>> filetime_to_dt(116444736000000000)
    datetime.datetime(1970, 1, 1, 0, 0)
    """
    # Get seconds and remainder in terms of Unix epoch
    (s, ns100) = divmod(ft - EPOCH_AS_FILETIME, HUNDREDS_OF_NANOSECONDS)
    # Convert to datetime object
    dt = datetime.utcfromtimestamp(s)
    # Add remainder in as microseconds. Python 3.2 requires an integer
    dt = dt.replace(microsecond=(ns100 // 10))
    return dt

datetime.utcfromtimestamp не принимает отрицательное значение в системе Windows, поэтому я не могу преобразовать файловое время до 1 января 1970 года. Но я могу преобразовать даты до 1970 года на Mac, используя тот же самый код (причина здесь). Есть ли обходной путь для Windows?


person Echo    schedule 10.08.2016    source источник
comment
Итак, все, что вы имеете в виду, это то, что вы хотите преобразовать какое-то время эпохи в обычное время даты, верно?   -  person harshil9968    schedule 10.08.2016


Ответы (4)


Добавив timedelta к контрольной дате, вы можете использовать любую формулу даты, какую захотите. timedelta может быть положительным или отрицательным.

def filetime_to_dt(ft):
    us = (ft - EPOCH_AS_FILETIME) // 10
    return datetime(1970, 1, 1) + timedelta(microseconds = us)
person Mark Ransom    schedule 10.08.2016

Согласно документации, вы должны использовать:

dt = datetime.fromtimestamp(s, datetime.timezone.utc)

вместо:

dt = datetime.utcfromtimestamp(s)
person Aaron    schedule 10.08.2016
comment
извините, я использую import datetime datetime.timezone.utc, выдает ошибку AttributeError: объект «модуль» не имеет атрибута «часовой пояс». Это почему? - person Echo; 10.08.2016
comment
@Echo: Может быть, вы не используете Python 3? - person BlackJack; 24.08.2016
comment
Я использую Python 2 - person Echo; 24.08.2016

сначала вам нужно преобразовать его в узнаваемый формат времени файла, например:

>>> dwLowDateTime = 0x0F7297A80
>>> dwHighDateTime = 0x1C3F10F << 32
>>> ft = (dwLowDateTime & 0xFFFFFFFF) | dwHighDateTime
127210265370000000

а затем используйте этот сценарий, он преобразует файловое время в datetime и наоборот https://gist.github.com/Mostafa-Hamdy-Elgiar/9714475f1b3bc224ea063af81566d873

>>> filetime_to_dt(ft)
2004-02-12 02:28:57
person Alya Gomaa    schedule 20.07.2020

Используйте timedeltas для добавления / вычитания / деления между временными рамками:

FILE_TIME_EPOCH = datetime.datetime(1601, 1, 1)
FILE_TIME_MICROSECOND = 10 # FILETIME counts 100 nanoseconds intervals = 0.1 microseconds, so 10 of those are 1 microsecond

def convert_from_file_time(file_time):
    microseconds_since_file_time_epoch = file_time // FILE_TIME_MICROSECOND
    return FILE_TIME_EPOCH + datetime.timedelta(microseconds=microseconds_since_file_time_epoch)

И обратная сторона этого:

def convert_to_file_time(date_time):
    microseconds_since_file_time_epoch = (date_time - FILE_TIME_EPOCH) // datetime.timedelta(microseconds=1)
    return microseconds_since_file_time_epoch * FILE_TIME_MICROSECOND
person assembly_wizard    schedule 04.09.2020