Fix (de)serialization of negative timestamps (#1241)

This commit is contained in:
binares
2019-08-01 19:47:38 +03:00
committed by Lonami
parent 2ace4fde41
commit 2b277dd558
2 changed files with 27 additions and 12 deletions

View File

@@ -1,7 +1,21 @@
import base64
import json
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):
@@ -121,21 +135,21 @@ class TLObject:
@staticmethod
def serialize_datetime(dt):
if not dt:
if not dt and not isinstance(dt, timedelta):
return b'\0\0\0\0'
if isinstance(dt, datetime):
dt = int(dt.timestamp())
dt = _datetime_to_timestamp(dt)
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):
dt = int(dt)
elif isinstance(dt, timedelta):
# Timezones are tricky. datetime.now() + ... timestamp() works
dt = int((datetime.now() + dt).timestamp())
# Timezones are tricky. datetime.utcnow() + ... timestamp() works
dt = _datetime_to_timestamp(datetime.utcnow() + dt)
if isinstance(dt, int):
return struct.pack('<I', dt)
return struct.pack('<i', dt)
raise TypeError('Cannot interpret "{}" as a date.'.format(dt))