Skip to content

Commit e8f17ca

Browse files
committed
Revert TIMESTAMP fields returned by the system to be naive datetime
objects to avoid a breaking change in timezone handling.
1 parent 17ae125 commit e8f17ca

File tree

5 files changed

+16
-9
lines changed

5 files changed

+16
-9
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ _______
4646
NoSQLHandle.table_request followed by TableResult.wait_for_completion.
4747
* Change PreparedStatement.set_variable method to support both name and position
4848
variables.
49-
* Enhance handling of TIMESTAMP types to consider a datetime instance with
50-
and explicit timezone.
49+
* Enhance handling of TIMESTAMP types to better handle a datetime instance with
50+
an explicit timezone. By default fields of type TIMESTAMP returned by the system
51+
are represented by a "naive" (not timezone aware) datetime object in the timezone UTC.
5152

5253
Fixed
5354
_____

docs/datatypes.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,7 @@ Timestamp in Borneo
7070
As mentioned above *Timestamp* fields are managed internally as UTC time. If a
7171
timezone is supplied when setting a *Timestamp*, either as a string or as a
7272
Python datetime object, it will be honored. The value will be converted to UTC
73-
internally and will be in UTC when returned in a row. If no timezone is
74-
supplied, python datetime instances and time strings are treated as UTC.
73+
internally and will be in UTC when returned in a row. Although they are represented
74+
in UTC returned datetime objects will be "naive" as described by Python documentation.
75+
On input, if no timezone is supplied, python datetime instances and time strings are
76+
treated as UTC.

src/borneo/serde.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,9 @@ def read_bytearray_with_int(bis):
362362

363363
@staticmethod
364364
def read_datetime(bis):
365-
# Deserialize a datetime value.
366-
return parser.parse(BinaryProtocol.read_string(bis)).replace(
367-
tzinfo=tz.UTC)
365+
# Deserialize a datetime value. Timezone is UTC, object is naive, not
366+
# timezone aware
367+
return parser.parse(BinaryProtocol.read_string(bis))
368368

369369
@staticmethod
370370
def read_decimal(bis):

test/put.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,11 @@ def testPutNormal(self):
196196
self.row['fld_time'] = (
197197
self.row['fld_time'].replace(tzinfo=tz.gettz('EST')))
198198
self.put_request.set_value(self.row).set_ttl(self.ttl)
199-
self.row['fld_time'] = self.row['fld_time'].astimezone(tz.UTC)
199+
# the replace(tzinfo=None) at the end makes the object a "naive"
200+
# datetime. Without that there is a datetime comparison problem in
201+
# check_get_result()
202+
self.row['fld_time'] = (
203+
self.row['fld_time'].astimezone(tz.UTC).replace(tzinfo=None))
200204
result = self.handle.put(self.put_request)
201205
expect_expiration = self.ttl.to_expiration_time(
202206
int(round(time() * 1000)))

test/testutils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def get_row(with_sid=True):
157157
row['fld_bool'] = True
158158
row['fld_str'] = '{"name": u1, "phone": null}'
159159
row['fld_bin'] = bytearray(pack('>i', 4))
160-
row['fld_time'] = datetime.now(tz.UTC)
160+
row['fld_time'] = datetime.now()
161161
row['fld_num'] = Decimal(5)
162162
location = OrderedDict()
163163
location['type'] = 'point'

0 commit comments

Comments
 (0)