From 6702cbea0e116f0dd0778a98c0451e1241a70898 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 12 Apr 2024 12:44:16 -0400 Subject: [PATCH 1/5] added support for centiseconds precision in the TimeElementsWithFractionOfSeconds added tests for TimeElementsWithFractionOfSeconds class --- dfdatetime/definitions.py | 3 + dfdatetime/precisions.py | 55 ++++++++++ dfdatetime/time_elements.py | 6 +- tests/precisions.py | 29 ++++++ tests/time_elements.py | 202 ++++++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+), 3 deletions(-) diff --git a/dfdatetime/definitions.py b/dfdatetime/definitions.py index 46200f4..7f7facc 100644 --- a/dfdatetime/definitions.py +++ b/dfdatetime/definitions.py @@ -13,6 +13,8 @@ DECISECONDS_PER_SECOND = 10 +CENTISECONDS_PER_SECOND = 100 + MILLISECONDS_PER_SECOND = 1000 MICROSECONDS_PER_DAY = 86400000000 @@ -23,6 +25,7 @@ NANOSECONDS_PER_DAY = 86400000000000 NANOSECONDS_PER_SECOND = 1000000000 NANOSECONDS_PER_DECISECOND = 100000000 +NANOSECONDS_PER_CENTISECOND = 10000000 NANOSECONDS_PER_MILLISECOND = 1000000 NANOSECONDS_PER_MICROSECOND = 1000 diff --git a/dfdatetime/precisions.py b/dfdatetime/precisions.py index 108ca1b..abfc59e 100644 --- a/dfdatetime/precisions.py +++ b/dfdatetime/precisions.py @@ -99,6 +99,60 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): f'{hours:02d}:{minutes:02d}:{seconds:02d}') +class CentisecondsPrecisionHelper(DateTimePrecisionHelper): + """Centiseconds (10 ms) precision helper.""" + + @classmethod + def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): + """Copies the number of nanoseconds to a fraction of second value. + + Args: + nanoseconds (int): number of nanoseconds. + + Returns: + decimal.Decimal: fraction of second, which must be a value between 0.00 + and 1.00. + + Raises: + ValueError: if the number of nanoseconds is out of bounds. + """ + if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: + raise ValueError( + f'Number of nanoseconds value: {nanoseconds:d} out of bounds.') + + centiseconds, _ = divmod( + nanoseconds, definitions.NANOSECONDS_PER_CENTISECOND) + return decimal.Decimal(centiseconds) / definitions.CENTISECONDS_PER_SECOND + + @classmethod + def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): + """Copies the time elements and fraction of second to a string. + + Args: + time_elements_tuple (tuple[int, int, int, int, int, int]): + time elements, contains year, month, day of month, hours, minutes and + seconds. + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.00 and 1.00. + + Returns: + str: date and time value formatted as: + YYYY-MM-DD hh:mm:ss.### + + Raises: + ValueError: if the fraction of second is out of bounds. + """ + if fraction_of_second < 0.00 or fraction_of_second >= 1.00: + raise ValueError( + f'Fraction of second value: {fraction_of_second:f} out of bounds.') + + year, month, day_of_month, hours, minutes, seconds = time_elements_tuple + centiseconds = int(fraction_of_second * definitions.CENTISECONDS_PER_SECOND) + + return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' + f'{hours:02d}:{minutes:02d}:{seconds:02d}.{centiseconds:02d}') + + class MillisecondsPrecisionHelper(DateTimePrecisionHelper): """Milliseconds precision helper.""" @@ -263,6 +317,7 @@ class PrecisionHelperFactory(object): """Date time precision helper factory.""" _PRECISION_CLASSES = { + definitions.PRECISION_10_MILLISECONDS: CentisecondsPrecisionHelper, definitions.PRECISION_1_MICROSECOND: MicrosecondsPrecisionHelper, definitions.PRECISION_1_MILLISECOND: MillisecondsPrecisionHelper, definitions.PRECISION_1_NANOSECOND: NanosecondsPrecisionHelper, diff --git a/dfdatetime/time_elements.py b/dfdatetime/time_elements.py index a463e96..8d7bd63 100644 --- a/dfdatetime/time_elements.py +++ b/dfdatetime/time_elements.py @@ -907,7 +907,7 @@ def __init__( Args: fraction_of_second (Optional[decimal.Decimal]): fraction of second, which - must be a value between 0.0 and 1.0. + must be a value between 0.00 and 1.00. is_delta (Optional[bool]): True if the date and time value is relative to another date and time value. precision (Optional[str]): precision of the date and time value, which @@ -923,7 +923,7 @@ def __init__( value is out of bounds. """ if fraction_of_second is not None: - if fraction_of_second < 0.0 or fraction_of_second >= 1.0: + if fraction_of_second < 0.00 or fraction_of_second >= 1.00: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') @@ -1035,7 +1035,7 @@ def CopyFromStringTuple(self, time_elements_tuple): raise ValueError( f'Invalid fraction of second value: {fraction_of_second_string!s}') - if fraction_of_second < 0.0 or fraction_of_second >= 1.0: + if fraction_of_second < 0.00 or fraction_of_second >= 1.00: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') diff --git a/tests/precisions.py b/tests/precisions.py index fcd558a..6aa8eca 100644 --- a/tests/precisions.py +++ b/tests/precisions.py @@ -56,6 +56,35 @@ def testCopyToDateTimeString(self): precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) +class CentisecondsPrevisionHelperTest(unittest.TestCase): + """Tests for the centiseconds prevision helper.""" + + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.CentisecondsPrecisionHelper + + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789) + self.assertEqual(fraction_of_second, decimal.Decimal('0.12')) + + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) + + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.CentisecondsPrecisionHelper + + date_time_string = precision_helper.CopyToDateTimeString( + (2018, 1, 2, 19, 45, 12), 0.123456) + self.assertEqual(date_time_string, '2018-01-02 19:45:12.12') + + with self.assertRaises(ValueError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + + class MillisecondsPrecisionHelperTest(unittest.TestCase): """Tests for the milliseconds precision helper.""" diff --git a/tests/time_elements.py b/tests/time_elements.py index 980d820..218afbf 100644 --- a/tests/time_elements.py +++ b/tests/time_elements.py @@ -6,6 +6,7 @@ import decimal import unittest +from dfdatetime import definitions from dfdatetime import time_elements @@ -1604,5 +1605,206 @@ def testNewFromDeltaAndYear(self): time_elements_object.NewFromDeltaAndYear(2009) +class TimeElementsWithFractionOfSeconds(unittest.TestCase): + """Tests for the time elements with fractions of seconds.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond() + self.assertIsNotNone(time_elements_object) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal(0.87), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple) + self.assertEqual(time_elements_object.fraction_of_second, 0.87) + + with self.assertRaises(ValueError): + time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('1.87'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + + with self.assertRaises(ValueError): + time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('-1'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.87')) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31), + time_zone_offset=60) + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.87')) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + time_elements_object.time_zone_offset = 60 + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.87')) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond() + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + def testCopyFromDateTimeValues(self): + """Tests the _CopyFromDateTimeValues function.""" + date_time_values = { + 'year': 2010, + 'month': 8, + 'day_of_month': 12, + 'hours': 21, + 'minutes': 6, + 'seconds': 31, + 'nanoseconds': 123456789, + 'time_zone_offset': 60} + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_10_MILLISECONDS) + time_elements_object._CopyFromDateTimeValues(date_time_values) + + self.assertEqual( + time_elements_object._time_elements_tuple, (2010, 8, 12, 21, 6, 31)) + self.assertEqual( + time_elements_object.fraction_of_second, decimal.Decimal('0.12')) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_1_MILLISECOND) + time_elements_object._CopyFromDateTimeValues(date_time_values) + self.assertEqual( + time_elements_object.fraction_of_second, decimal.Decimal('0.123')) + + def testCopyFromDatetime(self): + """Tests the CopyFromDatetime function.""" + datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + expected_fraction_of_second = decimal.Decimal('0.54') + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_10_MILLISECONDS) + time_elements_object.CopyFromDatetime(datetime_object) + + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple) + self.assertEqual( + time_elements_object._number_of_seconds, expected_number_of_seconds) + self.assertEqual( + time_elements_object.fraction_of_second, expected_fraction_of_second) + self.assertTrue(time_elements_object.is_local_time) + + datetime_object = datetime.datetime( + 2010, 8, 12, 21, 6, 31, 546875, tzinfo=datetime.timezone.utc) + time_elements_object.CopyFromDatetime(datetime_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple) + self.assertEqual( + time_elements_object._number_of_seconds, expected_number_of_seconds) + self.assertEqual( + time_elements_object.fraction_of_second, expected_fraction_of_second) + self.assertFalse(time_elements_object.is_local_time) + + def testCopyFromStringTuple(self): + """Tests the CopyFromStringTuple function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_10_MILLISECONDS) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + expected_fraction_of_second = decimal.Decimal('0.46') + time_elements_object.CopyFromStringTuple( + time_elements_tuple=('2010', '8', '12', '20', '6', '31', '0.46')) + + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple) + self.assertEqual( + time_elements_object.fraction_of_second, expected_fraction_of_second) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=('2010', '8', '12', '20', '6', '31')) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=('2010', '8', '12', '20', '6', '31', '96')) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, '2010-08-12 20:06:31.87') + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.874'), + precision=definitions.PRECISION_1_MILLISECOND, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, '2010-08-12 20:06:31.874') + + def testNewFromDeltaAndDate(self): + """Tests the NewFromDeltaAndDate function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + is_delta=True, + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(1, 0, 0, 20, 6, 31)) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertFalse(new_time_elements_object.is_delta) + self.assertEqual(new_time_elements_object.year, 2010) + self.assertEqual(new_time_elements_object.month, 1) + self.assertEqual(new_time_elements_object.day_of_month, 12) + self.assertEqual( + new_time_elements_object.fraction_of_second, decimal.Decimal('0.87')) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + time_elements_tuple=(1, 0, 0, 20, 6, 31)) + + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + + time_elements_object = time_elements.TimeElementsWithFractionOfSecond() + + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + + def testNewFromDeltaAndYear(self): + """Tests the NewFromDeltaAndYear function.""" + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.87'), + is_delta=True, + precision=definitions.PRECISION_10_MILLISECONDS, + time_elements_tuple=(1, 8, 12, 20, 6, 31)) + + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertFalse(new_time_elements_object.is_delta) + self.assertEqual(new_time_elements_object.year, 2010) + + if __name__ == '__main__': unittest.main() From 901abae23818a77f172c31ac70a3652ac2ebe904 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 12 Apr 2024 14:43:25 -0400 Subject: [PATCH 2/5] implemented 100us precision in TimeElementsWithFractionOfSecond --- dfdatetime/definitions.py | 3 ++ dfdatetime/precisions.py | 58 +++++++++++++++++++++++++++++++++++++++ tests/precisions.py | 28 +++++++++++++++++++ tests/time_elements.py | 39 +++++++++++++++++++++++++- 4 files changed, 127 insertions(+), 1 deletion(-) diff --git a/dfdatetime/definitions.py b/dfdatetime/definitions.py index 7f7facc..e8c9a9c 100644 --- a/dfdatetime/definitions.py +++ b/dfdatetime/definitions.py @@ -17,6 +17,8 @@ MILLISECONDS_PER_SECOND = 1000 +DECIMICROSECONDS_PER_SECOND = 10000 + MICROSECONDS_PER_DAY = 86400000000 MICROSECONDS_PER_SECOND = 1000000 MICROSECONDS_PER_DECISECOND = 100000 @@ -27,6 +29,7 @@ NANOSECONDS_PER_DECISECOND = 100000000 NANOSECONDS_PER_CENTISECOND = 10000000 NANOSECONDS_PER_MILLISECOND = 1000000 +NANOSECONDS_PER_DECIMILISECOND = 100000 NANOSECONDS_PER_MICROSECOND = 1000 PRECISION_1_DAY = '1d' diff --git a/dfdatetime/precisions.py b/dfdatetime/precisions.py index abfc59e..979b3b6 100644 --- a/dfdatetime/precisions.py +++ b/dfdatetime/precisions.py @@ -207,6 +207,63 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): f'{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}') +class DecimillisecondsPrecisionHelper(DateTimePrecisionHelper): + """Decimilliseconds (100 microseconds) precision helper.""" + + @classmethod + def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): + """Copies the number of nanoseconds to a fraction of second value. + + Args: + nanoseconds (int): number of nanoseconds. + + Returns: + decimal.Decimal: fraction of second, which must be a value between 0.0000 + and 1.0000. + + Raises: + ValueError: if the number of nanoseconds is out of bounds. + """ + if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: + raise ValueError( + f'Number of nanoseconds value: {nanoseconds:d} out of bounds.') + + decimiliseconds, _ = divmod( + nanoseconds, definitions.NANOSECONDS_PER_DECIMILISECOND) + return ( + decimal.Decimal(decimiliseconds) / + definitions.DECIMICROSECONDS_PER_SECOND) + + @classmethod + def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): + """Copies the time elements and fraction of second to a string. + + Args: + time_elements_tuple (tuple[int, int, int, int, int, int]): + time elements, contains year, month, day of month, hours, minutes and + seconds. + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.0000 and 1.0000. + + Returns: + str: date and time value formatted as: + YYYY-MM-DD hh:mm:ss.### + + Raises: + ValueError: if the fraction of second is out of bounds. + """ + if fraction_of_second < 0.0000 or fraction_of_second >= 1.0000: + raise ValueError( + f'Fraction of second value: {fraction_of_second:f} out of bounds.') + + year, month, day_of_month, hours, minutes, seconds = time_elements_tuple + decimicroseconds = int( + fraction_of_second * definitions.DECIMICROSECONDS_PER_SECOND) + + return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' + f'{hours:02d}:{minutes:02d}:{seconds:02d}.{decimicroseconds:04d}') + + class MicrosecondsPrecisionHelper(DateTimePrecisionHelper): """Microseconds precision helper.""" @@ -318,6 +375,7 @@ class PrecisionHelperFactory(object): _PRECISION_CLASSES = { definitions.PRECISION_10_MILLISECONDS: CentisecondsPrecisionHelper, + definitions.PRECISION_100_MICROSECONDS: DecimillisecondsPrecisionHelper, definitions.PRECISION_1_MICROSECOND: MicrosecondsPrecisionHelper, definitions.PRECISION_1_MILLISECOND: MillisecondsPrecisionHelper, definitions.PRECISION_1_NANOSECOND: NanosecondsPrecisionHelper, diff --git a/tests/precisions.py b/tests/precisions.py index 6aa8eca..ec08290 100644 --- a/tests/precisions.py +++ b/tests/precisions.py @@ -114,6 +114,34 @@ def testCopyToDateTimeString(self): precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) +class DeciMillisecondsPrevisionHelperTest(unittest.TestCase): + """Tests for the decimilliseconds precision helper.""" + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.DecimillisecondsPrecisionHelper + + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789) + self.assertEqual(fraction_of_second, decimal.Decimal('0.1234')) + + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) + + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.DecimillisecondsPrecisionHelper + + date_time_string = precision_helper.CopyToDateTimeString( + (2018, 1, 2, 19, 45, 12), 0.123456) + self.assertEqual(date_time_string, '2018-01-02 19:45:12.1234') + + with self.assertRaises(ValueError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + + class MicrosecondsPrecisionHelperTest(unittest.TestCase): """Tests for the microseconds precision helper.""" diff --git a/tests/time_elements.py b/tests/time_elements.py index 218afbf..dcde75a 100644 --- a/tests/time_elements.py +++ b/tests/time_elements.py @@ -1625,6 +1625,16 @@ def testInitialize(self): time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object.fraction_of_second, 0.87) + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal(0.8742), + precision=definitions.PRECISION_100_MICROSECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple) + self.assertEqual(time_elements_object.fraction_of_second, 0.8742) + with self.assertRaises(ValueError): time_elements.TimeElementsWithFractionOfSecond( fraction_of_second=decimal.Decimal('1.87'), @@ -1662,8 +1672,14 @@ def testGetNormalizedTimestamp(self): normalized_timestamp = time_elements_object._GetNormalizedTimestamp() self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.87')) - time_elements_object = time_elements.TimeElementsWithFractionOfSecond() + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.8724'), + precision=definitions.PRECISION_100_MICROSECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.8724')) + time_elements_object = time_elements.TimeElementsWithFractionOfSecond() normalized_timestamp = time_elements_object._GetNormalizedTimestamp() self.assertIsNone(normalized_timestamp) @@ -1694,6 +1710,12 @@ def testCopyFromDateTimeValues(self): self.assertEqual( time_elements_object.fraction_of_second, decimal.Decimal('0.123')) + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_100_MICROSECONDS) + time_elements_object._CopyFromDateTimeValues(date_time_values) + self.assertEqual( + time_elements_object.fraction_of_second, decimal.Decimal('0.1234')) + def testCopyFromDatetime(self): """Tests the CopyFromDatetime function.""" datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) @@ -1739,6 +1761,13 @@ def testCopyFromStringTuple(self): self.assertEqual( time_elements_object.fraction_of_second, expected_fraction_of_second) + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + precision=definitions.PRECISION_100_MICROSECONDS) + time_elements_object.CopyFromStringTuple( + time_elements_tuple=('2010', '8', '12', '20', '6', '31', '0.4671')) + self.assertEqual( + time_elements_object.fraction_of_second, decimal.Decimal('0.4671')) + with self.assertRaises(ValueError): time_elements_object.CopyFromStringTuple( time_elements_tuple=('2010', '8', '12', '20', '6', '31')) @@ -1765,6 +1794,14 @@ def testCopyToDateTimeString(self): date_time_string = time_elements_object.CopyToDateTimeString() self.assertEqual(date_time_string, '2010-08-12 20:06:31.874') + time_elements_object = time_elements.TimeElementsWithFractionOfSecond( + fraction_of_second=decimal.Decimal('0.8741'), + precision=definitions.PRECISION_100_MICROSECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, '2010-08-12 20:06:31.8741') + def testNewFromDeltaAndDate(self): """Tests the NewFromDeltaAndDate function.""" time_elements_object = time_elements.TimeElementsWithFractionOfSecond( From f5723a6e1f64c00c475df713bef487eb7e560054 Mon Sep 17 00:00:00 2001 From: rick Date: Sun, 14 Apr 2024 07:02:58 -0400 Subject: [PATCH 3/5] style corrections --- dfdatetime/time_elements.py | 2 +- tests/time_elements.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dfdatetime/time_elements.py b/dfdatetime/time_elements.py index 8d7bd63..b82fa95 100644 --- a/dfdatetime/time_elements.py +++ b/dfdatetime/time_elements.py @@ -923,7 +923,7 @@ def __init__( value is out of bounds. """ if fraction_of_second is not None: - if fraction_of_second < 0.00 or fraction_of_second >= 1.00: + if fraction_of_second < 0.0 or fraction_of_second >= 1.0: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') diff --git a/tests/time_elements.py b/tests/time_elements.py index dcde75a..6efb3f3 100644 --- a/tests/time_elements.py +++ b/tests/time_elements.py @@ -1627,9 +1627,9 @@ def testInitialize(self): expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) time_elements_object = time_elements.TimeElementsWithFractionOfSecond( - fraction_of_second=decimal.Decimal(0.8742), - precision=definitions.PRECISION_100_MICROSECONDS, - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + fraction_of_second=decimal.Decimal(0.8742), + precision=definitions.PRECISION_100_MICROSECONDS, + time_elements_tuple=(2010, 8, 12, 20, 6, 31)) self.assertIsNotNone(time_elements_object) self.assertEqual( time_elements_object._time_elements_tuple, expected_time_elements_tuple) From e4bd5e023b99c3745045a4b3dfb0495928d74050 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 4 May 2024 06:22:31 +0200 Subject: [PATCH 4/5] Changes after review --- dfdatetime/precisions.py | 20 ++++++++++---------- dfdatetime/time_elements.py | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dfdatetime/precisions.py b/dfdatetime/precisions.py index 979b3b6..8b9c320 100644 --- a/dfdatetime/precisions.py +++ b/dfdatetime/precisions.py @@ -25,8 +25,8 @@ def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): nanoseconds (int): number of nanoseconds. Returns: - decimal.Decimal: fraction of second, which must be a value between 0.0 - and 1.0. + decimal.Decimal: fraction of second, which must be a value between 0.0 and + 1.0. """ raise NotImplementedError() @@ -110,8 +110,8 @@ def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): nanoseconds (int): number of nanoseconds. Returns: - decimal.Decimal: fraction of second, which must be a value between 0.00 - and 1.00. + decimal.Decimal: fraction of second, which must be a value between 0.0 and + 1.0. Raises: ValueError: if the number of nanoseconds is out of bounds. @@ -133,7 +133,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): time elements, contains year, month, day of month, hours, minutes and seconds. fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.00 and 1.00. + value between 0.0 and 1.0. Returns: str: date and time value formatted as: @@ -142,7 +142,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): Raises: ValueError: if the fraction of second is out of bounds. """ - if fraction_of_second < 0.00 or fraction_of_second >= 1.00: + if fraction_of_second < 0.0 or fraction_of_second >= 1.0: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') @@ -218,8 +218,8 @@ def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): nanoseconds (int): number of nanoseconds. Returns: - decimal.Decimal: fraction of second, which must be a value between 0.0000 - and 1.0000. + decimal.Decimal: fraction of second, which must be a value between 0.0 + and 1.0. Raises: ValueError: if the number of nanoseconds is out of bounds. @@ -243,7 +243,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): time elements, contains year, month, day of month, hours, minutes and seconds. fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.0000 and 1.0000. + value between 0.0 and 1.0. Returns: str: date and time value formatted as: @@ -252,7 +252,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): Raises: ValueError: if the fraction of second is out of bounds. """ - if fraction_of_second < 0.0000 or fraction_of_second >= 1.0000: + if fraction_of_second < 0.0 or fraction_of_second >= 1.0: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') diff --git a/dfdatetime/time_elements.py b/dfdatetime/time_elements.py index b82fa95..a463e96 100644 --- a/dfdatetime/time_elements.py +++ b/dfdatetime/time_elements.py @@ -907,7 +907,7 @@ def __init__( Args: fraction_of_second (Optional[decimal.Decimal]): fraction of second, which - must be a value between 0.00 and 1.00. + must be a value between 0.0 and 1.0. is_delta (Optional[bool]): True if the date and time value is relative to another date and time value. precision (Optional[str]): precision of the date and time value, which @@ -1035,7 +1035,7 @@ def CopyFromStringTuple(self, time_elements_tuple): raise ValueError( f'Invalid fraction of second value: {fraction_of_second_string!s}') - if fraction_of_second < 0.00 or fraction_of_second >= 1.00: + if fraction_of_second < 0.0 or fraction_of_second >= 1.0: raise ValueError( f'Fraction of second value: {fraction_of_second:f} out of bounds.') From 06c1d3646505c10dbe100636c573c6a94a61478e Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 4 May 2024 06:25:41 +0200 Subject: [PATCH 5/5] Corrected docstrings --- dfdatetime/precisions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dfdatetime/precisions.py b/dfdatetime/precisions.py index 8b9c320..6491180 100644 --- a/dfdatetime/precisions.py +++ b/dfdatetime/precisions.py @@ -137,7 +137,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): Returns: str: date and time value formatted as: - YYYY-MM-DD hh:mm:ss.### + YYYY-MM-DD hh:mm:ss.## Raises: ValueError: if the fraction of second is out of bounds. @@ -247,7 +247,7 @@ def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): Returns: str: date and time value formatted as: - YYYY-MM-DD hh:mm:ss.### + YYYY-MM-DD hh:mm:ss.#### Raises: ValueError: if the fraction of second is out of bounds.