Updates to 'date' and 'time' type handling.
datetime.date --> 'date' datetime.time --> 'time' datetime.time seemed to be the best native type for time, but it doesn't have nanosecond resolution. Clients must use int types for that.
This commit is contained in:
@@ -36,7 +36,7 @@ import io
|
|||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
import datetime
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ apache_cassandra_type_prefix = 'org.apache.cassandra.db.marshal.'
|
|||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
_number_types = frozenset((int, float))
|
_number_types = frozenset((int, float))
|
||||||
_time_types = frozenset((int))
|
_time_types = frozenset((int,))
|
||||||
_date_types = frozenset((int))
|
_date_types = frozenset((int,))
|
||||||
long = int
|
long = int
|
||||||
else:
|
else:
|
||||||
_number_types = frozenset((int, long, float))
|
_number_types = frozenset((int, long, float))
|
||||||
@@ -74,6 +74,15 @@ def unix_time_from_uuid1(u):
|
|||||||
return (u.time - 0x01B21DD213814000) / 10000000.0
|
return (u.time - 0x01B21DD213814000) / 10000000.0
|
||||||
|
|
||||||
|
|
||||||
|
def datetime_from_timestamp(timestamp):
|
||||||
|
if timestamp >= 0:
|
||||||
|
dt = datetime.datetime.utcfromtimestamp(timestamp)
|
||||||
|
else:
|
||||||
|
# PYTHON-119: workaround for Windows
|
||||||
|
dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=timestamp)
|
||||||
|
return dt
|
||||||
|
|
||||||
|
|
||||||
_casstypes = {}
|
_casstypes = {}
|
||||||
|
|
||||||
|
|
||||||
@@ -543,26 +552,26 @@ class DateType(_CassandraType):
|
|||||||
typename = 'timestamp'
|
typename = 'timestamp'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate(cls, date):
|
def validate(cls, val):
|
||||||
if isinstance(date, six.string_types):
|
if isinstance(val, six.string_types):
|
||||||
date = cls.interpret_datestring(date)
|
val = cls.interpret_datestring(val)
|
||||||
return date
|
return val
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def interpret_datestring(date):
|
def interpret_datestring(val):
|
||||||
if date[-5] in ('+', '-'):
|
if val[-5] in ('+', '-'):
|
||||||
offset = (int(date[-4:-2]) * 3600 + int(date[-2:]) * 60) * int(date[-5] + '1')
|
offset = (int(val[-4:-2]) * 3600 + int(val[-2:]) * 60) * int(val[-5] + '1')
|
||||||
date = date[:-5]
|
val = val[:-5]
|
||||||
else:
|
else:
|
||||||
offset = -time.timezone
|
offset = -time.timezone
|
||||||
for tformat in cql_timestamp_formats:
|
for tformat in cql_timestamp_formats:
|
||||||
try:
|
try:
|
||||||
tval = time.strptime(date, tformat)
|
tval = time.strptime(val, tformat)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
continue
|
continue
|
||||||
return calendar.timegm(tval) + offset
|
return calendar.timegm(tval) + offset
|
||||||
else:
|
else:
|
||||||
raise ValueError("can't interpret %r as a date" % (date,))
|
raise ValueError("can't interpret %r as a date" % (val,))
|
||||||
|
|
||||||
def my_timestamp(self):
|
def my_timestamp(self):
|
||||||
return self.val
|
return self.val
|
||||||
@@ -570,12 +579,7 @@ class DateType(_CassandraType):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(byts, protocol_version):
|
def deserialize(byts, protocol_version):
|
||||||
timestamp = int64_unpack(byts) / 1000.0
|
timestamp = int64_unpack(byts) / 1000.0
|
||||||
if timestamp >= 0:
|
return datetime_from_timestamp(timestamp)
|
||||||
dt = datetime.utcfromtimestamp(timestamp)
|
|
||||||
else:
|
|
||||||
# PYTHON-119: workaround for Windows
|
|
||||||
dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
|
|
||||||
return dt
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize(v, protocol_version):
|
def serialize(v, protocol_version):
|
||||||
@@ -635,85 +639,87 @@ class SimpleDateType(_CassandraType):
|
|||||||
date_format = "%Y-%m-%d"
|
date_format = "%Y-%m-%d"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate(cls, date):
|
def validate(cls, val):
|
||||||
if isinstance(date, basestring):
|
if isinstance(val, six.string_types):
|
||||||
date = cls.interpret_simpledate_string(date)
|
val = cls.interpret_simpledate_string(val)
|
||||||
return date
|
elif (not isinstance(val, datetime.date)) and (type(val) not in _date_types):
|
||||||
|
raise TypeError('SimpleDateType arg must be a datetime.date, unsigned integer, or string in the format YYYY-MM-DD')
|
||||||
|
return val
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def interpret_simpledate_string(v):
|
def interpret_simpledate_string(v):
|
||||||
try:
|
date_time = datetime.datetime.strptime(v, SimpleDateType.date_format)
|
||||||
tval = time.strptime(v, SimpleDateType.date_format)
|
return datetime.date(date_time.year, date_time.month, date_time.day)
|
||||||
# shift upward w/epoch at 2**31
|
|
||||||
return (calendar.timegm(tval) / SimpleDateType.seconds_per_day) + 2**31
|
|
||||||
except TypeError:
|
|
||||||
# Ints are valid dates too
|
|
||||||
if type(v) not in _date_types:
|
|
||||||
raise TypeError('Date arguments must be an unsigned integer or string in the format YYYY-MM-DD')
|
|
||||||
return v
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize(val, protocol_version):
|
def serialize(val, protocol_version):
|
||||||
date_val = SimpleDateType.interpret_simpledate_string(val)
|
# Values of the 'date'` type are encoded as 32-bit unsigned integers
|
||||||
return uint32_pack(date_val)
|
# representing a number of days with "the epoch" at the center of the
|
||||||
|
# range (2^31). Epoch is January 1st, 1970
|
||||||
|
try:
|
||||||
|
shifted = (calendar.timegm(val.timetuple()) // SimpleDateType.seconds_per_day) + 2 ** 31
|
||||||
|
except AttributeError:
|
||||||
|
shifted = val
|
||||||
|
return uint32_pack(shifted)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(byts, protocol_version):
|
def deserialize(byts, protocol_version):
|
||||||
Result = namedtuple('SimpleDate', 'value')
|
timestamp = SimpleDateType.seconds_per_day * (uint32_unpack(byts) - 2 ** 31)
|
||||||
return Result(value=uint32_unpack(byts))
|
dt = datetime.datetime.utcfromtimestamp(timestamp)
|
||||||
|
return datetime.date(dt.year, dt.month, dt.day)
|
||||||
|
|
||||||
|
|
||||||
class TimeType(_CassandraType):
|
class TimeType(_CassandraType):
|
||||||
typename = 'time'
|
typename = 'time'
|
||||||
ONE_MICRO=1000
|
ONE_MICRO = 1000
|
||||||
ONE_MILLI=1000*ONE_MICRO
|
ONE_MILLI = 1000 * ONE_MICRO
|
||||||
ONE_SECOND=1000*ONE_MILLI
|
ONE_SECOND = 1000 * ONE_MILLI
|
||||||
ONE_MINUTE=60*ONE_SECOND
|
ONE_MINUTE = 60 * ONE_SECOND
|
||||||
ONE_HOUR=60*ONE_MINUTE
|
ONE_HOUR = 60 * ONE_MINUTE
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate(cls, val):
|
def validate(cls, val):
|
||||||
if isinstance(val, basestring):
|
if isinstance(val, six.string_types):
|
||||||
time = cls.interpret_timestring(val)
|
val = cls.interpret_timestring(val)
|
||||||
return time
|
elif (not isinstance(val, datetime.time)) and (type(val) not in _time_types):
|
||||||
|
raise TypeError('TimeType arguments must be a string or whole number')
|
||||||
|
return val
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def interpret_timestring(val):
|
def interpret_timestring(val):
|
||||||
try:
|
try:
|
||||||
nano = 0
|
nano = 0
|
||||||
try:
|
parts = val.split('.')
|
||||||
base_time_str = val
|
base_time = time.strptime(parts[0], "%H:%M:%S")
|
||||||
if '.' in base_time_str:
|
nano = (base_time.tm_hour * TimeType.ONE_HOUR +
|
||||||
base_time_str = val[0:val.find('.')]
|
base_time.tm_min * TimeType.ONE_MINUTE +
|
||||||
base_time = time.strptime(base_time_str, "%H:%M:%S")
|
base_time.tm_sec * TimeType.ONE_SECOND)
|
||||||
nano = base_time.tm_hour * TimeType.ONE_HOUR
|
|
||||||
nano += base_time.tm_min * TimeType.ONE_MINUTE
|
|
||||||
nano += base_time.tm_sec * TimeType.ONE_SECOND
|
|
||||||
|
|
||||||
if '.' in val:
|
if len(parts) > 1:
|
||||||
nano_time_str = val[val.find('.')+1:]
|
# right pad to 9 digits
|
||||||
# right pad to 9 digits
|
nano_time_str = parts[1] + "0" * (9 - len(parts[1]))
|
||||||
while len(nano_time_str) < 9:
|
nano += int(nano_time_str)
|
||||||
nano_time_str += "0"
|
|
||||||
nano += int(nano_time_str)
|
|
||||||
|
|
||||||
except AttributeError as e:
|
|
||||||
if type(val) not in _time_types:
|
|
||||||
raise TypeError('TimeType arguments must be a string or whole number')
|
|
||||||
# long / int values passed in are acceptable too
|
|
||||||
nano = val
|
|
||||||
return nano
|
return nano
|
||||||
except ValueError as e:
|
except ValueError:
|
||||||
raise ValueError("can't interpret %r as a time" % (val,))
|
raise ValueError("can't interpret %r as a time" % (val,))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize(val, protocol_version):
|
def serialize(val, protocol_version):
|
||||||
return int64_pack(TimeType.interpret_timestring(val))
|
# Values of the @time@ type are encoded as 64-bit signed integers
|
||||||
|
# representing the number of nanoseconds since midnight.
|
||||||
|
try:
|
||||||
|
nano = (val.hour * TimeType.ONE_HOUR +
|
||||||
|
val.minute * TimeType.ONE_MINUTE +
|
||||||
|
val.second * TimeType.ONE_SECOND +
|
||||||
|
val.microsecond * TimeType.ONE_MICRO)
|
||||||
|
except AttributeError:
|
||||||
|
nano = val
|
||||||
|
return int64_pack(nano)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(byts, protocol_version):
|
def deserialize(byts, protocol_version):
|
||||||
Result = namedtuple('Time', 'value')
|
return int64_unpack(byts)
|
||||||
return Result(value=int64_unpack(byts))
|
|
||||||
|
|
||||||
|
|
||||||
class UTF8Type(_CassandraType):
|
class UTF8Type(_CassandraType):
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class Encoder(object):
|
|||||||
UUID: self.cql_encode_object,
|
UUID: self.cql_encode_object,
|
||||||
datetime.datetime: self.cql_encode_datetime,
|
datetime.datetime: self.cql_encode_datetime,
|
||||||
datetime.date: self.cql_encode_date,
|
datetime.date: self.cql_encode_date,
|
||||||
|
datetime.time: self.cql_encode_time,
|
||||||
dict: self.cql_encode_map_collection,
|
dict: self.cql_encode_map_collection,
|
||||||
OrderedDict: self.cql_encode_map_collection,
|
OrderedDict: self.cql_encode_map_collection,
|
||||||
list: self.cql_encode_list_collection,
|
list: self.cql_encode_list_collection,
|
||||||
@@ -146,9 +147,16 @@ class Encoder(object):
|
|||||||
def cql_encode_date(self, val):
|
def cql_encode_date(self, val):
|
||||||
"""
|
"""
|
||||||
Converts a :class:`datetime.date` object to a string with format
|
Converts a :class:`datetime.date` object to a string with format
|
||||||
``YYYY-MM-DD-0000``.
|
``YYYY-MM-DD``.
|
||||||
"""
|
"""
|
||||||
return "'%s'" % val.strftime('%Y-%m-%d-0000')
|
return "'%s'" % val.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
def cql_encode_time(self, val):
|
||||||
|
"""
|
||||||
|
Converts a :class:`datetime.date` object to a string with format
|
||||||
|
``HH:MM:SS.mmmuuunnn``.
|
||||||
|
"""
|
||||||
|
return "'%s'" % val
|
||||||
|
|
||||||
def cql_encode_sequence(self, val):
|
def cql_encode_sequence(self, val):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import logging
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import datetime
|
from datetime import datetime, date, time
|
||||||
import six
|
import six
|
||||||
from uuid import uuid1, uuid4
|
from uuid import uuid1, uuid4
|
||||||
|
|
||||||
@@ -31,7 +31,6 @@ from cassandra.cluster import Cluster
|
|||||||
from cassandra.cqltypes import Int32Type, EMPTY
|
from cassandra.cqltypes import Int32Type, EMPTY
|
||||||
from cassandra.query import dict_factory
|
from cassandra.query import dict_factory
|
||||||
from cassandra.util import OrderedDict, sortedset
|
from cassandra.util import OrderedDict, sortedset
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
from tests.integration import get_server_versions, use_singledc, PROTOCOL_VERSION
|
from tests.integration import get_server_versions, use_singledc, PROTOCOL_VERSION
|
||||||
|
|
||||||
@@ -171,6 +170,8 @@ class TypeTests(unittest.TestCase):
|
|||||||
v1_uuid = uuid1()
|
v1_uuid = uuid1()
|
||||||
v4_uuid = uuid4()
|
v4_uuid = uuid4()
|
||||||
mydatetime = datetime(2013, 12, 31, 23, 59, 59, 999000)
|
mydatetime = datetime(2013, 12, 31, 23, 59, 59, 999000)
|
||||||
|
mydate = date(2015, 1, 15)
|
||||||
|
mytime = time(16, 47, 25, 7)
|
||||||
|
|
||||||
params = [
|
params = [
|
||||||
"sometext",
|
"sometext",
|
||||||
@@ -192,13 +193,10 @@ class TypeTests(unittest.TestCase):
|
|||||||
v1_uuid, # timeuuid
|
v1_uuid, # timeuuid
|
||||||
u"sometext\u1234", # varchar
|
u"sometext\u1234", # varchar
|
||||||
123456789123456789123456789, # varint
|
123456789123456789123456789, # varint
|
||||||
'2014-01-01', # date
|
mydate, # date
|
||||||
'01:02:03.456789012' # time
|
mytime
|
||||||
]
|
]
|
||||||
|
|
||||||
SimpleDate = namedtuple('SimpleDate', 'value')
|
|
||||||
Time = namedtuple('Time', 'value')
|
|
||||||
|
|
||||||
expected_vals = (
|
expected_vals = (
|
||||||
"sometext",
|
"sometext",
|
||||||
"sometext",
|
"sometext",
|
||||||
@@ -219,8 +217,8 @@ class TypeTests(unittest.TestCase):
|
|||||||
v1_uuid, # timeuuid
|
v1_uuid, # timeuuid
|
||||||
u"sometext\u1234", # varchar
|
u"sometext\u1234", # varchar
|
||||||
123456789123456789123456789, # varint
|
123456789123456789123456789, # varint
|
||||||
SimpleDate(2147499719), # date
|
mydate, # date
|
||||||
Time(3723456789012) # time
|
60445000007000 # time
|
||||||
)
|
)
|
||||||
|
|
||||||
s.execute("""
|
s.execute("""
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ except ImportError:
|
|||||||
import unittest # noqa
|
import unittest # noqa
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
from datetime import datetime
|
from datetime import datetime, date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
@@ -79,8 +79,9 @@ marshalled_value_pairs = (
|
|||||||
(b'\x00\x00', 'ListType(FloatType)', []),
|
(b'\x00\x00', 'ListType(FloatType)', []),
|
||||||
(b'\x00\x00', 'SetType(IntegerType)', sortedset()),
|
(b'\x00\x00', 'SetType(IntegerType)', sortedset()),
|
||||||
(b'\x00\x01\x00\x10\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0', 'ListType(TimeUUIDType)', [UUID(bytes=b'\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0')]),
|
(b'\x00\x01\x00\x10\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0', 'ListType(TimeUUIDType)', [UUID(bytes=b'\xafYC\xa3\xea<\x11\xe1\xabc\xc4,\x03"y\xf0')]),
|
||||||
(b'\x00\x00>\xc7', 'SimpleDateType', '2014-01-01'),
|
(b'\x80\x00\x00\x01', 'SimpleDateType', date(1970,1,2)),
|
||||||
(b'\x00\x00\x00\x00\x00\x00\x00\x01', 'TimeType', '00:00:00.000000001')
|
(b'\x7f\xff\xff\xff', 'SimpleDateType', date(1969,12,31)),
|
||||||
|
(b'\x00\x00\x00\x00\x00\x00\x00\x01', 'TimeType', 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
ordered_dict_value = OrderedDict()
|
ordered_dict_value = OrderedDict()
|
||||||
|
|||||||
@@ -128,56 +128,77 @@ class TypeTests(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
Test cassandra.cqltypes.SimpleDateType() construction
|
Test cassandra.cqltypes.SimpleDateType() construction
|
||||||
"""
|
"""
|
||||||
|
# from string
|
||||||
|
expected_date = datetime.date(1492, 10, 12)
|
||||||
|
sd = SimpleDateType('1492-10-12')
|
||||||
|
self.assertEqual(sd.val, expected_date)
|
||||||
|
|
||||||
nd = SimpleDateType.interpret_simpledate_string('2014-01-01')
|
# date
|
||||||
tval = time.strptime('2014-01-01', SimpleDateType.date_format)
|
sd = SimpleDateType(expected_date)
|
||||||
manual = calendar.timegm(tval) / SimpleDateType.seconds_per_day
|
self.assertEqual(sd.val, expected_date)
|
||||||
self.assertEqual(nd, manual)
|
|
||||||
|
|
||||||
nd = SimpleDateType.interpret_simpledate_string('1970-01-01')
|
# int
|
||||||
self.assertEqual(nd, 0)
|
expected_timestamp = calendar.timegm(expected_date.timetuple())
|
||||||
|
sd = SimpleDateType(expected_timestamp)
|
||||||
|
self.assertEqual(sd.val, expected_timestamp)
|
||||||
|
|
||||||
|
# no contruct
|
||||||
|
self.assertRaises(ValueError, SimpleDateType, '1999-10-10-bad-time')
|
||||||
|
self.assertRaises(TypeError, SimpleDateType, 1.234)
|
||||||
|
|
||||||
def test_time(self):
|
def test_time(self):
|
||||||
"""
|
"""
|
||||||
Test cassandra.cqltypes.TimeType() construction
|
Test cassandra.cqltypes.TimeType() construction
|
||||||
"""
|
"""
|
||||||
|
|
||||||
one_micro = 1000
|
one_micro = 1000
|
||||||
one_milli = 1000L*one_micro
|
one_milli = 1000 * one_micro
|
||||||
one_second = 1000L*one_milli
|
one_second = 1000 * one_milli
|
||||||
one_minute = 60L*one_second
|
one_minute = 60 * one_second
|
||||||
one_hour = 60L*one_minute
|
one_hour = 60 * one_minute
|
||||||
|
|
||||||
nd = TimeType.interpret_timestring('00:00:00.000000001')
|
# from strings
|
||||||
self.assertEqual(nd, 1)
|
tt = TimeType('00:00:00.000000001')
|
||||||
nd = TimeType.interpret_timestring('00:00:00.000001')
|
self.assertEqual(tt.val, 1)
|
||||||
self.assertEqual(nd, one_micro)
|
tt = TimeType('00:00:00.000001')
|
||||||
nd = TimeType.interpret_timestring('00:00:00.001')
|
self.assertEqual(tt.val, one_micro)
|
||||||
self.assertEqual(nd, one_milli)
|
tt = TimeType('00:00:00.001')
|
||||||
nd = TimeType.interpret_timestring('00:00:01')
|
self.assertEqual(tt.val, one_milli)
|
||||||
self.assertEqual(nd, one_second)
|
tt = TimeType('00:00:01')
|
||||||
nd = TimeType.interpret_timestring('00:01:00')
|
self.assertEqual(tt.val, one_second)
|
||||||
self.assertEqual(nd, one_minute)
|
tt = TimeType('00:01:00')
|
||||||
nd = TimeType.interpret_timestring('01:00:00')
|
self.assertEqual(tt.val, one_minute)
|
||||||
self.assertEqual(nd, one_hour)
|
tt = TimeType('01:00:00')
|
||||||
|
self.assertEqual(tt.val, one_hour)
|
||||||
|
tt = TimeType('01:00:00.')
|
||||||
|
self.assertEqual(tt.val, one_hour)
|
||||||
|
|
||||||
nd = TimeType('23:59:59.1')
|
tt = TimeType('23:59:59.1')
|
||||||
nd = TimeType('23:59:59.12')
|
tt = TimeType('23:59:59.12')
|
||||||
nd = TimeType('23:59:59.123')
|
tt = TimeType('23:59:59.123')
|
||||||
nd = TimeType('23:59:59.1234')
|
tt = TimeType('23:59:59.1234')
|
||||||
nd = TimeType('23:59:59.12345')
|
tt = TimeType('23:59:59.12345')
|
||||||
|
|
||||||
nd = TimeType.interpret_timestring('23:59:59.123456')
|
tt = TimeType('23:59:59.123456')
|
||||||
self.assertEquals(nd, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro)
|
self.assertEqual(tt.val, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro)
|
||||||
|
|
||||||
nd = TimeType.interpret_timestring('23:59:59.1234567')
|
tt = TimeType('23:59:59.1234567')
|
||||||
self.assertEquals(nd, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 700)
|
self.assertEqual(tt.val, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 700)
|
||||||
|
|
||||||
nd = TimeType.interpret_timestring('23:59:59.12345678')
|
tt = TimeType('23:59:59.12345678')
|
||||||
self.assertEquals(nd, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 780)
|
self.assertEqual(tt.val, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 780)
|
||||||
|
|
||||||
|
tt = TimeType('23:59:59.123456789')
|
||||||
|
self.assertEqual(tt.val, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 789)
|
||||||
|
|
||||||
|
# from int
|
||||||
|
tt = TimeType(12345678)
|
||||||
|
self.assertEqual(tt.val, 12345678)
|
||||||
|
|
||||||
|
# no construct
|
||||||
|
self.assertRaises(ValueError, TimeType, '1999-10-10 11:11:11.1234')
|
||||||
|
self.assertRaises(TypeError, TimeType, 1.234)
|
||||||
|
self.assertRaises(TypeError, TimeType, datetime.datetime(2004, 12, 23, 11, 11, 1))
|
||||||
|
|
||||||
nd = TimeType.interpret_timestring('23:59:59.123456789')
|
|
||||||
self.assertEquals(nd, 23*one_hour + 59*one_minute + 59*one_second + 123*one_milli + 456*one_micro + 789)
|
|
||||||
|
|
||||||
def test_cql_typename(self):
|
def test_cql_typename(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user