LINUX.ORG.RU

Перевод шарповских тиков в питоновскую datetime

 


0

1

Информация о времени хранится как набор байтиков, я их читаю из файла через struct.unpack('<q', data)[0] в int перегоняю, получается -8585939013345960378. И что-то я не понимаю, что дальше с этим делать и получить дату что-то типа декабря 2020

★★

Точно в int нужно прегонять, а не в long?

https://stackoverflow.com/questions/3682748/converting-unix-timestamp-string-to-readable-date

Когда получишь нормальное число, потом сюда посмотри как их превратить в дату. Не забывай, что большое число тиков, если там ms или даже ns, следует соратить делением дабы получить убодоваримый для Python-методово диапазон.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от EXL
❯ ipython
Python 3.9.1 (default, Dec 13 2020, 11:55:53) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import sys

In [2]: sys.maxsize
Out[2]: 9223372036854775807
tz4678 ★★
() автор топика
Ответ на: комментарий от EXL

то я видел, в коде у меня такое:

creation_time = r.read_long()

где r:

import struct
from typing import IO, Tuple


class BinaryReader:
    def __init__(self, fp: IO[bytes]) -> None:
        self.fp = fp

    def read(self, n: int) -> bytes:
        return self.fp.read(n)

    def seek(self, offset: int = 0, *args, **kwargs) -> int:
        return self.fp.seek(offset, *args, **kwargs)

    # In [1]: import sys

    # In [2]: sys.byteorder
    # Out[2]: 'little'
    # принудительно в little-endian
    # Используем типы из C#
    # https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/builtin-types/integral-numeric-types
    def read_byte(self) -> int:
        return struct.unpack('<B', self.read(1))[0]

    def read_bool(self) -> int:
        return struct.unpack('<?', self.read(1))[0]

    def read_short(self) -> int:
        return struct.unpack('<h', self.read(2))[0]

    def read_ushort(self) -> int:
        return struct.unpack('<H', self.read(2))[0]

    def read_int(self) -> int:
        return struct.unpack('<i', self.read(4))[0]

    def read_uint(self) -> int:
        return struct.unpack('<I', self.read(4))[0]

    def read_long(self) -> int:
        return struct.unpack('<q', self.read(8))[0]

    def read_ulong(self) -> int:
        return struct.unpack('<Q', self.read(8))[0]

    def read_float(self) -> float:
        return struct.unpack('<f', self.read(4))[0]

    def read_double(self) -> float:
        return struct.unpack('<d', self.read(8))[0]

    def read_pstring(self) -> str:
        """ Pascal String """
        i = self.read_byte()
        # Мне неизвестно в какой кодировке строки
        return self.read(i).decode('utf-8', 'replace')

tz4678 ★★
() автор топика
Последнее исправление: tz4678 (всего исправлений: 1)
Ответ на: комментарий от anonymous

это не я пишу. это файлы игры

tz4678 ★★
() автор топика
Ответ на: комментарий от fulmar_lor

перед тем как 8 байт в файлик записать, эти тики в int64 переводятся. вот я этот int64 и читаю. может, не может, а по факту там такое значение. остальные значения полей считываются верно судя по тестам

tz4678 ★★
() автор топика
import struct
import datetime

t_bytes = struct.pack('<q', -8585939013345960378)
t_bytes.hex()  # '469e5826f59dd888'

t = struct.unpack('<q', bytes.fromhex('469e5826f59dd808'))[0]
datetime.datetime(1, 1, 1) + datetime.timedelta(microseconds=t // 10)  # datetime.datetime(2020, 12, 11, 16, 52, 30, 881543)

Т.е. у тебя там почему-то 0x88 вместо 0x08 в последнем байте.

fulmar_lor
()
Последнее исправление: fulmar_lor (всего исправлений: 1)
Ответ на: комментарий от fulmar_lor

сишарповский код:

w.CreationTime = w.Version < 141 ? DateTime.Now.ToBinary() : w.CreationTime = r.ReadInt64();
w.MoonType = r.ReadByte();

Мой код:

creation_time = r.read_long()
moon_type = r.read_byte()
    def read_long(self) -> int:
        return struct.unpack('<q', self.read(8))[0]
tz4678 ★★
() автор топика
Ответ на: комментарий от tz4678

https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tobinary?view=net-5.0

A 64-bit signed integer that encodes the Kind and Ticks properties.

Вот откуда у тебя лишняя инфа в серилизованных байтах - это Kind.

var dt = DateTime.Now;
Console.WriteLine("{0:X}", dt.ToBinary()); // 88D8A81147B78A9F
		
dt = DateTime.SpecifyKind(dt, DateTimeKind.Unspecified);
Console.WriteLine("{0:X}", dt.ToBinary()); //  8D8A81147B78A9F
fulmar_lor
()
Ответ на: комментарий от fulmar_lor

Спс.

using System;

class MainClass {
  public static void Main (string[] args) {
    var dt = DateTime.Now;
    Console.WriteLine(dt.ToBinary());
    dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
Console.WriteLine(dt.ToBinary());
  }
}
 mcs -out:main.exe main.cs
 mono main.exe
-8585927876211104298
-8585927876211104298
 

In [14]: n = -8585927876211104298

In [15]: ticks = n & 0x3FFFFFFFFFFFFFFF

...

In [17]: kind = n >> 62

In [18]: ticks
Out[18]: 637444160643671510

In [19]: kind
Out[19]: -2

In [20]: import datetime

In [21]: datetime.datetime(1, 1, 1) + datetime.timedelta(microseconds=ticks // 10)
Out[21]: datetime.datetime(2020, 12, 24, 14, 14, 24, 367151)
tz4678 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.