Конвертирование даты и времени из xml в hex

Конвентирую бинарный файл в xml и обратно, точно знаю что в бинарном файле это значение 39D8CE0F отвечает за дату и время. Но не могу понять принцип конвертации. Пытаюсь написать функцию на Python, которая может конвентировать эти 4 байта в формат времени и даты. Есть список даты и времени в hex и в привычном виде:

39D8CE - day=4 month=8 year=2023 time=2000
39EDCE - day=25 month=8 year=2023 time=2000
25E7CE - day=19 month=8 year=2023 time=1500
3702CF - day=15 month=9 year=2023 time=1930
2769CE - day=15 month=4 year=2023 time=1530
0020D0 - day=1 month=2 year=2024 time=0
2768D0 - day=13 month=4 year=2024 time=1530
2769CE - day=15 month=4 year=2023 time=1530
274CD0 - day=16 month=3 year=2024 time=1530
35DCCE - day=8 month=8 year=2023 time=1900

Судя по всему, первый байт отвечает за время, Второй байт за день и месяц, Последний байт за год.

Есть идеи?


Ответы (1 шт):

Автор решения: 0andriy

После правки опечатки и с помощью первого комментария Super-intelligent Shade (почти) всё очевидно. Последовательность трёх байт представляет собой комбинацию времени в сутках (не в пятнадцатиминутных интервалах, а в тридцатиминутных), дня от начала года и собственно года. Разбивка по битам: 7 (время), 1 (AM/PM?), 9 (день), 7 (год).

Функцию декодера на Питоне написать несложно.

import datetime

def decode(timestamp):
    x = int.from_bytes(bytes.fromhex(timestamp), 'little')
    T = (((x & 0x0000fe) >> 1) + (x & 0x000001) * 12) * 30
    D = (x & 0x01ff00) >> 8
    Y = ((x & 0xfe0000) >> 17) + 1920
    return Y, D, T

def to_datetime(year, days, minutes):
    return datetime.datetime(year, 1, 1) + datetime.timedelta(days=days - 1, minutes=minutes)

Например,

In : input = "3702CF"
In : year, days, minutes = decode(input)
In : to_datetime(year, days, minutes)
Out: datetime.datetime(2023, 9, 15, 19, 30)

datetime — стандартная библиотека работы со временем, потом можно этот тип данных выводить в каком угодно формате.

P.S. Что касается декодера минут. Ваши примеры он пройдёт, но без примеров после десяти вечера и до полудня трудновато понять, если это правильно.

P.P.S. Прогон на приведённых в вопросе данных.

data = """\
39D8CE - day=4 month=8 year=2023 time=2000
39EDCE - day=25 month=8 year=2023 time=2000
25E7CE - day=19 month=8 year=2023 time=1500
3702CF - day=15 month=9 year=2023 time=1930
2769CE - day=15 month=4 year=2023 time=1530
0020D0 - day=1 month=2 year=2024 time=0
2768D0 - day=13 month=4 year=2024 time=1530
2769CE - day=15 month=4 year=2023 time=1530
274CD0 - day=16 month=3 year=2024 time=1530
35DCCE - day=8 month=8 year=2023 time=1900""".split('\n')

for line in data:
    print(f'{line[:6]} -> {to_datetime(*decode(line[:6]))} -> {line[9:]}')

Вывод:

39D8CE -> 2023-08-04 20:00:00 -> day=4 month=8 year=2023 time=2000
39EDCE -> 2023-08-25 20:00:00 -> day=25 month=8 year=2023 time=2000
25E7CE -> 2023-08-19 15:00:00 -> day=19 month=8 year=2023 time=1500
3702CF -> 2023-09-15 19:30:00 -> day=15 month=9 year=2023 time=1930
2769CE -> 2023-04-15 15:30:00 -> day=15 month=4 year=2023 time=1530
0020D0 -> 2024-02-01 00:00:00 -> day=1 month=2 year=2024 time=0
2768D0 -> 2024-04-13 15:30:00 -> day=13 month=4 year=2024 time=1530
2769CE -> 2023-04-15 15:30:00 -> day=15 month=4 year=2023 time=1530
274CD0 -> 2024-03-16 15:30:00 -> day=16 month=3 year=2024 time=1530
35DCCE -> 2023-08-08 19:00:00 -> day=8 month=8 year=2023 time=1900
→ Ссылка