mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-25 19:03:46 +03:00
Fix (de)serialization of negative timestamps (#1241)
This commit is contained in:
parent
2ace4fde41
commit
2b277dd558
|
@ -2,14 +2,18 @@
|
||||||
This module contains the BinaryReader utility class.
|
This module contains the BinaryReader utility class.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone, timedelta
|
||||||
from io import BufferedReader, BytesIO
|
from io import BufferedReader, BytesIO
|
||||||
from struct import unpack
|
from struct import unpack
|
||||||
|
import time
|
||||||
|
|
||||||
from ..errors import TypeNotFoundError
|
from ..errors import TypeNotFoundError
|
||||||
from ..tl.alltlobjects import tlobjects
|
from ..tl.alltlobjects import tlobjects
|
||||||
from ..tl.core import core_objects
|
from ..tl.core import core_objects
|
||||||
|
|
||||||
|
_EPOCH_NAIVE = datetime(*time.gmtime(0)[:6])
|
||||||
|
_EPOCH = _EPOCH_NAIVE.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
class BinaryReader:
|
class BinaryReader:
|
||||||
"""
|
"""
|
||||||
|
@ -120,10 +124,7 @@ class BinaryReader:
|
||||||
into a Python datetime object.
|
into a Python datetime object.
|
||||||
"""
|
"""
|
||||||
value = self.read_int()
|
value = self.read_int()
|
||||||
if value == 0:
|
return _EPOCH + timedelta(seconds=value)
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return datetime.fromtimestamp(value, tz=timezone.utc)
|
|
||||||
|
|
||||||
def tgread_object(self):
|
def tgread_object(self):
|
||||||
"""Reads a Telegram object."""
|
"""Reads a Telegram object."""
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import struct
|
import struct
|
||||||
from datetime import datetime, date, timedelta
|
from datetime import datetime, date, timedelta, timezone
|
||||||
|
import time
|
||||||
|
|
||||||
|
_EPOCH_NAIVE = datetime(*time.gmtime(0)[:6])
|
||||||
|
_EPOCH_NAIVE_LOCAL = datetime(*time.localtime(0)[:6])
|
||||||
|
_EPOCH = _EPOCH_NAIVE.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
def _datetime_to_timestamp(dt):
|
||||||
|
# If no timezone is specified, it is assumed to be in utc zone
|
||||||
|
if dt.tzinfo is None:
|
||||||
|
dt = dt.replace(tzinfo=timezone.utc)
|
||||||
|
# We use .total_seconds() method instead of simply dt.timestamp(),
|
||||||
|
# because on Windows the latter raises OSError on datetimes ~< datetime(1970,1,1)
|
||||||
|
return int((dt - _EPOCH).total_seconds())
|
||||||
|
|
||||||
|
|
||||||
def _json_default(value):
|
def _json_default(value):
|
||||||
|
@ -121,21 +135,21 @@ class TLObject:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize_datetime(dt):
|
def serialize_datetime(dt):
|
||||||
if not dt:
|
if not dt and not isinstance(dt, timedelta):
|
||||||
return b'\0\0\0\0'
|
return b'\0\0\0\0'
|
||||||
|
|
||||||
if isinstance(dt, datetime):
|
if isinstance(dt, datetime):
|
||||||
dt = int(dt.timestamp())
|
dt = _datetime_to_timestamp(dt)
|
||||||
elif isinstance(dt, date):
|
elif isinstance(dt, date):
|
||||||
dt = int(datetime(dt.year, dt.month, dt.day).timestamp())
|
dt = _datetime_to_timestamp(datetime(dt.year, dt.month, dt.day))
|
||||||
elif isinstance(dt, float):
|
elif isinstance(dt, float):
|
||||||
dt = int(dt)
|
dt = int(dt)
|
||||||
elif isinstance(dt, timedelta):
|
elif isinstance(dt, timedelta):
|
||||||
# Timezones are tricky. datetime.now() + ... timestamp() works
|
# Timezones are tricky. datetime.utcnow() + ... timestamp() works
|
||||||
dt = int((datetime.now() + dt).timestamp())
|
dt = _datetime_to_timestamp(datetime.utcnow() + dt)
|
||||||
|
|
||||||
if isinstance(dt, int):
|
if isinstance(dt, int):
|
||||||
return struct.pack('<I', dt)
|
return struct.pack('<i', dt)
|
||||||
|
|
||||||
raise TypeError('Cannot interpret "{}" as a date.'.format(dt))
|
raise TypeError('Cannot interpret "{}" as a date.'.format(dt))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user