Skip to content

Commit

Permalink
Replace datetime.utcfromtimestamp
Browse files Browse the repository at this point in the history
It is depricated and to be removed soon.
Only method available out-of-box for this purpose is `datetime.fromtimestamp`.
But it either include timezone into datetime which is not acceptable, or offset datetime from utc which we don't want to happen.
On other hand `tz_info` in not writable on `datetime` and all API that
allows you to manipulate it offsets time.
So, simpliest solution would to be ship a function that calls `datetime.fromtimestamp` and then builds exactly same datetime with tz_info empty.
  • Loading branch information
dkropachev committed Jan 5, 2025
1 parent d62eb38 commit 18e2644
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 16 deletions.
4 changes: 2 additions & 2 deletions cassandra/cqlengine/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from cassandra.cqltypes import SimpleDateType, _cqltypes, UserType
from cassandra.cqlengine import ValidationError
from cassandra.cqlengine.functions import get_total_seconds
from cassandra.util import Duration as _Duration
from cassandra.util import Duration as _Duration, utcfromtimestamp

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -551,7 +551,7 @@ def to_python(self, value):
elif isinstance(value, date):
return datetime(*(value.timetuple()[:6]))

return datetime.utcfromtimestamp(value)
return utcfromtimestamp(value)

def to_database(self, value):
value = super(DateTime, self).to_database(value)
Expand Down
11 changes: 10 additions & 1 deletion cassandra/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,17 @@

from cassandra import DriverException


def utcfromtimestamp(timestamp):
"""
It replicates behavior of datetime.utcfromtimestamp
"""
dt = datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc)
return datetime.datetime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, fold=dt.fold)


DATETIME_EPOC = datetime.datetime(1970, 1, 1)
UTC_DATETIME_EPOC = datetime.datetime.utcfromtimestamp(0)
UTC_DATETIME_EPOC = utcfromtimestamp(0)

_nan = float('nan')

Expand Down
7 changes: 4 additions & 3 deletions tests/integration/cqlengine/columns/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import unittest

import sys
from datetime import datetime, timedelta, date, tzinfo, time
from datetime import datetime, timedelta, date, tzinfo, time, timezone
from decimal import Decimal as D
from uuid import uuid4, uuid1
from packaging.version import Version
Expand All @@ -30,6 +30,7 @@
from cassandra.cqlengine.models import Model, ValidationError
from cassandra.cqlengine.usertype import UserType
from cassandra import util
from cassandra.util import utcfromtimestamp

from tests.integration import PROTOCOL_VERSION, CASSANDRA_VERSION, greaterthanorequalcass30, greaterthanorequalcass3_11
from tests.integration.cqlengine.base import BaseCassEngTestCase
Expand Down Expand Up @@ -97,7 +98,7 @@ def test_datetime_timestamp(self):
dt_value = 1454520554
self.DatetimeTest.objects.create(test_id=5, created_at=dt_value)
dt2 = self.DatetimeTest.objects(test_id=5).first()
self.assertEqual(dt2.created_at, datetime.utcfromtimestamp(dt_value))
self.assertEqual(dt2.created_at, utcfromtimestamp(dt_value))

def test_datetime_large(self):
dt_value = datetime(2038, 12, 31, 10, 10, 10, 123000)
Expand Down Expand Up @@ -809,7 +810,7 @@ def test_conversion_specific_date(self):
assert isinstance(uuid, UUID)

ts = (uuid.time - 0x01b21dd213814000) / 1e7 # back to a timestamp
new_dt = datetime.utcfromtimestamp(ts)
new_dt = utcfromtimestamp(ts)

# checks that we created a UUID1 with the proper timestamp
assert new_dt == dt
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/cqlengine/model/test_model_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from uuid import uuid4, UUID
import random
from datetime import datetime, date, time
from datetime import datetime, date, time, timezone
from decimal import Decimal
from operator import itemgetter

Expand All @@ -26,7 +26,7 @@
from cassandra.cqlengine.management import drop_table
from cassandra.cqlengine.models import Model
from cassandra.query import SimpleStatement
from cassandra.util import Date, Time, Duration
from cassandra.util import Date, Time, Duration, utcfromtimestamp
from cassandra.cqlengine.statements import SelectStatement, DeleteStatement, WhereClause
from cassandra.cqlengine.operators import EqualsOperator

Expand Down Expand Up @@ -200,13 +200,13 @@ class AllDatatypesModel(Model):

sync_table(AllDatatypesModel)

input = ['ascii', 2 ** 63 - 1, bytearray(b'hello world'), True, datetime.utcfromtimestamp(872835240),
input = ['ascii', 2 ** 63 - 1, bytearray(b'hello world'), True, utcfromtimestamp(872835240),
Decimal('12.3E+7'), 2.39, 3.4028234663852886e+38, '123.123.123.123', 2147483647, 'text',
UUID('FE2B4360-28C6-11E2-81C1-0800200C9A66'), UUID('067e6162-3b6f-4ae2-a171-2470b63dff00'),
int(str(2147483647) + '000')]

AllDatatypesModel.create(id=0, a='ascii', b=2 ** 63 - 1, c=bytearray(b'hello world'), d=True,
e=datetime.utcfromtimestamp(872835240), f=Decimal('12.3E+7'), g=2.39,
e=utcfromtimestamp(872835240), f=Decimal('12.3E+7'), g=2.39,
h=3.4028234663852886e+38, i='123.123.123.123', j=2147483647, k='text',
l=UUID('FE2B4360-28C6-11E2-81C1-0800200C9A66'),
m=UUID('067e6162-3b6f-4ae2-a171-2470b63dff00'), n=int(str(2147483647) + '000'),
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/cqlengine/model/test_udts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.
import unittest

from datetime import datetime, date, time
from datetime import datetime, date, time, timezone
from decimal import Decimal
from mock import Mock
from uuid import UUID, uuid4
Expand All @@ -23,7 +23,7 @@
from cassandra.cqlengine import columns, connection
from cassandra.cqlengine.management import sync_table, drop_table, sync_type, create_keyspace_simple, drop_keyspace
from cassandra.cqlengine import ValidationError
from cassandra.util import Date, Time
from cassandra.util import Date, Time, utcfromtimestamp

from tests.integration import PROTOCOL_VERSION
from tests.integration.cqlengine.base import BaseCassEngTestCase
Expand Down Expand Up @@ -272,7 +272,7 @@ def test_can_insert_udts_with_all_datatypes(self):
self.addCleanup(drop_table, AllDatatypesModel)

input = AllDatatypes(a='ascii', b=2 ** 63 - 1, c=bytearray(b'hello world'), d=True,
e=datetime.utcfromtimestamp(872835240), f=Decimal('12.3E+7'), g=2.39,
e=utcfromtimestamp(872835240), f=Decimal('12.3E+7'), g=2.39,
h=3.4028234663852886e+38, i='123.123.123.123', j=2147483647, k='text',
l=UUID('FE2B4360-28C6-11E2-81C1-0800200C9A66'),
m=UUID('067e6162-3b6f-4ae2-a171-2470b63dff00'), n=int(str(2147483647) + '000'))
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from cassandra.util import (
OPEN_BOUND, Date, DateRange, DateRangeBound,
DateRangePrecision, Time, ms_timestamp_from_datetime,
datetime_from_timestamp
datetime_from_timestamp, utcfromtimestamp
)
from tests.unit.util import check_sequence_consistency

Expand Down Expand Up @@ -200,7 +200,7 @@ def test_empty_value(self):

def test_datetype(self):
now_time_seconds = time.time()
now_datetime = datetime.datetime.utcfromtimestamp(now_time_seconds)
now_datetime = utcfromtimestamp(now_time_seconds)

# Cassandra timestamps in millis
now_timestamp = now_time_seconds * 1e3
Expand All @@ -211,7 +211,7 @@ def test_datetype(self):
# deserialize
# epoc
expected = 0
self.assertEqual(DateType.deserialize(int64_pack(1000 * expected), 0), datetime.datetime.utcfromtimestamp(expected))
self.assertEqual(DateType.deserialize(int64_pack(1000 * expected), 0), utcfromtimestamp(expected))

# beyond 32b
expected = 2 ** 33
Expand Down

0 comments on commit 18e2644

Please sign in to comment.