From bd7c34ae4c803d6252d8bd45ca21d3ec7958df20 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 30 Mar 2024 06:09:21 +0100 Subject: [PATCH] Added NewFromDeltaAndDate method (#280) --- .github/workflows/test_docker.yml | 4 +- config/dpkg/changelog | 4 +- dfdatetime/__init__.py | 2 +- dfdatetime/time_elements.py | 113 +++++++++++++++++++++++++----- setup.cfg | 2 +- tests/interface.py | 14 +++- tests/time_elements.py | 74 +++++++++++++++++++ 7 files changed, 185 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test_docker.yml b/.github/workflows/test_docker.yml index fe6b4f3..d0d43d4 100644 --- a/.github/workflows/test_docker.yml +++ b/.github/workflows/test_docker.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - version: ['39'] + version: ['39', '40'] container: image: registry.fedoraproject.org/fedora:${{ matrix.version }} steps: @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - version: ['22.04'] + version: ['24.04'] container: image: ubuntu:${{ matrix.version }} steps: diff --git a/config/dpkg/changelog b/config/dpkg/changelog index a69f5c5..8656b9c 100644 --- a/config/dpkg/changelog +++ b/config/dpkg/changelog @@ -1,5 +1,5 @@ -dfdatetime (20240316-1) unstable; urgency=low +dfdatetime (20240330-1) unstable; urgency=low * Auto-generated - -- Log2Timeline maintainers Sat, 16 Mar 2024 21:04:25 +0100 + -- Log2Timeline maintainers Sat, 30 Mar 2024 05:58:15 +0100 diff --git a/dfdatetime/__init__.py b/dfdatetime/__init__.py index 229366c..34d9b3f 100644 --- a/dfdatetime/__init__.py +++ b/dfdatetime/__init__.py @@ -25,4 +25,4 @@ from dfdatetime import webkit_time -__version__ = '20240316' +__version__ = '20240330' diff --git a/dfdatetime/time_elements.py b/dfdatetime/time_elements.py index e12175b..a463e96 100644 --- a/dfdatetime/time_elements.py +++ b/dfdatetime/time_elements.py @@ -840,11 +840,14 @@ def CopyToDateTimeString(self): f'{year:04d}-{month:02d}-{day_of_month:02d} ' f'{hours:02d}:{minutes:02d}:{seconds:02d}') - def NewFromDeltaAndYear(self, year): - """Creates a new time elements instance from a date time delta and a year. + def NewFromDeltaAndDate(self, year, month, day_of_month): + """Creates a new time elements instance from a date time delta and a date. Args: year (int): year. + month (int): month, where 1 represents January and 0 if not set. + day_of_month (int): day of month, where 1 represents the first day and 0 + if not set. Returns: TimeElements: time elements or None if time elements are missing. @@ -855,14 +858,15 @@ def NewFromDeltaAndYear(self, year): if not self._is_delta: raise ValueError('Not a date time delta.') - if self._number_of_seconds is None: + if self._time_elements_tuple is None: return None - delta_year, month, day_of_month, hours, minutes, seconds = ( + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( self._time_elements_tuple) time_elements_tuple = ( - year + delta_year, month, day_of_month, hours, minutes, seconds) + year + delta_year, month + delta_month, + day_of_month + delta_day_of_month, hours, minutes, seconds) date_time = TimeElements( precision=self._precision, time_elements_tuple=time_elements_tuple, @@ -872,6 +876,20 @@ def NewFromDeltaAndYear(self, year): return date_time + def NewFromDeltaAndYear(self, year): + """Creates a new time elements instance from a date time delta and a year. + + Args: + year (int): year. + + Returns: + TimeElements: time elements or None if time elements are missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + return self.NewFromDeltaAndDate(year, 0, 0) + class TimeElementsWithFractionOfSecond(TimeElements): """Time elements with a fraction of second interface. @@ -1042,11 +1060,14 @@ def CopyToDateTimeString(self): return precision_helper.CopyToDateTimeString( self._time_elements_tuple, self.fraction_of_second) - def NewFromDeltaAndYear(self, year): - """Creates a new time elements instance from a date time delta and a year. + def NewFromDeltaAndDate(self, year, month, day_of_month): + """Creates a new time elements instance from a date time delta and a date. Args: year (int): year. + month (int): month, where 1 represents January and 0 if not set. + day_of_month (int): day of month, where 1 represents the first day and 0 + if not set. Returns: TimeElementsWithFractionOfSecond: time elements or None if time elements @@ -1058,20 +1079,36 @@ def NewFromDeltaAndYear(self, year): if not self._is_delta: raise ValueError('Not a date time delta.') - if self._number_of_seconds is None: + if self._time_elements_tuple is None: return None - delta_year, month, day_of_month, hours, minutes, seconds = ( + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( self._time_elements_tuple) time_elements_tuple = ( - year + delta_year, month, day_of_month, hours, minutes, seconds) + year + delta_year, month + delta_month, + day_of_month + delta_day_of_month, hours, minutes, seconds) return TimeElementsWithFractionOfSecond( fraction_of_second=self.fraction_of_second, precision=self._precision, time_elements_tuple=time_elements_tuple, time_zone_offset=self._time_zone_offset) + def NewFromDeltaAndYear(self, year): + """Creates a new time elements instance from a date time delta and a year. + + Args: + year (int): year. + + Returns: + TimeElementsWithFractionOfSecond: time elements or None if time elements + are missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + return self.NewFromDeltaAndDate(year, 0, 0) + class TimeElementsInMilliseconds(TimeElementsWithFractionOfSecond): """Time elements in milliseconds. @@ -1170,11 +1207,14 @@ def CopyFromStringTuple(self, time_elements_tuple): super(TimeElementsInMilliseconds, self).CopyFromStringTuple( time_elements_tuple) - def NewFromDeltaAndYear(self, year): - """Creates a new time elements instance from a date time delta and a year. + def NewFromDeltaAndDate(self, year, month, day_of_month): + """Creates a new time elements instance from a date time delta and a date. Args: year (int): year. + month (int): month, where 1 represents January and 0 if not set. + day_of_month (int): day of month, where 1 represents the first day and 0 + if not set. Returns: TimeElementsInMilliseconds: time elements or None if time elements are @@ -1186,20 +1226,36 @@ def NewFromDeltaAndYear(self, year): if not self._is_delta: raise ValueError('Not a date time delta.') - if self._number_of_seconds is None: + if self._time_elements_tuple is None: return None - delta_year, month, day_of_month, hours, minutes, seconds = ( + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( self._time_elements_tuple) time_elements_tuple = ( - year + delta_year, month, day_of_month, hours, minutes, seconds, + year + delta_year, month + delta_month, + day_of_month + delta_day_of_month, hours, minutes, seconds, self.milliseconds) return TimeElementsInMilliseconds( precision=self._precision, time_elements_tuple=time_elements_tuple, time_zone_offset=self._time_zone_offset) + def NewFromDeltaAndYear(self, year): + """Creates a new time elements instance from a date time delta and a year. + + Args: + year (int): year. + + Returns: + TimeElementsInMilliseconds: time elements or None if time elements are + missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + return self.NewFromDeltaAndDate(year, 0, 0) + class TimeElementsInMicroseconds(TimeElementsWithFractionOfSecond): """Time elements in microseconds. @@ -1298,11 +1354,14 @@ def CopyFromStringTuple(self, time_elements_tuple): super(TimeElementsInMicroseconds, self).CopyFromStringTuple( time_elements_tuple) - def NewFromDeltaAndYear(self, year): + def NewFromDeltaAndDate(self, year, month, day_of_month): """Creates a new time elements instance from a date time delta and a year. Args: year (int): year. + month (int): month, where 1 represents January and 0 if not set. + day_of_month (int): day of month, where 1 represents the first day and 0 + if not set. Returns: TimeElementsInMicroseconds: time elements or None if time elements are @@ -1314,20 +1373,36 @@ def NewFromDeltaAndYear(self, year): if not self._is_delta: raise ValueError('Not a date time delta.') - if self._number_of_seconds is None: + if self._time_elements_tuple is None: return None - delta_year, month, day_of_month, hours, minutes, seconds = ( + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( self._time_elements_tuple) time_elements_tuple = ( - year + delta_year, month, day_of_month, hours, minutes, seconds, + year + delta_year, month + delta_month, + day_of_month + delta_day_of_month, hours, minutes, seconds, self.microseconds) return TimeElementsInMicroseconds( precision=self._precision, time_elements_tuple=time_elements_tuple, time_zone_offset=self._time_zone_offset) + def NewFromDeltaAndYear(self, year): + """Creates a new time elements instance from a date time delta and a year. + + Args: + year (int): year. + + Returns: + TimeElementsInMicroseconds: time elements or None if time elements are + missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + return self.NewFromDeltaAndDate(year, 0, 0) + factory.Factory.RegisterDateTimeValues(TimeElements) factory.Factory.RegisterDateTimeValues(TimeElementsInMilliseconds) diff --git a/setup.cfg b/setup.cfg index 73f3bfc..4f48f39 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = dfdatetime -version = 20240316 +version = 20240330 description = Digital Forensics date and time (dfDateTime). long_description = dfDateTime, or Digital Forensics date and time, provides date and time objects to preserve accuracy and precision. long_description_content_type = text/plain diff --git a/tests/interface.py b/tests/interface.py index 1af29c4..5ed4008 100644 --- a/tests/interface.py +++ b/tests/interface.py @@ -559,21 +559,29 @@ def testGetNumberOfSecondsFromElements(self): 0, 1, 2, 0, 0, 0) self.assertEqual(number_of_seconds, -62167132800) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 2010, 8, 0, 24, 6, 31) + self.assertIsNone(number_of_seconds) + with self.assertRaises(ValueError): date_time_values._GetNumberOfSecondsFromElements( 2010, 13, 12, 21, 6, 31) with self.assertRaises(ValueError): date_time_values._GetNumberOfSecondsFromElements( - 2010, 13, 12, 24, 6, 31) + 2010, 8, 32, 24, 6, 31) + + with self.assertRaises(ValueError): + date_time_values._GetNumberOfSecondsFromElements( + 2010, 8, 12, 24, 6, 31) with self.assertRaises(ValueError): date_time_values._GetNumberOfSecondsFromElements( - 2010, 13, 12, 21, 99, 31) + 2010, 8, 12, 21, 99, 31) with self.assertRaises(ValueError): date_time_values._GetNumberOfSecondsFromElements( - 2010, 13, 12, 21, 6, 65) + 2010, 8, 12, 21, 6, 65) with self.assertRaises(ValueError): date_time_values._GetNumberOfSecondsFromElements( diff --git a/tests/time_elements.py b/tests/time_elements.py index 2e48a02..980d820 100644 --- a/tests/time_elements.py +++ b/tests/time_elements.py @@ -770,6 +770,30 @@ def testGetTimeOfDay(self): time_of_day_tuple = time_elements_object.GetTimeOfDay() self.assertEqual(time_of_day_tuple, (None, None, None)) + def testNewFromDeltaAndDate(self): + """Tests the NewFromDeltaAndDate function.""" + time_elements_object = time_elements.TimeElements( + is_delta=True, time_elements_tuple=(1, 0, 0, 20, 6, 31)) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNotNone(new_time_elements_object) + 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) + + time_elements_object = time_elements.TimeElements(is_delta=True) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNone(new_time_elements_object) + + time_elements_object = time_elements.TimeElements(is_delta=False) + + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + def testNewFromDeltaAndYear(self): """Tests the NewFromDeltaAndYear function.""" time_elements_object = time_elements.TimeElements( @@ -1138,6 +1162,31 @@ def testGetTimeOfDay(self): time_of_day_tuple = time_elements_object.GetTimeOfDay() self.assertEqual(time_of_day_tuple, (None, None, None)) + def testNewFromDeltaAndDate(self): + """Tests the NewFromDeltaAndDate function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + is_delta=True, time_elements_tuple=(1, 0, 0, 20, 6, 31, 429)) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNotNone(new_time_elements_object) + 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.milliseconds, 429) + + time_elements_object = time_elements.TimeElements(is_delta=True) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNone(new_time_elements_object) + + time_elements_object = time_elements.TimeElements(is_delta=False) + + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + def testNewFromDeltaAndYear(self): """Tests the NewFromDeltaAndYear function.""" time_elements_object = time_elements.TimeElementsInMilliseconds( @@ -1508,6 +1557,31 @@ def testGetTimeOfDay(self): time_of_day_tuple = time_elements_object.GetTimeOfDay() self.assertEqual(time_of_day_tuple, (None, None, None)) + def testNewFromDeltaAndDate(self): + """Tests the NewFromDeltaAndDate function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + is_delta=True, time_elements_tuple=(1, 0, 0, 20, 6, 31, 429876)) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNotNone(new_time_elements_object) + 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.microseconds, 429876) + + time_elements_object = time_elements.TimeElements(is_delta=True) + + new_time_elements_object = time_elements_object.NewFromDeltaAndDate( + 2009, 1, 12) + self.assertIsNone(new_time_elements_object) + + time_elements_object = time_elements.TimeElements(is_delta=False) + + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + def testNewFromDeltaAndYear(self): """Tests the NewFromDeltaAndYear function.""" time_elements_object = time_elements.TimeElementsInMicroseconds(