diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d80d2d4 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,51 @@ +# Check source. +name: lint +on: + pull_request: + branches: + - main + push: + branches: + - main +permissions: read-all +jobs: + black: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Check format of Python code + uses: psf/black@stable + with: + options: "--check" + src: "." + pylint: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.14'] + container: + image: ubuntu:26.04 + steps: + - uses: actions/checkout@v6 + - name: Set up container + env: + DEBIAN_FRONTEND: noninteractive + run: | + apt-get update -q + apt-get install -y libterm-readline-gnu-perl locales software-properties-common + locale-gen en_US.UTF-8 + ln -f -s /usr/share/zoneinfo/UTC /etc/localtime + - name: Install dependencies + env: + DEBIAN_FRONTEND: noninteractive + run: | + add-apt-repository -y universe + add-apt-repository -y ppa:deadsnakes/ppa + add-apt-repository -y ppa:gift/dev + apt-get update -q + apt-get install -y build-essential git pkg-config python${{ matrix.python-version }} python${{ matrix.python-version }}-dev python${{ matrix.python-version }}-venv python3-pip python3-setuptools tox + - name: Run linter + env: + LANG: en_US.UTF-8 + run: | + tox -e pylint diff --git a/.github/workflows/test_tox.yml b/.github/workflows/test_tox.yml index 0f0c5fc..de80a7a 100644 --- a/.github/workflows/test_tox.yml +++ b/.github/workflows/test_tox.yml @@ -85,34 +85,3 @@ jobs: uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} - lint: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ['3.14'] - container: - image: ubuntu:26.04 - steps: - - uses: actions/checkout@v6 - - name: Set up container - env: - DEBIAN_FRONTEND: noninteractive - run: | - apt-get update -q - apt-get install -y libterm-readline-gnu-perl locales software-properties-common - locale-gen en_US.UTF-8 - ln -f -s /usr/share/zoneinfo/UTC /etc/localtime - - name: Install dependencies - env: - DEBIAN_FRONTEND: noninteractive - run: | - add-apt-repository -y universe - add-apt-repository -y ppa:deadsnakes/ppa - add-apt-repository -y ppa:gift/dev - apt-get update -q - apt-get install -y build-essential git pkg-config python${{ matrix.python-version }} python${{ matrix.python-version }}-dev python${{ matrix.python-version }}-venv python3-pip python3-setuptools tox - - name: Run linter - env: - LANG: en_US.UTF-8 - run: | - tox -e lint diff --git a/.pylintrc b/.pylintrc index ca6099d..34bcab3 100644 --- a/.pylintrc +++ b/.pylintrc @@ -358,12 +358,11 @@ indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). -# indent-string=' ' -indent-string=' ' +indent-string=' ' # Maximum number of characters on a single line. # max-line-length=100 -max-line-length=80 +max-line-length=88 # Maximum number of lines in a module. max-module-lines=1000 @@ -599,7 +598,7 @@ spelling-store-unknown-words=no # This flag controls whether inconsistent-quotes generates a warning when the # character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=no +check-quote-consistency=yes # This flag controls whether the implicit-str-concat should generate a warning # on implicit string concatenation in sequences defined over several lines. diff --git a/dfdatetime/__init__.py b/dfdatetime/__init__.py index af2fd9a..b669649 100644 --- a/dfdatetime/__init__.py +++ b/dfdatetime/__init__.py @@ -23,5 +23,4 @@ from dfdatetime import uuid_time from dfdatetime import webkit_time - -__version__ = '20260513' +__version__ = "20260513" diff --git a/dfdatetime/apfs_time.py b/dfdatetime/apfs_time.py index d1a8da7..ea1f5fa 100644 --- a/dfdatetime/apfs_time.py +++ b/dfdatetime/apfs_time.py @@ -8,69 +8,79 @@ class APFSTime(posix_time.PosixTimeInNanoseconds): - """Apple File System (APFS) timestamp. + """Apple File System (APFS) timestamp. - The APFS timestamp is a signed 64-bit integer that contains the number of - nanoseconds since 1970-01-01 00:00:00. + The APFS timestamp is a signed 64-bit integer that contains the number of + nanoseconds since 1970-01-01 00:00:00. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= self._INT64_MIN and - self._timestamp <= self._INT64_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.NANOSECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a APFS timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the date and time value is not supported. - """ - super()._CopyFromDateTimeString(time_string) - - if (self._timestamp is None or self._timestamp < self._INT64_MIN or - self._timestamp > self._INT64_MAX): - raise ValueError('Date time value not supported.') - - def CopyToDateTimeString(self): - """Copies the APFS timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or - None if the timestamp is missing or invalid. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if (self._timestamp is None or self._timestamp < self._INT64_MIN or - self._timestamp > self._INT64_MAX): - return None - return super()._CopyToDateTimeString() + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= self._INT64_MIN + and self._timestamp <= self._INT64_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.NANOSECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a APFS timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the date and time value is not supported. + """ + super()._CopyFromDateTimeString(time_string) + + if ( + self._timestamp is None + or self._timestamp < self._INT64_MIN + or self._timestamp > self._INT64_MAX + ): + raise ValueError("Date time value not supported.") + + def CopyToDateTimeString(self): + """Copies the APFS timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or + None if the timestamp is missing or invalid. + """ + if ( + self._timestamp is None + or self._timestamp < self._INT64_MIN + or self._timestamp > self._INT64_MAX + ): + return None + + return super()._CopyToDateTimeString() factory.Factory.RegisterDateTimeValues(APFSTime) diff --git a/dfdatetime/cocoa_time.py b/dfdatetime/cocoa_time.py index 30c6ea3..fa1b2b3 100644 --- a/dfdatetime/cocoa_time.py +++ b/dfdatetime/cocoa_time.py @@ -8,125 +8,131 @@ class CocoaTimeEpoch(interface.DateTimeEpoch): - """Cocoa time epoch.""" + """Cocoa time epoch.""" - def __init__(self): - """Initializes a Cocoa time epoch.""" - super().__init__(2001, 1, 1) + def __init__(self): + """Initializes a Cocoa time epoch.""" + super().__init__(2001, 1, 1) class CocoaTime(interface.DateTimeValues): - """Cocoa timestamp. + """Cocoa timestamp. - The Cocoa timestamp is a floating point value that contains the number of - seconds since 2001-01-01 00:00:00 (also known as the Cocoa epoch). - Negative values represent date and times predating the Cocoa epoch. + The Cocoa timestamp is a floating point value that contains the number of + seconds since 2001-01-01 00:00:00 (also known as the Cocoa epoch). + Negative values represent date and times predating the Cocoa epoch. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - # The difference between January 1, 2001 and January 1, 1970 in seconds. - _COCOA_TO_POSIX_BASE = -978307200 - - _EPOCH = CocoaTimeEpoch() - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a Cocoa timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[float]): Cocoa timestamp. - """ - super().__init__( - precision=precision or definitions.PRECISION_1_SECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """float: Cocoa timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - float: normalized timestamp, which contains the number of seconds since - January 1, 1970 00:00:00 and a fraction of second used for increased - precision, or None if the normalized timestamp cannot be determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) - self._COCOA_TO_POSIX_BASE) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a Cocoa timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp += self._COCOA_TO_POSIX_BASE - - timestamp = float(timestamp) - timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_SECOND - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the Cocoa timestamp to a date and time string. - - Returns: - str: date and time value formatted as: YYYY-MM-DD hh:mm:ss.###### or - None if the timestamp cannot be copied to a date and time string. - """ - if self._timestamp is None: - return None - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - int(self._timestamp)) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - microseconds = int( - (self._timestamp % 1) * definitions.MICROSECONDS_PER_SECOND) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + # The difference between January 1, 2001 and January 1, 1970 in seconds. + _COCOA_TO_POSIX_BASE = -978307200 + + _EPOCH = CocoaTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a Cocoa timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[float]): Cocoa timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_SECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """float: Cocoa timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + float: normalized timestamp, which contains the number of seconds since + January 1, 1970 00:00:00 and a fraction of second used for increased + precision, or None if the normalized timestamp cannot be determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) - self._COCOA_TO_POSIX_BASE + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a Cocoa timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp += self._COCOA_TO_POSIX_BASE + + timestamp = float(timestamp) + timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_SECOND + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the Cocoa timestamp to a date and time string. + + Returns: + str: date and time value formatted as: YYYY-MM-DD hh:mm:ss.###### or + None if the timestamp cannot be copied to a date and time string. + """ + if self._timestamp is None: + return None + + number_of_days, hours, minutes, seconds = self._GetTimeValues( + int(self._timestamp) + ) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + microseconds = int((self._timestamp % 1) * definitions.MICROSECONDS_PER_SECOND) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) factory.Factory.RegisterDateTimeValues(CocoaTime) diff --git a/dfdatetime/decorators.py b/dfdatetime/decorators.py index 1061e64..39982d6 100644 --- a/dfdatetime/decorators.py +++ b/dfdatetime/decorators.py @@ -4,18 +4,20 @@ def deprecated(function): # pylint: disable=invalid-name - """Decorator to mark functions or methods as deprecated.""" + """Decorator to mark functions or methods as deprecated.""" - def IssueDeprecationWarning(*args, **kwargs): - """Issue a deprecation warning.""" - warnings.simplefilter('default', DeprecationWarning) - warnings.warn( - f'Call to deprecated function: {function.__name__:s}.', - category=DeprecationWarning, stacklevel=2) + def IssueDeprecationWarning(*args, **kwargs): + """Issue a deprecation warning.""" + warnings.simplefilter("default", DeprecationWarning) + warnings.warn( + f"Call to deprecated function: {function.__name__:s}.", + category=DeprecationWarning, + stacklevel=2, + ) - return function(*args, **kwargs) + return function(*args, **kwargs) - IssueDeprecationWarning.__name__ = function.__name__ - IssueDeprecationWarning.__doc__ = function.__doc__ - IssueDeprecationWarning.__dict__.update(function.__dict__) - return IssueDeprecationWarning + IssueDeprecationWarning.__name__ = function.__name__ + IssueDeprecationWarning.__doc__ = function.__doc__ + IssueDeprecationWarning.__dict__.update(function.__dict__) + return IssueDeprecationWarning diff --git a/dfdatetime/definitions.py b/dfdatetime/definitions.py index d122e2f..70a755b 100644 --- a/dfdatetime/definitions.py +++ b/dfdatetime/definitions.py @@ -31,64 +31,67 @@ NANOSECONDS_PER_DECIMILISECOND = 100000 NANOSECONDS_PER_MICROSECOND = 1000 -PRECISION_1_DAY = '1d' -PRECISION_1_HOUR = '1h' -PRECISION_1_NANOSECOND = '1ns' -PRECISION_10_NANOSECONDS = '10s' -PRECISION_100_NANOSECONDS = '100ns' -PRECISION_1_MICROSECOND = '1us' -PRECISION_10_MICROSECONDS = '10us' -PRECISION_100_MICROSECONDS = '100us' -PRECISION_1_MILLISECOND = '1ms' -PRECISION_10_MILLISECONDS = '10ms' -PRECISION_100_MILLISECONDS = '100ms' -PRECISION_1_MINUTE = '1min' -PRECISION_1_SECOND = '1s' -PRECISION_2_SECONDS = '2s' - -PRECISION_VALUES = frozenset([ - PRECISION_1_DAY, - PRECISION_1_HOUR, - PRECISION_1_NANOSECOND, - PRECISION_10_NANOSECONDS, - PRECISION_100_NANOSECONDS, - PRECISION_1_MICROSECOND, - PRECISION_10_MICROSECONDS, - PRECISION_100_MICROSECONDS, - PRECISION_1_MILLISECOND, - PRECISION_10_MILLISECONDS, - PRECISION_100_MILLISECONDS, - PRECISION_1_MINUTE, - PRECISION_1_SECOND, - PRECISION_2_SECONDS]) +PRECISION_1_DAY = "1d" +PRECISION_1_HOUR = "1h" +PRECISION_1_NANOSECOND = "1ns" +PRECISION_10_NANOSECONDS = "10s" +PRECISION_100_NANOSECONDS = "100ns" +PRECISION_1_MICROSECOND = "1us" +PRECISION_10_MICROSECONDS = "10us" +PRECISION_100_MICROSECONDS = "100us" +PRECISION_1_MILLISECOND = "1ms" +PRECISION_10_MILLISECONDS = "10ms" +PRECISION_100_MILLISECONDS = "100ms" +PRECISION_1_MINUTE = "1min" +PRECISION_1_SECOND = "1s" +PRECISION_2_SECONDS = "2s" + +PRECISION_VALUES = frozenset( + [ + PRECISION_1_DAY, + PRECISION_1_HOUR, + PRECISION_1_NANOSECOND, + PRECISION_10_NANOSECONDS, + PRECISION_100_NANOSECONDS, + PRECISION_1_MICROSECOND, + PRECISION_10_MICROSECONDS, + PRECISION_100_MICROSECONDS, + PRECISION_1_MILLISECOND, + PRECISION_10_MILLISECONDS, + PRECISION_100_MILLISECONDS, + PRECISION_1_MINUTE, + PRECISION_1_SECOND, + PRECISION_2_SECONDS, + ] +) # Create a days per century lookup table. DAYS_PER_CENTURY = {} for year in range(-10000, 10000, 100): - if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0: - number_of_days = 36525 - else: - number_of_days = 36524 - DAYS_PER_CENTURY[year] = number_of_days + if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0: + number_of_days = 36525 + else: + number_of_days = 36524 + DAYS_PER_CENTURY[year] = number_of_days # Create a days per year lookup table. DAYS_PER_YEAR = {} for year in range(-10000, 10000, 1): - if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0: - number_of_days = 366 - else: - number_of_days = 365 - DAYS_PER_YEAR[year] = number_of_days + if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0: + number_of_days = 366 + else: + number_of_days = 365 + DAYS_PER_YEAR[year] = number_of_days # Create a days per year in POSIX epoch lookup table. DAYS_PER_YEAR_IN_POSIX_EPOCH = {} number_of_days = 0 for year in range(1969, -10000, -1): - number_of_days -= DAYS_PER_YEAR[year] - DAYS_PER_YEAR_IN_POSIX_EPOCH[year] = number_of_days + number_of_days -= DAYS_PER_YEAR[year] + DAYS_PER_YEAR_IN_POSIX_EPOCH[year] = number_of_days number_of_days = 0 for year in range(1970, 10000, 1): - DAYS_PER_YEAR_IN_POSIX_EPOCH[year] = number_of_days - number_of_days += DAYS_PER_YEAR[year] + DAYS_PER_YEAR_IN_POSIX_EPOCH[year] = number_of_days + number_of_days += DAYS_PER_YEAR[year] diff --git a/dfdatetime/delphi_date_time.py b/dfdatetime/delphi_date_time.py index 60218b8..8771416 100644 --- a/dfdatetime/delphi_date_time.py +++ b/dfdatetime/delphi_date_time.py @@ -8,142 +8,150 @@ class DelphiDateTimeEpoch(interface.DateTimeEpoch): - """Delphi TDateTime epoch.""" + """Delphi TDateTime epoch.""" - def __init__(self): - """Initializes a Delphi TDateTime epoch.""" - super().__init__(1899, 12, 30) + def __init__(self): + """Initializes a Delphi TDateTime epoch.""" + super().__init__(1899, 12, 30) class DelphiDateTime(interface.DateTimeValues): - """Delphi TDateTime timestamp. + """Delphi TDateTime timestamp. - The Delphi TDateTime timestamp is a floating point value that contains - the number of days since 1899-12-30 00:00:00 (also known as the epoch). - Negative values represent date and times predating the epoch. + The Delphi TDateTime timestamp is a floating point value that contains + the number of days since 1899-12-30 00:00:00 (also known as the epoch). + Negative values represent date and times predating the epoch. - The maximal correct date supported by TDateTime values is limited to: - 9999-12-31 23:59:59.999 + The maximal correct date supported by TDateTime values is limited to: + 9999-12-31 23:59:59.999 - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - # The difference between December 30, 1899 and January 1, 1970 in days. - _DELPHI_TO_POSIX_BASE = 25569 - - _EPOCH = DelphiDateTimeEpoch() - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a Delphi TDateTime timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[float]): Delphi TDateTime timestamp. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - super().__init__( - precision=precision or definitions.PRECISION_1_MILLISECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """float: Delphi TDateTime timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) - self._DELPHI_TO_POSIX_BASE) - self._normalized_timestamp *= definitions.SECONDS_PER_DAY - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a Delphi TDateTime timestamp from a string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year > 9999: - raise ValueError(f'Unsupported year value: {year:d}.') - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - - timestamp = float(timestamp) / definitions.SECONDS_PER_DAY - timestamp += self._DELPHI_TO_POSIX_BASE - timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_DAY - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the Delphi TDateTime timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. - """ - if self._timestamp is None: - return None - - number_of_seconds = self._timestamp * definitions.SECONDS_PER_DAY - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - int(number_of_seconds)) - - # The maximum date supported by TDateTime values is limited to: - # 9999-12-31 23:59:59.999 (approximate 2958465 days since epoch). - # The minimum date is unknown hence assuming it is limited to: - # 0001-01-01 00:00:00.000 (approximate -693593 days since epoch). - if number_of_days < -693593 or number_of_days > 2958465: - return None - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - microseconds = int( - (number_of_seconds % 1) * definitions.MICROSECONDS_PER_SECOND) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + # The difference between December 30, 1899 and January 1, 1970 in days. + _DELPHI_TO_POSIX_BASE = 25569 + + _EPOCH = DelphiDateTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a Delphi TDateTime timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[float]): Delphi TDateTime timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MILLISECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """float: Delphi TDateTime timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) - self._DELPHI_TO_POSIX_BASE + ) + self._normalized_timestamp *= definitions.SECONDS_PER_DAY + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a Delphi TDateTime timestamp from a string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year > 9999: + raise ValueError(f"Unsupported year value: {year:d}.") + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + + timestamp = float(timestamp) / definitions.SECONDS_PER_DAY + timestamp += self._DELPHI_TO_POSIX_BASE + timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_DAY + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the Delphi TDateTime timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if self._timestamp is None: + return None + + number_of_seconds = self._timestamp * definitions.SECONDS_PER_DAY + + number_of_days, hours, minutes, seconds = self._GetTimeValues( + int(number_of_seconds) + ) + + # The maximum date supported by TDateTime values is limited to: + # 9999-12-31 23:59:59.999 (approximate 2958465 days since epoch). + # The minimum date is unknown hence assuming it is limited to: + # 0001-01-01 00:00:00.000 (approximate -693593 days since epoch). + if number_of_days < -693593 or number_of_days > 2958465: + return None + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + microseconds = int( + (number_of_seconds % 1) * definitions.MICROSECONDS_PER_SECOND + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) factory.Factory.RegisterDateTimeValues(DelphiDateTime) diff --git a/dfdatetime/dotnet_datetime.py b/dfdatetime/dotnet_datetime.py index 86e705d..4979c49 100644 --- a/dfdatetime/dotnet_datetime.py +++ b/dfdatetime/dotnet_datetime.py @@ -8,129 +8,139 @@ class DotNetDateTimeEpoch(interface.DateTimeEpoch): - """.NET DateTime epoch.""" + """.NET DateTime epoch.""" - def __init__(self): - """Initializes a .NET DateTime epoch.""" - super().__init__(1, 1, 1) + def __init__(self): + """Initializes a .NET DateTime epoch.""" + super().__init__(1, 1, 1) class DotNetDateTime(interface.DateTimeValues): - """.NET DateTime ticks. + """.NET DateTime ticks. - The .NET DateTime timestamp is a 64-bit signed integer that contains the date - and time as the number of 100 nanoseconds since 12:00 AM January 1, year 1 - A.D. in the proleptic Gregorian Calendar. - """ - - _EPOCH = DotNetDateTimeEpoch() - - # The difference between January 1, 1 and January 1, 1970 in seconds. - _DOTNET_TO_POSIX_BASE = ( - ((1969 * 365) + (1969 // 4) - (1969 // 100) + (1969 // 400)) * - definitions.SECONDS_PER_DAY) - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a .NET DateTime timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): .NET DateTime ticks. + The .NET DateTime timestamp is a 64-bit signed integer that contains the date + and time as the number of 100 nanoseconds since 12:00 AM January 1, year 1 + A.D. in the proleptic Gregorian Calendar. """ - super().__init__( - precision=precision or definitions.PRECISION_100_NANOSECONDS, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp or 0 - - @property - def timestamp(self): - """integer: .NET DateTime timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND) - self._normalized_timestamp -= self._DOTNET_TO_POSIX_BASE - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a .NET DateTime timestamp from a string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year > 9999: - raise ValueError(f'Unsupported year value: {year:d}.') - - nanoseconds, _ = divmod(nanoseconds, 100) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp += self._DOTNET_TO_POSIX_BASE - timestamp *= self._100_NANOSECONDS_PER_SECOND - timestamp += nanoseconds - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the .NET DateTime timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. - """ - if (self._timestamp is None or self._timestamp < 0 or - self._timestamp > self._UINT64_MAX): - return None - - timestamp, fraction_of_second = divmod( - self._timestamp, self._100_NANOSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}') + _EPOCH = DotNetDateTimeEpoch() + + # The difference between January 1, 1 and January 1, 1970 in seconds. + _DOTNET_TO_POSIX_BASE = ( + (1969 * 365) + (1969 // 4) - (1969 // 100) + (1969 // 400) + ) * definitions.SECONDS_PER_DAY + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a .NET DateTime timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): .NET DateTime ticks. + """ + super().__init__( + precision=precision or definitions.PRECISION_100_NANOSECONDS, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp or 0 + + @property + def timestamp(self): + """integer: .NET DateTime timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND + ) + self._normalized_timestamp -= self._DOTNET_TO_POSIX_BASE + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a .NET DateTime timestamp from a string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year > 9999: + raise ValueError(f"Unsupported year value: {year:d}.") + + nanoseconds, _ = divmod(nanoseconds, 100) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp += self._DOTNET_TO_POSIX_BASE + timestamp *= self._100_NANOSECONDS_PER_SECOND + timestamp += nanoseconds + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the .NET DateTime timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if ( + self._timestamp is None + or self._timestamp < 0 + or self._timestamp > self._UINT64_MAX + ): + return None + + timestamp, fraction_of_second = divmod( + self._timestamp, self._100_NANOSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}" + ) factory.Factory.RegisterDateTimeValues(DotNetDateTime) diff --git a/dfdatetime/factory.py b/dfdatetime/factory.py index 4936ce7..52e8042 100644 --- a/dfdatetime/factory.py +++ b/dfdatetime/factory.py @@ -2,58 +2,58 @@ class Factory: - """Date and time values factory.""" + """Date and time values factory.""" - _date_time_values_types = {} + _date_time_values_types = {} - @classmethod - def DeregisterDateTimeValues(cls, date_time_values_type): - """Deregisters a date and time values type. + @classmethod + def DeregisterDateTimeValues(cls, date_time_values_type): + """Deregisters a date and time values type. - Args: - date_time_values_type (type): date and time values type. + Args: + date_time_values_type (type): date and time values type. - Raises: - KeyError: if date and time values type is not registered. - """ - class_name = date_time_values_type.__name__ - if class_name not in cls._date_time_values_types: - raise KeyError(f'Date and time values type: {class_name:s} not set.') + Raises: + KeyError: if date and time values type is not registered. + """ + class_name = date_time_values_type.__name__ + if class_name not in cls._date_time_values_types: + raise KeyError(f"Date and time values type: {class_name:s} not set.") - del cls._date_time_values_types[class_name] + del cls._date_time_values_types[class_name] - @classmethod - def NewDateTimeValues(cls, class_name, **kwargs): - """Creates a new date and time values for the specific type indicator. + @classmethod + def NewDateTimeValues(cls, class_name, **kwargs): + """Creates a new date and time values for the specific type indicator. - Args: - class_name (str): type indicator. - kwargs (dict): keyword arguments depending on the date and time values. + Args: + class_name (str): type indicator. + kwargs (dict): keyword arguments depending on the date and time values. - Returns: - DateTimeValues: date and time values. + Returns: + DateTimeValues: date and time values. - Raises: - KeyError: if date and time values is not registered. - """ - if class_name not in cls._date_time_values_types: - raise KeyError(f'Date and time values type: {class_name:s} not set.') + Raises: + KeyError: if date and time values is not registered. + """ + if class_name not in cls._date_time_values_types: + raise KeyError(f"Date and time values type: {class_name:s} not set.") - date_time_values_type = cls._date_time_values_types[class_name] - return date_time_values_type(**kwargs) + date_time_values_type = cls._date_time_values_types[class_name] + return date_time_values_type(**kwargs) - @classmethod - def RegisterDateTimeValues(cls, date_time_values_type): - """Registers a date and time values type. + @classmethod + def RegisterDateTimeValues(cls, date_time_values_type): + """Registers a date and time values type. - Args: - date_time_values_type (type): date and time values type. + Args: + date_time_values_type (type): date and time values type. - Raises: - KeyError: if date and time values is already registered. - """ - class_name = date_time_values_type.__name__ - if class_name in cls._date_time_values_types: - raise KeyError(f'Date and time values type: {class_name:s} already set.') + Raises: + KeyError: if date and time values is already registered. + """ + class_name = date_time_values_type.__name__ + if class_name in cls._date_time_values_types: + raise KeyError(f"Date and time values type: {class_name:s} already set.") - cls._date_time_values_types[class_name] = date_time_values_type + cls._date_time_values_types[class_name] = date_time_values_type diff --git a/dfdatetime/fake_time.py b/dfdatetime/fake_time.py index d0992b6..3965863 100644 --- a/dfdatetime/fake_time.py +++ b/dfdatetime/fake_time.py @@ -9,114 +9,120 @@ class FakeTime(interface.DateTimeValues): - """Fake timestamp. + """Fake timestamp. - The fake timestamp is intended for testing purposes. On initialization - it contains the current time in UTC in microsecond precision. + The fake timestamp is intended for testing purposes. On initialization + it contains the current time in UTC in microsecond precision. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = posix_time.PosixTimeEpoch() - - def __init__(self, precision=None, time_zone_offset=None): - """Initializes a fake timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - """ - # Note that time.time() and divmod return floating point values. - timestamp, fraction_of_second = divmod(time.time(), 1) - - super().__init__( - precision=precision or definitions.PRECISION_1_MICROSECOND, - time_zone_offset=time_zone_offset) - self._microseconds = int( - fraction_of_second * definitions.MICROSECONDS_PER_SECOND) - self._number_of_seconds = int(timestamp) - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if self._normalized_timestamp is None: - if self._number_of_seconds is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._microseconds) / - definitions.MICROSECONDS_PER_SECOND) - self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a fake timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds') - time_zone_offset = date_time_values.get('time_zone_offset') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - - if nanoseconds is None: - self._microseconds = None - else: - self._microseconds, _ = divmod(nanoseconds, 1000) - - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the fake timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or - "YYYY-MM-DD hh:mm:ss.######" or None if the number of seconds - is missing. - """ - if self._number_of_seconds is None: - return None - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - self._number_of_seconds) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - date_time_string = ( - f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') - - if self._microseconds is not None: - date_time_string = '.'.join([ - date_time_string, f'{self._microseconds:06d}']) - return date_time_string + _EPOCH = posix_time.PosixTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None): + """Initializes a fake timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + """ + # Note that time.time() and divmod return floating point values. + timestamp, fraction_of_second = divmod(time.time(), 1) + + super().__init__( + precision=precision or definitions.PRECISION_1_MICROSECOND, + time_zone_offset=time_zone_offset, + ) + self._microseconds = int( + fraction_of_second * definitions.MICROSECONDS_PER_SECOND + ) + self._number_of_seconds = int(timestamp) + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._number_of_seconds is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._microseconds) + / definitions.MICROSECONDS_PER_SECOND + ) + self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a fake timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds") + time_zone_offset = date_time_values.get("time_zone_offset") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + + if nanoseconds is None: + self._microseconds = None + else: + self._microseconds, _ = divmod(nanoseconds, 1000) + + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the fake timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or + "YYYY-MM-DD hh:mm:ss.######" or None if the number of seconds + is missing. + """ + if self._number_of_seconds is None: + return None + + number_of_days, hours, minutes, seconds = self._GetTimeValues( + self._number_of_seconds + ) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + date_time_string = ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) + + if self._microseconds is not None: + date_time_string = ".".join([date_time_string, f"{self._microseconds:06d}"]) + + return date_time_string diff --git a/dfdatetime/fat_date_time.py b/dfdatetime/fat_date_time.py index 2cc8bb3..62e4538 100644 --- a/dfdatetime/fat_date_time.py +++ b/dfdatetime/fat_date_time.py @@ -8,297 +8,309 @@ class FATDateTimeEpoch(interface.DateTimeEpoch): - """FAT date time time epoch.""" + """FAT date time time epoch.""" - def __init__(self): - """Initializes a FAT date time epoch.""" - super().__init__(1980, 1, 1) + def __init__(self): + """Initializes a FAT date time epoch.""" + super().__init__(1980, 1, 1) class FATDateTime(interface.DateTimeValues): - """FAT date time. + """FAT date time. - The FAT date time is mainly used in DOS/Windows file formats and FAT. + The FAT date time is mainly used in DOS/Windows file formats and FAT. - The FAT date and time is a 32-bit value containing two 16-bit values: - * The date (lower 16-bit). - * bits 0 - 4: day of month, where 1 represents the first day - * bits 5 - 8: month of year, where 1 represent January - * bits 9 - 15: year since 1980 - * The time of day (upper 16-bit). - * bits 0 - 4: seconds (in 2 second intervals) - * bits 5 - 10: minutes - * bits 11 - 15: hours + The FAT date and time is a 32-bit value containing two 16-bit values: + * The date (lower 16-bit). + * bits 0 - 4: day of month, where 1 represents the first day + * bits 5 - 8: month of year, where 1 represent January + * bits 9 - 15: year since 1980 + * The time of day (upper 16-bit). + * bits 0 - 4: seconds (in 2 second intervals) + * bits 5 - 10: minutes + * bits 11 - 15: hours - The FAT date time has no time zone information and is typically stored - in the local time of the computer. + The FAT date time has no time zone information and is typically stored + in the local time of the computer. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = FATDateTimeEpoch() - - # The difference between January 1, 1980 and January 1, 1970 in seconds. - _FAT_DATE_TO_POSIX_BASE = 315532800 - - def __init__(self, fat_date_time=None, precision=None, time_zone_offset=None): - """Initializes a FAT date time. - - Args: - fat_date_time (Optional[int]): FAT date time. - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - """ - super().__init__( - precision=precision or definitions.PRECISION_2_SECONDS, - time_zone_offset=time_zone_offset) - self._fat_date_time = fat_date_time - self._number_of_seconds = None - - if fat_date_time is not None: - self._number_of_seconds = self._GetNumberOfSeconds(fat_date_time) - - @property - def fat_date_time(self): - """int: FAT date time or None if not set.""" - return self._fat_date_time - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._number_of_seconds is not None and self._number_of_seconds >= 0: - self._normalized_timestamp = ( - decimal.Decimal(self._number_of_seconds) + - self._FAT_DATE_TO_POSIX_BASE) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def _GetNumberOfSeconds(self, fat_date_time): - """Retrieves the number of seconds from a FAT date time. - - Args: - fat_date_time (int): FAT date time. - - Returns: - int: number of seconds since January 1, 1980 00:00:00. - - Raises: - ValueError: if the month, day of month, hours, minutes or seconds - value is out of bounds. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - day_of_month = fat_date_time & 0x1f - month = (fat_date_time >> 5) & 0x0f - year = (fat_date_time >> 9) & 0x7f - days_per_month = self._GetDaysPerMonth(year, month) - if day_of_month < 1 or day_of_month > days_per_month: - raise ValueError('Day of month value out of bounds.') + _EPOCH = FATDateTimeEpoch() + + # The difference between January 1, 1980 and January 1, 1970 in seconds. + _FAT_DATE_TO_POSIX_BASE = 315532800 + + def __init__(self, fat_date_time=None, precision=None, time_zone_offset=None): + """Initializes a FAT date time. + + Args: + fat_date_time (Optional[int]): FAT date time. + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + """ + super().__init__( + precision=precision or definitions.PRECISION_2_SECONDS, + time_zone_offset=time_zone_offset, + ) + self._fat_date_time = fat_date_time + self._number_of_seconds = None + + if fat_date_time is not None: + self._number_of_seconds = self._GetNumberOfSeconds(fat_date_time) + + @property + def fat_date_time(self): + """int: FAT date time or None if not set.""" + return self._fat_date_time + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._number_of_seconds is not None and self._number_of_seconds >= 0: + self._normalized_timestamp = ( + decimal.Decimal(self._number_of_seconds) + + self._FAT_DATE_TO_POSIX_BASE + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def _GetNumberOfSeconds(self, fat_date_time): + """Retrieves the number of seconds from a FAT date time. + + Args: + fat_date_time (int): FAT date time. + + Returns: + int: number of seconds since January 1, 1980 00:00:00. + + Raises: + ValueError: if the month, day of month, hours, minutes or seconds + value is out of bounds. + """ + day_of_month = fat_date_time & 0x1F + month = (fat_date_time >> 5) & 0x0F + year = (fat_date_time >> 9) & 0x7F + + days_per_month = self._GetDaysPerMonth(year, month) + if day_of_month < 1 or day_of_month > days_per_month: + raise ValueError("Day of month value out of bounds.") + + number_of_days = self._GetDayOfYear(1980 + year, month, day_of_month) + number_of_days -= 1 + for past_year in range(0, year): + number_of_days += self._GetNumberOfDaysInYear(past_year) + + fat_date_time >>= 16 + + seconds = (fat_date_time & 0x1F) * 2 + minutes = (fat_date_time >> 5) & 0x3F + hours = (fat_date_time >> 11) & 0x1F + + if hours not in range(0, 24): + raise ValueError("Hours value out of bounds.") + + if minutes not in range(0, 60): + raise ValueError("Minutes value out of bounds.") + + if seconds not in range(0, 60): + raise ValueError("Seconds value out of bounds.") + + number_of_seconds = (((hours * 60) + minutes) * 60) + seconds + number_of_seconds += number_of_days * definitions.SECONDS_PER_DAY + return number_of_seconds + + def CopyFromDateTimeString(self, time_string): + """Copies a FAT date time from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 1980 or year > (1980 + 0x7F): + raise ValueError(f"Year value not supported: {year!s}.") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._number_of_seconds -= self._FAT_DATE_TO_POSIX_BASE + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the FAT date time to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None + if number of seconds is missing. + """ + if self._number_of_seconds is None: + return None - number_of_days = self._GetDayOfYear(1980 + year, month, day_of_month) - number_of_days -= 1 - for past_year in range(0, year): - number_of_days += self._GetNumberOfDaysInYear(past_year) - - fat_date_time >>= 16 - - seconds = (fat_date_time & 0x1f) * 2 - minutes = (fat_date_time >> 5) & 0x3f - hours = (fat_date_time >> 11) & 0x1f - - if hours not in range(0, 24): - raise ValueError('Hours value out of bounds.') - - if minutes not in range(0, 60): - raise ValueError('Minutes value out of bounds.') - - if seconds not in range(0, 60): - raise ValueError('Seconds value out of bounds.') - - number_of_seconds = (((hours * 60) + minutes) * 60) + seconds - number_of_seconds += number_of_days * definitions.SECONDS_PER_DAY - return number_of_seconds - - def CopyFromDateTimeString(self, time_string): - """Copies a FAT date time from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 1980 or year > (1980 + 0x7f): - raise ValueError(f'Year value not supported: {year!s}.') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._number_of_seconds -= self._FAT_DATE_TO_POSIX_BASE - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the FAT date time to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None - if number of seconds is missing. - """ - if self._number_of_seconds is None: - return None + number_of_days, hours, minutes, seconds = self._GetTimeValues( + self._number_of_seconds + ) - number_of_days, hours, minutes, seconds = self._GetTimeValues( - self._number_of_seconds) + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) class FATTimestamp(interface.DateTimeValues): - """FAT timestamp. - - The FAT timestamp is an unsigned integer that contains the number of - 10 milli seconds intervals since 1980-01-01 00:00:00 (also known as - the FAT date time epoch). - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ + """FAT timestamp. - _EPOCH = FATDateTimeEpoch() + The FAT timestamp is an unsigned integer that contains the number of + 10 milli seconds intervals since 1980-01-01 00:00:00 (also known as + the FAT date time epoch). - # The difference between January 1, 1980 and January 1, 1970 in seconds. - _FAT_DATE_TO_POSIX_BASE = 315532800 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a FAT timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): FAT timestamp. - """ - super().__init__( - precision=precision or definitions.PRECISION_10_MILLISECONDS, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: FAT timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - (decimal.Decimal(self._timestamp) / 100) + - self._FAT_DATE_TO_POSIX_BASE) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a FAT timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 1980 or year > (1980 + 0x7f): - raise ValueError(f'Year value not supported: {year!s}.') - - milliseconds, _ = divmod(nanoseconds, 10000000) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp -= self._FAT_DATE_TO_POSIX_BASE - timestamp *= 100 - timestamp += milliseconds - - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the FAT timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. - """ - if self._timestamp is None: - return None - - timestamp, milliseconds = divmod(self._timestamp, 100) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:02d}') + _EPOCH = FATDateTimeEpoch() + + # The difference between January 1, 1980 and January 1, 1970 in seconds. + _FAT_DATE_TO_POSIX_BASE = 315532800 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a FAT timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): FAT timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_10_MILLISECONDS, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: FAT timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) / 100 + ) + self._FAT_DATE_TO_POSIX_BASE + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a FAT timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 1980 or year > (1980 + 0x7F): + raise ValueError(f"Year value not supported: {year!s}.") + + milliseconds, _ = divmod(nanoseconds, 10000000) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp -= self._FAT_DATE_TO_POSIX_BASE + timestamp *= 100 + timestamp += milliseconds + + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the FAT timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if self._timestamp is None: + return None + + timestamp, milliseconds = divmod(self._timestamp, 100) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:02d}" + ) factory.Factory.RegisterDateTimeValues(FATDateTime) diff --git a/dfdatetime/filetime.py b/dfdatetime/filetime.py index 4e5e1c4..ccbb72c 100644 --- a/dfdatetime/filetime.py +++ b/dfdatetime/filetime.py @@ -8,133 +8,146 @@ class FiletimeEpoch(interface.DateTimeEpoch): - """FILETIME epoch.""" + """FILETIME epoch.""" - def __init__(self): - """Initializes a FILETIME epoch.""" - super().__init__(1601, 1, 1) + def __init__(self): + """Initializes a FILETIME epoch.""" + super().__init__(1601, 1, 1) class Filetime(interface.DateTimeValues): - """FILETIME timestamp. + """FILETIME timestamp. - The FILETIME timestamp is a 64-bit integer that contains the number - of 100th nano seconds since 1601-01-01 00:00:00. + The FILETIME timestamp is a 64-bit integer that contains the number + of 100th nano seconds since 1601-01-01 00:00:00. - Do not confuse this with the FILETIME structure that consists of - 2 x 32-bit integers and is presumed to be unsigned. + Do not confuse this with the FILETIME structure that consists of + 2 x 32-bit integers and is presumed to be unsigned. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = FiletimeEpoch() - - # The difference between January 1, 1601 and January 1, 1970 in seconds. - _FILETIME_TO_POSIX_BASE = 11644473600 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a FILETIME timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): FILETIME timestamp. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - super().__init__( - precision=precision or definitions.PRECISION_100_NANOSECONDS, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: FILETIME timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= 0 and - self._timestamp <= self._UINT64_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND) - self._normalized_timestamp -= self._FILETIME_TO_POSIX_BASE - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a FILETIME timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 1601: - raise ValueError(f'Year value not supported: {year!s}.') - - nanoseconds, _ = divmod(nanoseconds, 100) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp += self._FILETIME_TO_POSIX_BASE - timestamp *= self._100_NANOSECONDS_PER_SECOND - timestamp += nanoseconds - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the FILETIME timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#######" or - None if the timestamp is missing or invalid. - """ - if (self._timestamp is None or self._timestamp < 0 or - self._timestamp > self._UINT64_MAX): - return None - - timestamp, fraction_of_second = divmod( - self._timestamp, self._100_NANOSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}') + _EPOCH = FiletimeEpoch() + + # The difference between January 1, 1601 and January 1, 1970 in seconds. + _FILETIME_TO_POSIX_BASE = 11644473600 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a FILETIME timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): FILETIME timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_100_NANOSECONDS, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: FILETIME timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= 0 + and self._timestamp <= self._UINT64_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND + ) + self._normalized_timestamp -= self._FILETIME_TO_POSIX_BASE + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a FILETIME timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 1601: + raise ValueError(f"Year value not supported: {year!s}.") + + nanoseconds, _ = divmod(nanoseconds, 100) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp += self._FILETIME_TO_POSIX_BASE + timestamp *= self._100_NANOSECONDS_PER_SECOND + timestamp += nanoseconds + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the FILETIME timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#######" or + None if the timestamp is missing or invalid. + """ + if ( + self._timestamp is None + or self._timestamp < 0 + or self._timestamp > self._UINT64_MAX + ): + return None + + timestamp, fraction_of_second = divmod( + self._timestamp, self._100_NANOSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}" + ) factory.Factory.RegisterDateTimeValues(Filetime) diff --git a/dfdatetime/golang_time.py b/dfdatetime/golang_time.py index 82110db..05f04d1 100644 --- a/dfdatetime/golang_time.py +++ b/dfdatetime/golang_time.py @@ -9,205 +9,222 @@ class GolangTimeEpoch(interface.DateTimeEpoch): - """Golang time.Time epoch.""" + """Golang time.Time epoch.""" - def __init__(self): - """Initializes a Golang time.Time epoch.""" - super().__init__(1, 1, 1) + def __init__(self): + """Initializes a Golang time.Time epoch.""" + super().__init__(1, 1, 1) class GolangTime(interface.DateTimeValues): - """Golang time.Time timestamp. - - A Golang time.Time timestamp contains the number of nanoseconds since - January 1, 1 UTC. Depending on the version of the timestamp, the time - zone is stored in minutes or seconds relative to UTC. - - A serialized version 1 Golang time.Time timestamp is a 15 byte value - that consists of: - - * byte 0 - version as an 8-bit integer. - * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed - integer. - * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian - signed integer. - * bytes 13-14 - time zone offset in minutes as a 16-bit big-endian integer, - where -1 represents UTC. - - A serialized version 2 Golang time.Time timestamp is a 16 byte value - that consists of: - - * byte 0 - version as an 8-bit integer. - * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed - integer. - * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian - signed integer. - * bytes 13-14 - time zone offset in minutes as a 16-bit big-endian integer, - where -1 represents UTC. - * byte 15 - time zone offset in seconds as an 8-bit integer. - - Attributes: - is_local_time (bool): True if the date and time value is in local time - """ - - # The delta between January 1, 1970 (unix epoch) and January 1, 1 - # (Golang epoch). - _GOLANG_TO_POSIX_BASE = ( - ((1969 * 365) + (1969 // 4) - (1969 // 100) + (1969 // 400)) * - definitions.SECONDS_PER_DAY) - - _EPOCH = GolangTimeEpoch() - - def __init__(self, golang_timestamp=None, precision=None): - """Initializes a Golang time.Time timestamp. - - Args: - golang_timestamp (Optional[bytes]): the Golang time.Time timestamp. - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. + """Golang time.Time timestamp. + + A Golang time.Time timestamp contains the number of nanoseconds since + January 1, 1 UTC. Depending on the version of the timestamp, the time + zone is stored in minutes or seconds relative to UTC. + + A serialized version 1 Golang time.Time timestamp is a 15 byte value + that consists of: + + * byte 0 - version as an 8-bit integer. + * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed + integer. + * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian + signed integer. + * bytes 13-14 - time zone offset in minutes as a 16-bit big-endian integer, + where -1 represents UTC. + + A serialized version 2 Golang time.Time timestamp is a 16 byte value + that consists of: + + * byte 0 - version as an 8-bit integer. + * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed + integer. + * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian + signed integer. + * bytes 13-14 - time zone offset in minutes as a 16-bit big-endian integer, + where -1 represents UTC. + * byte 15 - time zone offset in seconds as an 8-bit integer. + + Attributes: + is_local_time (bool): True if the date and time value is in local time """ - number_of_seconds, nanoseconds, time_zone_offset = (None, None, None) - if golang_timestamp is not None: - number_of_seconds, nanoseconds, time_zone_offset = ( - self._GetNumberOfSeconds(golang_timestamp)) - - super().__init__( - precision=precision or definitions.PRECISION_1_NANOSECOND, - time_zone_offset=time_zone_offset) - self._golang_timestamp = golang_timestamp - self._nanoseconds = nanoseconds - self._number_of_seconds = number_of_seconds - - @property - def golang_timestamp(self): - """int: Golang time.Time timestamp or None if not set.""" - return self._golang_timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._number_of_seconds is not None and - self._number_of_seconds >= self._GOLANG_TO_POSIX_BASE and - self._nanoseconds is not None and self._nanoseconds >= 0): - - self._normalized_timestamp = decimal.Decimal( - self._number_of_seconds - GolangTime._GOLANG_TO_POSIX_BASE) - - if self._nanoseconds is not None and self._nanoseconds >= 0: - self._normalized_timestamp += ( - decimal.Decimal(self._nanoseconds) / - definitions.NANOSECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def _GetNumberOfSeconds(self, golang_timestamp): - """Retrieves the number of seconds from a Golang time.Time timestamp. - - Args: - golang_timestamp (bytes): the Golang time.Time timestamp. - - Returns: - tuple[int, int, int]: number of seconds since January 1, 1 00:00:00, - fraction of second in nanoseconds and time zone offset in minutes. - - Raises: - ValueError: if the Golang time.Time timestamp could not be parsed. - """ - byte_size = len(golang_timestamp) - if byte_size < 15: - raise ValueError('Unsupported Golang time.Time timestamp.') - - version = golang_timestamp[0] - if version not in (1, 2): - raise ValueError( - f'Unsupported Golang time.Time timestamp version: {version:d}.') - - if (version == 1 and byte_size != 15) or (version == 2 and byte_size != 16): - raise ValueError('Unsupported Golang time.Time timestamp.') - - try: - number_of_seconds, nanoseconds, time_zone_offset = struct.unpack( - '>qih', golang_timestamp[1:15]) - - # TODO: add support for version 2 time zone offset in seconds - - except (TypeError, struct.error) as exception: - raise ValueError(( - f'Unable to unpacked Golang time.Time timestamp with error: ' - f'{exception!s}')) - - # A time zone offset of -1 minute is a special representation for UTC. - if time_zone_offset == -1: - time_zone_offset = 0 - - return number_of_seconds, nanoseconds, time_zone_offset - - def CopyFromDateTimeString(self, time_string): - """Copies a date time value from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 0: - raise ValueError(f'Year value not supported: {year!s}.') - - seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - - seconds += self._GOLANG_TO_POSIX_BASE - - self._normalized_timestamp = None - self._number_of_seconds = seconds - self._nanoseconds = nanoseconds - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the Golang time value to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp cannot be copied to a date and time string. - """ - if self._number_of_seconds is None or self._number_of_seconds < 0: - return None - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - self._number_of_seconds) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{self._nanoseconds:09d}') + # The delta between January 1, 1970 (unix epoch) and January 1, 1 + # (Golang epoch). + _GOLANG_TO_POSIX_BASE = ( + (1969 * 365) + (1969 // 4) - (1969 // 100) + (1969 // 400) + ) * definitions.SECONDS_PER_DAY + + _EPOCH = GolangTimeEpoch() + + def __init__(self, golang_timestamp=None, precision=None): + """Initializes a Golang time.Time timestamp. + + Args: + golang_timestamp (Optional[bytes]): the Golang time.Time timestamp. + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + """ + number_of_seconds, nanoseconds, time_zone_offset = (None, None, None) + if golang_timestamp is not None: + number_of_seconds, nanoseconds, time_zone_offset = self._GetNumberOfSeconds( + golang_timestamp + ) + + super().__init__( + precision=precision or definitions.PRECISION_1_NANOSECOND, + time_zone_offset=time_zone_offset, + ) + self._golang_timestamp = golang_timestamp + self._nanoseconds = nanoseconds + self._number_of_seconds = number_of_seconds + + @property + def golang_timestamp(self): + """int: Golang time.Time timestamp or None if not set.""" + return self._golang_timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._number_of_seconds is not None + and self._number_of_seconds >= self._GOLANG_TO_POSIX_BASE + and self._nanoseconds is not None + and self._nanoseconds >= 0 + ): + + self._normalized_timestamp = decimal.Decimal( + self._number_of_seconds - GolangTime._GOLANG_TO_POSIX_BASE + ) + + if self._nanoseconds is not None and self._nanoseconds >= 0: + self._normalized_timestamp += ( + decimal.Decimal(self._nanoseconds) + / definitions.NANOSECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def _GetNumberOfSeconds(self, golang_timestamp): + """Retrieves the number of seconds from a Golang time.Time timestamp. + + Args: + golang_timestamp (bytes): the Golang time.Time timestamp. + + Returns: + tuple[int, int, int]: number of seconds since January 1, 1 00:00:00, + fraction of second in nanoseconds and time zone offset in minutes. + + Raises: + ValueError: if the Golang time.Time timestamp could not be parsed. + """ + byte_size = len(golang_timestamp) + if byte_size < 15: + raise ValueError("Unsupported Golang time.Time timestamp.") + + version = golang_timestamp[0] + if version not in (1, 2): + raise ValueError( + f"Unsupported Golang time.Time timestamp version: {version:d}." + ) + + if (version == 1 and byte_size != 15) or (version == 2 and byte_size != 16): + raise ValueError("Unsupported Golang time.Time timestamp.") + + try: + number_of_seconds, nanoseconds, time_zone_offset = struct.unpack( + ">qih", golang_timestamp[1:15] + ) + + # TODO: add support for version 2 time zone offset in seconds + + except (TypeError, struct.error) as exception: + raise ValueError( + ( + f"Unable to unpacked Golang time.Time timestamp with error: " + f"{exception!s}" + ) + ) + + # A time zone offset of -1 minute is a special representation for UTC. + if time_zone_offset == -1: + time_zone_offset = 0 + + return number_of_seconds, nanoseconds, time_zone_offset + + def CopyFromDateTimeString(self, time_string): + """Copies a date time value from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 0: + raise ValueError(f"Year value not supported: {year!s}.") + + seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + + seconds += self._GOLANG_TO_POSIX_BASE + + self._normalized_timestamp = None + self._number_of_seconds = seconds + self._nanoseconds = nanoseconds + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the Golang time value to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp cannot be copied to a date and time string. + """ + if self._number_of_seconds is None or self._number_of_seconds < 0: + return None + + number_of_days, hours, minutes, seconds = self._GetTimeValues( + self._number_of_seconds + ) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{self._nanoseconds:09d}" + ) factory.Factory.RegisterDateTimeValues(GolangTime) diff --git a/dfdatetime/hfs_time.py b/dfdatetime/hfs_time.py index 5d7ca20..db25ca6 100644 --- a/dfdatetime/hfs_time.py +++ b/dfdatetime/hfs_time.py @@ -8,122 +8,133 @@ class HFSTimeEpoch(interface.DateTimeEpoch): - """HFS time epoch.""" + """HFS time epoch.""" - def __init__(self): - """Initializes a HFS time epoch.""" - super().__init__(1904, 1, 1) + def __init__(self): + """Initializes a HFS time epoch.""" + super().__init__(1904, 1, 1) class HFSTime(interface.DateTimeValues): - """HFS timestamp. + """HFS timestamp. - The HFS timestamp is an unsigned 32-bit integer that contains the number of - seconds since 1904-01-01 00:00:00. Where in HFS the timestamp is typically - in local time and in HFS+/HFSX in UTC. + The HFS timestamp is an unsigned 32-bit integer that contains the number of + seconds since 1904-01-01 00:00:00. Where in HFS the timestamp is typically + in local time and in HFS+/HFSX in UTC. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = HFSTimeEpoch() - - # The difference between Jan 1, 1904 and Jan 1, 1970 in seconds. - _HFS_TO_POSIX_BASE = 2082844800 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a HFS timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): HFS timestamp. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - super().__init__( - precision=precision or definitions.PRECISION_1_SECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: HFS timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= 0 and - self._timestamp <= self._UINT32_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) - self._HFS_TO_POSIX_BASE) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a HFS timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 1904 or year > 2040: - raise ValueError('Year value not supported.') - - self._normalized_timestamp = None - self._timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._timestamp += self._HFS_TO_POSIX_BASE - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the HFS timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None - if the timestamp is missing or invalid. - """ - if (self._timestamp is None or self._timestamp < 0 or - self._timestamp > self._UINT32_MAX): - return None - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - self._timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') + _EPOCH = HFSTimeEpoch() + + # The difference between Jan 1, 1904 and Jan 1, 1970 in seconds. + _HFS_TO_POSIX_BASE = 2082844800 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a HFS timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): HFS timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_SECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: HFS timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= 0 + and self._timestamp <= self._UINT32_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) - self._HFS_TO_POSIX_BASE + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a HFS timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 1904 or year > 2040: + raise ValueError("Year value not supported.") + + self._normalized_timestamp = None + self._timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._timestamp += self._HFS_TO_POSIX_BASE + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the HFS timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None + if the timestamp is missing or invalid. + """ + if ( + self._timestamp is None + or self._timestamp < 0 + or self._timestamp > self._UINT32_MAX + ): + return None + + number_of_days, hours, minutes, seconds = self._GetTimeValues(self._timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) factory.Factory.RegisterDateTimeValues(HFSTime) diff --git a/dfdatetime/interface.py b/dfdatetime/interface.py index 057b765..97e7ee3 100644 --- a/dfdatetime/interface.py +++ b/dfdatetime/interface.py @@ -7,999 +7,1038 @@ class DateTimeEpoch: - """Date and time epoch interface. + """Date and time epoch interface. - This is the super class of different epoch representations. + This is the super class of different epoch representations. - Attributes: - year (int): year that is the start of the epoch e.g. 1970. - month (int): month that is the start of the epoch, where 1 represents - January. - day_of_month (int): day of the month that is the start of the epoch, - where 1 represents the first day. - """ - - def __init__(self, year, month, day_of_month): - """Initializes a date time epoch. - - Args: + Attributes: year (int): year that is the start of the epoch e.g. 1970. month (int): month that is the start of the epoch, where 1 represents January. day_of_month (int): day of the month that is the start of the epoch, where 1 represents the first day. """ - super().__init__() - self.day_of_month = day_of_month - self.month = month - self.year = year - - -class NormalizedTimeEpoch(DateTimeEpoch): - """dfDateTime normalized time epoch.""" - - def __init__(self): - """Initializes a dfDateTime normalized time epoch.""" - super().__init__(1970, 1, 1) - - -class DateTimeValues: - """Date and time values interface. - - This is the super class of different date and time representations. - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - time_zone_hint (str): time zone hint, such as "Europe/Amsterdam", "CET" or - "UTC+1", or None if not set. - """ - - # pylint: disable=redundant-returns-doc - - _EPOCH_NORMALIZED_TIME = NormalizedTimeEpoch() - - _100_MILLISECONDS_PER_SECOND = 10 - _10_MILLISECONDS_PER_SECOND = 100 - _1_MILLISECOND_PER_SECOND = 1000 - _100_MICROSECONDS_PER_SECOND = 10000 - _10_MICROSECONDS_PER_SECOND = 100000 - _1_MICROSECOND_PER_SECOND = 1000000 - _100_NANOSECONDS_PER_SECOND = 10000000 - _10_NANOSECONDS_PER_SECOND = 100000000 - _1_NANOSECOND_PER_SECOND = definitions.NANOSECONDS_PER_SECOND - - _100_NANOSECONDS_PER_MICROSECOND = 10 - - _INT64_MIN = -(1 << 63) - _INT64_MAX = (1 << 63) - 1 - - _UINT32_MAX = (1 << 32) - 1 - _UINT60_MAX = (1 << 60) - 1 - _UINT64_MAX = (1 << 64) - 1 - - _REMAINDER_MULTIPLIER = { - definitions.PRECISION_1_MILLISECOND: _1_MILLISECOND_PER_SECOND, - definitions.PRECISION_10_MILLISECONDS: _10_MILLISECONDS_PER_SECOND, - definitions.PRECISION_100_MILLISECONDS: _100_MILLISECONDS_PER_SECOND, - definitions.PRECISION_1_MICROSECOND: _1_MICROSECOND_PER_SECOND, - definitions.PRECISION_10_MICROSECONDS: _10_MICROSECONDS_PER_SECOND, - definitions.PRECISION_100_MICROSECONDS: _100_MICROSECONDS_PER_SECOND, - definitions.PRECISION_1_NANOSECOND: _1_NANOSECOND_PER_SECOND, - definitions.PRECISION_10_NANOSECONDS: _10_NANOSECONDS_PER_SECOND, - definitions.PRECISION_100_NANOSECONDS: _100_NANOSECONDS_PER_SECOND} - - def __init__(self, is_delta=False, precision=None, time_zone_offset=None): - """Initializes date time values. - - Args: - 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 - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - """ - super().__init__() - self._cached_date_time_values = None - self._is_delta = is_delta - self._normalized_timestamp = None - self._precision = precision - self._time_zone_offset = time_zone_offset - - self.is_local_time = False - self.time_zone_hint = False - - @property - def is_delta(self): - """Is delta (bool): True if the date and time is relative to another.""" - return self._is_delta - - @property - def precision(self): - """Precision (str): precision of the date and time value.""" - return self._precision - - @property - def time_zone_offset(self): - """Time zone offset (int): time zone offset in minutes from UTC.""" - return self._time_zone_offset - - @time_zone_offset.setter - def time_zone_offset(self, time_zone_offset): - """Sets the time zone offset. - - Args: - time_zone_offset (int): time zone offset in number of minutes from UTC or - None if not set. - """ - self._normalized_timestamp = None - self._time_zone_offset = time_zone_offset - - def __eq__(self, other): - """Determines if the date time values are equal to other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are equal to other. - """ - if not isinstance(other, DateTimeValues): - return False - - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access - - if normalized_timestamp is None and other_normalized_timestamp is not None: - return False - - if normalized_timestamp is not None and other_normalized_timestamp is None: - return False - - return normalized_timestamp == other_normalized_timestamp - - def __ge__(self, other): - """Determines if the date time values are greater than or equal to other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are greater than or equal to other. - - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') - - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access - - if normalized_timestamp is None: - return other_normalized_timestamp is None - - if other_normalized_timestamp is None: - return True - - return normalized_timestamp >= other_normalized_timestamp - - def __gt__(self, other): - """Determines if the date time values are greater than other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are greater than other. - - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access + def __init__(self, year, month, day_of_month): + """Initializes a date time epoch. - if normalized_timestamp is None: - return False + Args: + year (int): year that is the start of the epoch e.g. 1970. + month (int): month that is the start of the epoch, where 1 represents + January. + day_of_month (int): day of the month that is the start of the epoch, + where 1 represents the first day. + """ + super().__init__() + self.day_of_month = day_of_month + self.month = month + self.year = year - if other_normalized_timestamp is None: - return True - - return normalized_timestamp > other_normalized_timestamp - - def __le__(self, other): - """Determines if the date time values are greater than or equal to other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are greater than or equal to other. - - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') - - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access - - if normalized_timestamp is None: - return True - - if other_normalized_timestamp is None: - return False - - return normalized_timestamp <= other_normalized_timestamp - - def __lt__(self, other): - """Determines if the date time values are less than other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are less than other. - - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') - - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access - - if normalized_timestamp is None: - return other_normalized_timestamp is not None - - if other_normalized_timestamp is None: - return False - - return normalized_timestamp < other_normalized_timestamp - - def __ne__(self, other): - """Determines if the date time values are not equal to other. - - Args: - other (DateTimeValues): date time values to compare against. - - Returns: - bool: True if the date time values are not equal to other. - """ - if not isinstance(other, DateTimeValues): - return True - - normalized_timestamp = self._GetNormalizedTimestamp() - other_normalized_timestamp = other._GetNormalizedTimestamp() # pylint: disable=protected-access - - if normalized_timestamp is None and other_normalized_timestamp is not None: - return True - - if normalized_timestamp is not None and other_normalized_timestamp is None: - return True - - return normalized_timestamp != other_normalized_timestamp - - def _CopyDateFromString(self, date_string): - """Copies a date from a string. - - Args: - date_string (str): date value formatted as: YYYY-MM-DD - - Returns: - tuple[int, int, int]: year, month, day of month. - - Raises: - ValueError: if the date string is invalid or not supported. - """ - date_string_length = len(date_string) - # The date string should at least contain 'YYYY-MM-DD'. - if date_string_length < 10: - raise ValueError('Date string too short.') - - if date_string[4] != '-' or date_string[7] != '-': - raise ValueError('Invalid date string.') - - try: - year = int(date_string[0:4], 10) - except ValueError: - raise ValueError('Unable to parse year.') - - try: - month = int(date_string[5:7], 10) - except ValueError: - raise ValueError('Unable to parse month.') - - try: - day_of_month = int(date_string[8:10], 10) - except ValueError: - raise ValueError('Unable to parse day of month.') - - days_per_month = self._GetDaysPerMonth(year, month) - if day_of_month < 1 or day_of_month > days_per_month: - raise ValueError('Day of month value out of bounds.') - - return year, month, day_of_month - - def _CopyDateTimeFromString(self, time_string): - """Copies a date and time from a string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, nanoseconds, time zone offset in minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - if not time_string: - raise ValueError('Invalid time string.') - - time_string_length = len(time_string) - - year, month, day_of_month = self._CopyDateFromString(time_string) - - if time_string_length <= 10: - return { - 'year': year, - 'month': month, - 'day_of_month': day_of_month} - - # If a time of day is specified the time string it should at least - # contain 'YYYY-MM-DD hh:mm:ss'. - if time_string[10] != ' ': - raise ValueError( - 'Invalid time string - space missing as date and time separator.') - - hours, minutes, seconds, nanoseconds, time_zone_offset = ( - self._CopyTimeFromString(time_string[11:])) - - date_time_values = { - 'year': year, - 'month': month, - 'day_of_month': day_of_month, - 'hours': hours, - 'minutes': minutes, - 'seconds': seconds} - - if nanoseconds is not None: - date_time_values['nanoseconds'] = nanoseconds - if time_zone_offset is not None: - date_time_values['time_zone_offset'] = time_zone_offset - - return date_time_values +class NormalizedTimeEpoch(DateTimeEpoch): + """dfDateTime normalized time epoch.""" - def _CopyTimeFromString(self, time_string): - """Copies a time from a string. + def __init__(self): + """Initializes a dfDateTime normalized time epoch.""" + super().__init__(1970, 1, 1) - Args: - time_string (str): time value formatted as: - hh:mm:ss.######[+-]##:## - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The seconds fraction and - time zone offset are optional. +class DateTimeValues: + """Date and time values interface. - Returns: - tuple[int, int, int, int, int]: hours, minutes, seconds, nanoseconds, - time zone offset in minutes. + This is the super class of different date and time representations. - Raises: - ValueError: if the time string is invalid or not supported. + Attributes: + is_local_time (bool): True if the date and time value is in local time. + time_zone_hint (str): time zone hint, such as "Europe/Amsterdam", "CET" or + "UTC+1", or None if not set. """ - time_string_length = len(time_string) - - # The time string should at least contain 'hh:mm:ss'. - if time_string_length < 8: - raise ValueError('Time string too short.') - - if time_string[2] != ':' or time_string[5] != ':': - raise ValueError('Invalid time string.') - - try: - hours = int(time_string[0:2], 10) - except ValueError: - raise ValueError('Unable to parse hours.') - - if hours not in range(0, 24): - raise ValueError(f'Hours value: {hours:d} out of bounds.') - - try: - minutes = int(time_string[3:5], 10) - except ValueError: - raise ValueError('Unable to parse minutes.') - - if minutes not in range(0, 60): - raise ValueError(f'Minutes value: {minutes:d} out of bounds.') - - try: - seconds = int(time_string[6:8], 10) - except ValueError: - raise ValueError('Unable to parse day of seconds.') - - # TODO: support a leap second? - if seconds not in range(0, 60): - raise ValueError(f'Seconds value: {seconds:d} out of bounds.') - - nanoseconds = None - time_zone_offset = None - - time_zone_string_index = 8 - while time_zone_string_index < time_string_length: - if time_string[time_zone_string_index] in ('+', '-'): - break - - time_zone_string_index += 1 - - # The calculations that follow rely on the time zone string index - # to point beyond the string in case no time zone offset was defined. - if time_zone_string_index == time_string_length - 1: - time_zone_string_index += 1 - - if time_string_length > 8 and time_string[8] == '.': - time_fraction_length = time_zone_string_index - 9 - if time_fraction_length not in (3, 6, 9): - raise ValueError('Invalid time string.') - - try: - time_fraction = time_string[9:time_zone_string_index] - time_fraction = int(time_fraction, 10) - except ValueError: - raise ValueError('Unable to parse time fraction.') - - if time_fraction_length == 3: - time_fraction *= 1000000 - elif time_fraction_length == 6: - time_fraction *= 1000 - - nanoseconds = time_fraction - - if time_zone_string_index < time_string_length: - if (time_string_length - time_zone_string_index != 6 or - time_string[time_zone_string_index + 3] != ':'): - raise ValueError('Invalid time string.') - - try: - hours_from_utc = int(time_string[ - time_zone_string_index + 1:time_zone_string_index + 3]) - except ValueError: - raise ValueError('Unable to parse time zone hours offset.') - - if hours_from_utc not in range(0, 15): - raise ValueError('Time zone hours offset value out of bounds.') - - try: - minutes_from_utc = int(time_string[ - time_zone_string_index + 4:time_zone_string_index + 6]) - except ValueError: - raise ValueError('Unable to parse time zone minutes offset.') - - if minutes_from_utc not in range(0, 60): - raise ValueError('Time zone minutes offset value out of bounds.') - - # pylint: disable=invalid-unary-operand-type - time_zone_offset = (hours_from_utc * 60) + minutes_from_utc - - if time_string[time_zone_string_index] == '-': - time_zone_offset = -time_zone_offset - - return hours, minutes, seconds, nanoseconds, time_zone_offset - - def _GetDateValues( - self, number_of_days, epoch_year, epoch_month, epoch_day_of_month): - """Determines date values. - Args: - number_of_days (int): number of days since epoch. - epoch_year (int): year that is the start of the epoch e.g. 1970. - epoch_month (int): month that is the start of the epoch, where - 1 represents January. - epoch_day_of_month (int): day of month that is the start of the epoch, - where 1 represents the first day. - - Returns: - tuple[int, int, int]: year, month, day of month. - - Raises: - ValueError: if the epoch year, month or day of month values are out - of bounds. - """ - if epoch_year < 0: - raise ValueError(f'Epoch year value: {epoch_year:d} out of bounds.') - - if epoch_month not in range(1, 13): - raise ValueError(f'Epoch month value: {epoch_month:d} out of bounds.') - - epoch_days_per_month = self._GetDaysPerMonth(epoch_year, epoch_month) - if epoch_day_of_month < 1 or epoch_day_of_month > epoch_days_per_month: - raise ValueError( - f'Epoch day of month value: {epoch_day_of_month:d} out of bounds.') - - before_epoch = number_of_days < 0 - - year = epoch_year - month = epoch_month - if before_epoch: - month -= 1 - if month <= 0: - month = 12 - year -= 1 - - number_of_days += epoch_day_of_month - if before_epoch: - number_of_days *= -1 - - # Align with the start of the year. - while month > 1: - days_per_month = self._GetDaysPerMonth(year, month) - if number_of_days < days_per_month: - break - - if before_epoch: - month -= 1 - else: - month += 1 - - if month > 12: - month = 1 - year += 1 - - number_of_days -= days_per_month - - # Align with the start of the next century. - _, remainder = divmod(year, 100) - for _ in range(remainder, 100): - days_in_year = self._GetNumberOfDaysInYear(year) - if number_of_days < days_in_year: - break - - if before_epoch: - year -= 1 - else: - year += 1 - - number_of_days -= days_in_year - - days_in_century = self._GetNumberOfDaysInCentury(year) - while number_of_days > days_in_century: - if before_epoch: - year -= 100 - else: - year += 100 - - number_of_days -= days_in_century - days_in_century = self._GetNumberOfDaysInCentury(year) - - days_in_year = self._GetNumberOfDaysInYear(year) - while number_of_days > days_in_year: - if before_epoch: - year -= 1 - else: - year += 1 - - number_of_days -= days_in_year - days_in_year = self._GetNumberOfDaysInYear(year) - - days_per_month = self._GetDaysPerMonth(year, month) - while number_of_days > days_per_month: - if before_epoch: - month -= 1 - else: - month += 1 - - if month <= 0: - month = 12 - year -= 1 - elif month > 12: - month = 1 - year += 1 - - number_of_days -= days_per_month - days_per_month = self._GetDaysPerMonth(year, month) - - if before_epoch: - days_per_month = self._GetDaysPerMonth(year, month) - number_of_days = days_per_month - number_of_days - - elif number_of_days == 0: - number_of_days = 31 - month = 12 - year -= 1 - - return year, month, number_of_days - - def _GetDateValuesWithEpoch(self, number_of_days, date_time_epoch): - """Determines date values. - - Args: - number_of_days (int): number of days since epoch. - date_time_epoch (DateTimeEpoch): date and time of the epoch. - - Returns: - tuple[int, int, int]: year, month, day of month. - """ - return self._GetDateValues( - number_of_days, date_time_epoch.year, date_time_epoch.month, - date_time_epoch.day_of_month) + # pylint: disable=redundant-returns-doc + + _EPOCH_NORMALIZED_TIME = NormalizedTimeEpoch() + + _100_MILLISECONDS_PER_SECOND = 10 + _10_MILLISECONDS_PER_SECOND = 100 + _1_MILLISECOND_PER_SECOND = 1000 + _100_MICROSECONDS_PER_SECOND = 10000 + _10_MICROSECONDS_PER_SECOND = 100000 + _1_MICROSECOND_PER_SECOND = 1000000 + _100_NANOSECONDS_PER_SECOND = 10000000 + _10_NANOSECONDS_PER_SECOND = 100000000 + _1_NANOSECOND_PER_SECOND = definitions.NANOSECONDS_PER_SECOND + + _100_NANOSECONDS_PER_MICROSECOND = 10 + + _INT64_MIN = -(1 << 63) + _INT64_MAX = (1 << 63) - 1 + + _UINT32_MAX = (1 << 32) - 1 + _UINT60_MAX = (1 << 60) - 1 + _UINT64_MAX = (1 << 64) - 1 + + _REMAINDER_MULTIPLIER = { + definitions.PRECISION_1_MILLISECOND: _1_MILLISECOND_PER_SECOND, + definitions.PRECISION_10_MILLISECONDS: _10_MILLISECONDS_PER_SECOND, + definitions.PRECISION_100_MILLISECONDS: _100_MILLISECONDS_PER_SECOND, + definitions.PRECISION_1_MICROSECOND: _1_MICROSECOND_PER_SECOND, + definitions.PRECISION_10_MICROSECONDS: _10_MICROSECONDS_PER_SECOND, + definitions.PRECISION_100_MICROSECONDS: _100_MICROSECONDS_PER_SECOND, + definitions.PRECISION_1_NANOSECOND: _1_NANOSECOND_PER_SECOND, + definitions.PRECISION_10_NANOSECONDS: _10_NANOSECONDS_PER_SECOND, + definitions.PRECISION_100_NANOSECONDS: _100_NANOSECONDS_PER_SECOND, + } + + def __init__(self, is_delta=False, precision=None, time_zone_offset=None): + """Initializes date time values. + + Args: + 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 + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + """ + super().__init__() + self._cached_date_time_values = None + self._is_delta = is_delta + self._normalized_timestamp = None + self._precision = precision + self._time_zone_offset = time_zone_offset + + self.is_local_time = False + self.time_zone_hint = False + + @property + def is_delta(self): + """Is delta (bool): True if the date and time is relative to another.""" + return self._is_delta + + @property + def precision(self): + """Precision (str): precision of the date and time value.""" + return self._precision + + @property + def time_zone_offset(self): + """Time zone offset (int): time zone offset in minutes from UTC.""" + return self._time_zone_offset + + @time_zone_offset.setter + def time_zone_offset(self, time_zone_offset): + """Sets the time zone offset. + + Args: + time_zone_offset (int): time zone offset in number of minutes from UTC or + None if not set. + """ + self._normalized_timestamp = None + self._time_zone_offset = time_zone_offset + + def __eq__(self, other): + """Determines if the date time values are equal to other. + + Args: + other (DateTimeValues): date time values to compare against. + + Returns: + bool: True if the date time values are equal to other. + """ + if not isinstance(other, DateTimeValues): + return False - def _GetDateWithTimeOfDay(self): - """Retrieves the date with time of day. + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access + + if normalized_timestamp is None and other_normalized_timestamp is not None: + return False + + if normalized_timestamp is not None and other_normalized_timestamp is None: + return False + + return normalized_timestamp == other_normalized_timestamp + + def __ge__(self, other): + """Determines if the date time values are greater than or equal to other. + + Args: + other (DateTimeValues): date time values to compare against. + + Returns: + bool: True if the date time values are greater than or equal to other. + + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - Note that the date and time are adjusted to UTC. + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access - Returns: - tuple[int, int, int, int, int, int]: year, month, day of month, hours, - minutes, seconds or (None, None, None, None, None, None) - if the date and time values do not represent a date or time of day. - """ - normalized_timestamp = self._GetNormalizedTimestamp() - if normalized_timestamp is None: - return None, None, None, None, None, None + if normalized_timestamp is None: + return other_normalized_timestamp is None - if (not self._cached_date_time_values or - self._cached_date_time_values[0] != normalized_timestamp): - number_of_days, hours, minutes, seconds = self._GetTimeValues( - normalized_timestamp) + if other_normalized_timestamp is None: + return True - try: - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH_NORMALIZED_TIME) + return normalized_timestamp >= other_normalized_timestamp - except ValueError: - return None, None, None, None, None, None + def __gt__(self, other): + """Determines if the date time values are greater than other. - self._cached_date_time_values = ( - normalized_timestamp, year, month, day_of_month, hours, minutes, - seconds) + Args: + other (DateTimeValues): date time values to compare against. - return self._cached_date_time_values[1:] + Returns: + bool: True if the date time values are greater than other. - def _GetDayOfYear(self, year, month, day_of_month): - """Retrieves the day of the year for a specific day of a month in a year. + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - Args: - year (int): year e.g. 1970. - month (int): month, where 1 represents January. - day_of_month (int): day of the month, where 1 represents the first day. + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access - Returns: - int: day of year. + if normalized_timestamp is None: + return False - Raises: - ValueError: if the month or day of month value is out of bounds. - """ - if month not in range(1, 13): - raise ValueError('Month value out of bounds.') + if other_normalized_timestamp is None: + return True - days_per_month = self._GetDaysPerMonth(year, month) - if day_of_month < 1 or day_of_month > days_per_month: - raise ValueError('Day of month value out of bounds.') + return normalized_timestamp > other_normalized_timestamp - day_of_year = day_of_month - for past_month in range(1, month): - day_of_year += self._GetDaysPerMonth(year, past_month) + def __le__(self, other): + """Determines if the date time values are greater than or equal to other. - return day_of_year + Args: + other (DateTimeValues): date time values to compare against. - def _GetDaysPerMonth(self, year, month): - """Retrieves the number of days in a month of a specific year. + Returns: + bool: True if the date time values are greater than or equal to other. - Args: - year (int): year e.g. 1970. - month (int): month, where 1 represents January. + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - Returns: - int: number of days in the month. + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access - Raises: - ValueError: if the month value is out of bounds. - """ - if month not in range(1, 13): - raise ValueError('Month value out of bounds.') + if normalized_timestamp is None: + return True - days_per_month = definitions.DAYS_PER_MONTH[month - 1] - if month == 2 and (self._is_delta or self._IsLeapYear(year)): - days_per_month += 1 + if other_normalized_timestamp is None: + return False - return days_per_month + return normalized_timestamp <= other_normalized_timestamp - @abc.abstractmethod - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. + def __lt__(self, other): + """Determines if the date time values are less than other. - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ + Args: + other (DateTimeValues): date time values to compare against. - def _GetNumberOfDaysInCentury(self, year): - """Retrieves the number of days in a century. + Returns: + bool: True if the date time values are less than other. - Args: - year (int): year in the century e.g. 1970. + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - Returns: - int: number of (remaining) days in the century. + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access - Raises: - ValueError: if the year value is out of bounds. - """ - if year < 0: - raise ValueError('Year value out of bounds.') + if normalized_timestamp is None: + return other_normalized_timestamp is not None - year, _ = divmod(year, 100) - year *= 100 + if other_normalized_timestamp is None: + return False - number_of_days = definitions.DAYS_PER_CENTURY.get(year) - if number_of_days is not None: - return number_of_days + return normalized_timestamp < other_normalized_timestamp - if self._IsLeapYear(year): - return 36525 - return 36524 + def __ne__(self, other): + """Determines if the date time values are not equal to other. - def _GetNumberOfDaysInYear(self, year): - """Retrieves the number of days in a specific year. + Args: + other (DateTimeValues): date time values to compare against. - Args: - year (int): year e.g. 1970. + Returns: + bool: True if the date time values are not equal to other. + """ + if not isinstance(other, DateTimeValues): + return True - Returns: - int: number of days in the year. - """ - number_of_days = definitions.DAYS_PER_YEAR.get(year) - if number_of_days is not None: - return number_of_days - - if self._IsLeapYear(year): - return 366 - return 365 - - def _GetNumberOfSecondsFromElements( - self, year, month, day_of_month, hours, minutes, seconds): - """Retrieves the number of seconds from the date and time elements. - - Args: - year (int): year e.g. 1970. - month (int): month, where 1 represents January. - day_of_month (int): day of the month, where 1 represents the first day. - hours (int): hours. - minutes (int): minutes. - seconds (int): seconds. - - Returns: - int: number of seconds since January 1, 1970 00:00:00 or None if year, - month or day of month are not set. - - Raises: - ValueError: if the time elements are invalid. - """ - if not month or not day_of_month: - return None + normalized_timestamp = self._GetNormalizedTimestamp() + other_normalized_timestamp = ( + other._GetNormalizedTimestamp() + ) # pylint: disable=protected-access - if hours is None: - hours = 0 - elif hours not in range(0, 24): - raise ValueError(f'Hours value: {hours!s} out of bounds.') + if normalized_timestamp is None and other_normalized_timestamp is not None: + return True - if minutes is None: - minutes = 0 - elif minutes not in range(0, 60): - raise ValueError(f'Minutes value: {minutes!s} out of bounds.') + if normalized_timestamp is not None and other_normalized_timestamp is None: + return True - # TODO: support a leap second? - if seconds is None: - seconds = 0 - elif seconds not in range(0, 60): - raise ValueError(f'Seconds value: {seconds!s} out of bounds.') + return normalized_timestamp != other_normalized_timestamp - number_of_days = definitions.DAYS_PER_YEAR_IN_POSIX_EPOCH.get(year) - if number_of_days is None: - raise ValueError(f'Year value: {year!s} out of bounds.') + def _CopyDateFromString(self, date_string): + """Copies a date from a string. - number_of_days += sum( - definitions.DAYS_PER_MONTH[index] for index in range(month - 1)) - if month > 2 and self._IsLeapYear(year): - number_of_days += 1 + Args: + date_string (str): date value formatted as: YYYY-MM-DD - days_per_month = self._GetDaysPerMonth(year, month) - if day_of_month < 1 or day_of_month > days_per_month: - raise ValueError(f'Day of month value: {day_of_month:d} out of bounds.') + Returns: + tuple[int, int, int]: year, month, day of month. - number_of_days += day_of_month - 1 - number_of_hours = (number_of_days * 24) + hours - number_of_minutes = (number_of_hours * 60) + minutes - number_of_seconds = (number_of_minutes * 60) + seconds + Raises: + ValueError: if the date string is invalid or not supported. + """ + date_string_length = len(date_string) - return number_of_seconds + # The date string should at least contain 'YYYY-MM-DD'. + if date_string_length < 10: + raise ValueError("Date string too short.") - def _GetTimeValues(self, number_of_seconds): - """Determines time values. + if date_string[4] != "-" or date_string[7] != "-": + raise ValueError("Invalid date string.") - Args: - number_of_seconds (int|decimal.Decimal): number of seconds. + try: + year = int(date_string[0:4], 10) + except ValueError: + raise ValueError("Unable to parse year.") - Returns: - tuple[int, int, int, int]: days, hours, minutes, seconds. - """ - number_of_seconds = int(number_of_seconds) - number_of_minutes, seconds = divmod(number_of_seconds, 60) - number_of_hours, minutes = divmod(number_of_minutes, 60) - number_of_days, hours = divmod(number_of_hours, 24) - return number_of_days, hours, minutes, seconds + try: + month = int(date_string[5:7], 10) + except ValueError: + raise ValueError("Unable to parse month.") - def _IsLeapYear(self, year): - """Determines if a year is a leap year. + try: + day_of_month = int(date_string[8:10], 10) + except ValueError: + raise ValueError("Unable to parse day of month.") - Args: - year (int): year e.g. 1970. + days_per_month = self._GetDaysPerMonth(year, month) + if day_of_month < 1 or day_of_month > days_per_month: + raise ValueError("Day of month value out of bounds.") - Returns: - bool: True if the year is a leap year. - """ - # pylint: disable=consider-using-ternary - return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 + return year, month, day_of_month - @abc.abstractmethod - def CopyFromDateTimeString(self, time_string): - """Copies a date time value from a date and time string. + def _CopyDateTimeFromString(self, time_string): + """Copies a date and time from a string. - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. - Raises: - ValueError: if the time string is invalid or not supported. - """ + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, nanoseconds, time zone offset in minutes. - def CopyToPosixTimestamp(self): - """Copies the date time value to a POSIX timestamp. + Raises: + ValueError: if the time string is invalid or not supported. + """ + if not time_string: + raise ValueError("Invalid time string.") - Returns: - int: a POSIX timestamp in seconds or None if no timestamp is available. - """ - normalized_timestamp = self._GetNormalizedTimestamp() - if normalized_timestamp is None: - return None + time_string_length = len(time_string) - return int(normalized_timestamp) + year, month, day_of_month = self._CopyDateFromString(time_string) - def CopyToPosixTimestampWithFractionOfSecond(self): - """Copies the date time value to a POSIX timestamp with fraction of second. + if time_string_length <= 10: + return {"year": year, "month": month, "day_of_month": day_of_month} - Returns: - tuple[int, int]: a POSIX timestamp in seconds with fraction of second or - None, None if no timestamp is available. - """ - normalized_timestamp = self._GetNormalizedTimestamp() - if normalized_timestamp is None: - return None, None - - remainder_multiplier = self._REMAINDER_MULTIPLIER.get(self._precision) - if not remainder_multiplier: - remainder = None - elif normalized_timestamp >= 0: - remainder = int((normalized_timestamp % 1) * remainder_multiplier) - else: - remainder = int((normalized_timestamp % 1) * -remainder_multiplier) - - return int(normalized_timestamp), remainder - - @abc.abstractmethod - def CopyToDateTimeString(self): - """Copies the date time value to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp cannot be copied to a date and time string. - """ + # If a time of day is specified the time string it should at least + # contain 'YYYY-MM-DD hh:mm:ss'. + if time_string[10] != " ": + raise ValueError( + "Invalid time string - space missing as date and time separator." + ) - def CopyToDateTimeStringISO8601(self): - """Copies the date time value to an ISO 8601 date and time string. + hours, minutes, seconds, nanoseconds, time_zone_offset = ( + self._CopyTimeFromString(time_string[11:]) + ) + + date_time_values = { + "year": year, + "month": month, + "day_of_month": day_of_month, + "hours": hours, + "minutes": minutes, + "seconds": seconds, + } - Returns: - str: date and time value formatted as an ISO 8601 date and time string or - None if the timestamp cannot be copied to a date and time string. - """ - date_time_string = self.CopyToDateTimeString() - if date_time_string: - date_time_string = date_time_string.replace(' ', 'T') - - if self._time_zone_offset is not None or not self.is_local_time: - time_zone_offset_hours, time_zone_offset_minutes = divmod( - self._time_zone_offset or 0, 60) - if time_zone_offset_hours >= 0: - time_zone_offset_sign = '+' + if nanoseconds is not None: + date_time_values["nanoseconds"] = nanoseconds + if time_zone_offset is not None: + date_time_values["time_zone_offset"] = time_zone_offset + + return date_time_values + + def _CopyTimeFromString(self, time_string): + """Copies a time from a string. + + Args: + time_string (str): time value formatted as: + hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The seconds fraction and + time zone offset are optional. + + Returns: + tuple[int, int, int, int, int]: hours, minutes, seconds, nanoseconds, + time zone offset in minutes. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + time_string_length = len(time_string) + + # The time string should at least contain 'hh:mm:ss'. + if time_string_length < 8: + raise ValueError("Time string too short.") + + if time_string[2] != ":" or time_string[5] != ":": + raise ValueError("Invalid time string.") + + try: + hours = int(time_string[0:2], 10) + except ValueError: + raise ValueError("Unable to parse hours.") + + if hours not in range(0, 24): + raise ValueError(f"Hours value: {hours:d} out of bounds.") + + try: + minutes = int(time_string[3:5], 10) + except ValueError: + raise ValueError("Unable to parse minutes.") + + if minutes not in range(0, 60): + raise ValueError(f"Minutes value: {minutes:d} out of bounds.") + + try: + seconds = int(time_string[6:8], 10) + except ValueError: + raise ValueError("Unable to parse day of seconds.") + + # TODO: support a leap second? + if seconds not in range(0, 60): + raise ValueError(f"Seconds value: {seconds:d} out of bounds.") + + nanoseconds = None + time_zone_offset = None + + time_zone_string_index = 8 + while time_zone_string_index < time_string_length: + if time_string[time_zone_string_index] in ("+", "-"): + break + + time_zone_string_index += 1 + + # The calculations that follow rely on the time zone string index + # to point beyond the string in case no time zone offset was defined. + if time_zone_string_index == time_string_length - 1: + time_zone_string_index += 1 + + if time_string_length > 8 and time_string[8] == ".": + time_fraction_length = time_zone_string_index - 9 + if time_fraction_length not in (3, 6, 9): + raise ValueError("Invalid time string.") + + try: + time_fraction = time_string[9:time_zone_string_index] + time_fraction = int(time_fraction, 10) + except ValueError: + raise ValueError("Unable to parse time fraction.") + + if time_fraction_length == 3: + time_fraction *= 1000000 + elif time_fraction_length == 6: + time_fraction *= 1000 + + nanoseconds = time_fraction + + if time_zone_string_index < time_string_length: + if ( + time_string_length - time_zone_string_index != 6 + or time_string[time_zone_string_index + 3] != ":" + ): + raise ValueError("Invalid time string.") + + try: + hours_from_utc = int( + time_string[time_zone_string_index + 1 : time_zone_string_index + 3] + ) + except ValueError: + raise ValueError("Unable to parse time zone hours offset.") + + if hours_from_utc not in range(0, 15): + raise ValueError("Time zone hours offset value out of bounds.") + + try: + minutes_from_utc = int( + time_string[time_zone_string_index + 4 : time_zone_string_index + 6] + ) + except ValueError: + raise ValueError("Unable to parse time zone minutes offset.") + + if minutes_from_utc not in range(0, 60): + raise ValueError("Time zone minutes offset value out of bounds.") + + # pylint: disable=invalid-unary-operand-type + time_zone_offset = (hours_from_utc * 60) + minutes_from_utc + + if time_string[time_zone_string_index] == "-": + time_zone_offset = -time_zone_offset + + return hours, minutes, seconds, nanoseconds, time_zone_offset + + def _GetDateValues( + self, number_of_days, epoch_year, epoch_month, epoch_day_of_month + ): + """Determines date values. + + Args: + number_of_days (int): number of days since epoch. + epoch_year (int): year that is the start of the epoch e.g. 1970. + epoch_month (int): month that is the start of the epoch, where + 1 represents January. + epoch_day_of_month (int): day of month that is the start of the epoch, + where 1 represents the first day. + + Returns: + tuple[int, int, int]: year, month, day of month. + + Raises: + ValueError: if the epoch year, month or day of month values are out + of bounds. + """ + if epoch_year < 0: + raise ValueError(f"Epoch year value: {epoch_year:d} out of bounds.") + + if epoch_month not in range(1, 13): + raise ValueError(f"Epoch month value: {epoch_month:d} out of bounds.") + + epoch_days_per_month = self._GetDaysPerMonth(epoch_year, epoch_month) + if epoch_day_of_month < 1 or epoch_day_of_month > epoch_days_per_month: + raise ValueError( + f"Epoch day of month value: {epoch_day_of_month:d} out of bounds." + ) + + before_epoch = number_of_days < 0 + + year = epoch_year + month = epoch_month + if before_epoch: + month -= 1 + if month <= 0: + month = 12 + year -= 1 + + number_of_days += epoch_day_of_month + if before_epoch: + number_of_days *= -1 + + # Align with the start of the year. + while month > 1: + days_per_month = self._GetDaysPerMonth(year, month) + if number_of_days < days_per_month: + break + + if before_epoch: + month -= 1 + else: + month += 1 + + if month > 12: + month = 1 + year += 1 + + number_of_days -= days_per_month + + # Align with the start of the next century. + _, remainder = divmod(year, 100) + for _ in range(remainder, 100): + days_in_year = self._GetNumberOfDaysInYear(year) + if number_of_days < days_in_year: + break + + if before_epoch: + year -= 1 + else: + year += 1 + + number_of_days -= days_in_year + + days_in_century = self._GetNumberOfDaysInCentury(year) + while number_of_days > days_in_century: + if before_epoch: + year -= 100 + else: + year += 100 + + number_of_days -= days_in_century + days_in_century = self._GetNumberOfDaysInCentury(year) + + days_in_year = self._GetNumberOfDaysInYear(year) + while number_of_days > days_in_year: + if before_epoch: + year -= 1 + else: + year += 1 + + number_of_days -= days_in_year + days_in_year = self._GetNumberOfDaysInYear(year) + + days_per_month = self._GetDaysPerMonth(year, month) + while number_of_days > days_per_month: + if before_epoch: + month -= 1 + else: + month += 1 + + if month <= 0: + month = 12 + year -= 1 + elif month > 12: + month = 1 + year += 1 + + number_of_days -= days_per_month + days_per_month = self._GetDaysPerMonth(year, month) + + if before_epoch: + days_per_month = self._GetDaysPerMonth(year, month) + number_of_days = days_per_month - number_of_days + + elif number_of_days == 0: + number_of_days = 31 + month = 12 + year -= 1 + + return year, month, number_of_days + + def _GetDateValuesWithEpoch(self, number_of_days, date_time_epoch): + """Determines date values. + + Args: + number_of_days (int): number of days since epoch. + date_time_epoch (DateTimeEpoch): date and time of the epoch. + + Returns: + tuple[int, int, int]: year, month, day of month. + """ + return self._GetDateValues( + number_of_days, + date_time_epoch.year, + date_time_epoch.month, + date_time_epoch.day_of_month, + ) + + def _GetDateWithTimeOfDay(self): + """Retrieves the date with time of day. + + Note that the date and time are adjusted to UTC. + + Returns: + tuple[int, int, int, int, int, int]: year, month, day of month, hours, + minutes, seconds or (None, None, None, None, None, None) + if the date and time values do not represent a date or time of day. + """ + normalized_timestamp = self._GetNormalizedTimestamp() + if normalized_timestamp is None: + return None, None, None, None, None, None + + if ( + not self._cached_date_time_values + or self._cached_date_time_values[0] != normalized_timestamp + ): + number_of_days, hours, minutes, seconds = self._GetTimeValues( + normalized_timestamp + ) + + try: + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH_NORMALIZED_TIME + ) + + except ValueError: + return None, None, None, None, None, None + + self._cached_date_time_values = ( + normalized_timestamp, + year, + month, + day_of_month, + hours, + minutes, + seconds, + ) + + return self._cached_date_time_values[1:] + + def _GetDayOfYear(self, year, month, day_of_month): + """Retrieves the day of the year for a specific day of a month in a year. + + Args: + year (int): year e.g. 1970. + month (int): month, where 1 represents January. + day_of_month (int): day of the month, where 1 represents the first day. + + Returns: + int: day of year. + + Raises: + ValueError: if the month or day of month value is out of bounds. + """ + if month not in range(1, 13): + raise ValueError("Month value out of bounds.") + + days_per_month = self._GetDaysPerMonth(year, month) + if day_of_month < 1 or day_of_month > days_per_month: + raise ValueError("Day of month value out of bounds.") + + day_of_year = day_of_month + for past_month in range(1, month): + day_of_year += self._GetDaysPerMonth(year, past_month) + + return day_of_year + + def _GetDaysPerMonth(self, year, month): + """Retrieves the number of days in a month of a specific year. + + Args: + year (int): year e.g. 1970. + month (int): month, where 1 represents January. + + Returns: + int: number of days in the month. + + Raises: + ValueError: if the month value is out of bounds. + """ + if month not in range(1, 13): + raise ValueError("Month value out of bounds.") + + days_per_month = definitions.DAYS_PER_MONTH[month - 1] + if month == 2 and (self._is_delta or self._IsLeapYear(year)): + days_per_month += 1 + + return days_per_month + + @abc.abstractmethod + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + + def _GetNumberOfDaysInCentury(self, year): + """Retrieves the number of days in a century. + + Args: + year (int): year in the century e.g. 1970. + + Returns: + int: number of (remaining) days in the century. + + Raises: + ValueError: if the year value is out of bounds. + """ + if year < 0: + raise ValueError("Year value out of bounds.") + + year, _ = divmod(year, 100) + year *= 100 + + number_of_days = definitions.DAYS_PER_CENTURY.get(year) + if number_of_days is not None: + return number_of_days + + if self._IsLeapYear(year): + return 36525 + return 36524 + + def _GetNumberOfDaysInYear(self, year): + """Retrieves the number of days in a specific year. + + Args: + year (int): year e.g. 1970. + + Returns: + int: number of days in the year. + """ + number_of_days = definitions.DAYS_PER_YEAR.get(year) + if number_of_days is not None: + return number_of_days + + if self._IsLeapYear(year): + return 366 + return 365 + + def _GetNumberOfSecondsFromElements( + self, year, month, day_of_month, hours, minutes, seconds + ): + """Retrieves the number of seconds from the date and time elements. + + Args: + year (int): year e.g. 1970. + month (int): month, where 1 represents January. + day_of_month (int): day of the month, where 1 represents the first day. + hours (int): hours. + minutes (int): minutes. + seconds (int): seconds. + + Returns: + int: number of seconds since January 1, 1970 00:00:00 or None if year, + month or day of month are not set. + + Raises: + ValueError: if the time elements are invalid. + """ + if not month or not day_of_month: + return None + + if hours is None: + hours = 0 + elif hours not in range(0, 24): + raise ValueError(f"Hours value: {hours!s} out of bounds.") + + if minutes is None: + minutes = 0 + elif minutes not in range(0, 60): + raise ValueError(f"Minutes value: {minutes!s} out of bounds.") + + # TODO: support a leap second? + if seconds is None: + seconds = 0 + elif seconds not in range(0, 60): + raise ValueError(f"Seconds value: {seconds!s} out of bounds.") + + number_of_days = definitions.DAYS_PER_YEAR_IN_POSIX_EPOCH.get(year) + if number_of_days is None: + raise ValueError(f"Year value: {year!s} out of bounds.") + + number_of_days += sum( + definitions.DAYS_PER_MONTH[index] for index in range(month - 1) + ) + if month > 2 and self._IsLeapYear(year): + number_of_days += 1 + + days_per_month = self._GetDaysPerMonth(year, month) + if day_of_month < 1 or day_of_month > days_per_month: + raise ValueError(f"Day of month value: {day_of_month:d} out of bounds.") + + number_of_days += day_of_month - 1 + number_of_hours = (number_of_days * 24) + hours + number_of_minutes = (number_of_hours * 60) + minutes + number_of_seconds = (number_of_minutes * 60) + seconds + + return number_of_seconds + + def _GetTimeValues(self, number_of_seconds): + """Determines time values. + + Args: + number_of_seconds (int|decimal.Decimal): number of seconds. + + Returns: + tuple[int, int, int, int]: days, hours, minutes, seconds. + """ + number_of_seconds = int(number_of_seconds) + number_of_minutes, seconds = divmod(number_of_seconds, 60) + number_of_hours, minutes = divmod(number_of_minutes, 60) + number_of_days, hours = divmod(number_of_hours, 24) + return number_of_days, hours, minutes, seconds + + def _IsLeapYear(self, year): + """Determines if a year is a leap year. + + Args: + year (int): year e.g. 1970. + + Returns: + bool: True if the year is a leap year. + """ + # pylint: disable=consider-using-ternary + return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 + + @abc.abstractmethod + def CopyFromDateTimeString(self, time_string): + """Copies a date time value from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + + def CopyToPosixTimestamp(self): + """Copies the date time value to a POSIX timestamp. + + Returns: + int: a POSIX timestamp in seconds or None if no timestamp is available. + """ + normalized_timestamp = self._GetNormalizedTimestamp() + if normalized_timestamp is None: + return None + + return int(normalized_timestamp) + + def CopyToPosixTimestampWithFractionOfSecond(self): + """Copies the date time value to a POSIX timestamp with fraction of second. + + Returns: + tuple[int, int]: a POSIX timestamp in seconds with fraction of second or + None, None if no timestamp is available. + """ + normalized_timestamp = self._GetNormalizedTimestamp() + if normalized_timestamp is None: + return None, None + + remainder_multiplier = self._REMAINDER_MULTIPLIER.get(self._precision) + if not remainder_multiplier: + remainder = None + elif normalized_timestamp >= 0: + remainder = int((normalized_timestamp % 1) * remainder_multiplier) else: - time_zone_offset_sign = '-' - time_zone_offset_hours *= -1 - - time_zone_string = ( - f'{time_zone_offset_hours:02d}:{time_zone_offset_minutes:02d}') - date_time_string = time_zone_offset_sign.join([ - date_time_string, time_zone_string]) - - return date_time_string - - def GetDate(self): - """Retrieves the date represented by the date and time values. - - Note that the date is adjusted to UTC. - - Returns: - tuple[int, int, int]: year, month, day of month or (None, None, None) - if the date and time values do not represent a date. - """ - year, month, day_of_month, _, _, _ = self._GetDateWithTimeOfDay() - return year, month, day_of_month - - def GetDateWithTimeOfDay(self): - """Retrieves the date with time of day. - - Note that the date and time are adjusted to UTC. - - Returns: - tuple[int, int, int, int, int, int]: year, month, day of month, hours, - minutes, seconds or (None, None, None, None, None, None) - if the date and time values do not represent a date or time of day. - """ - return self._GetDateWithTimeOfDay() - - # TODO: remove this method when there is no more need for it in Plaso. - def GetPlasoTimestamp(self): - """Retrieves a timestamp that is compatible with Plaso. - - Returns: - int: a POSIX timestamp in microseconds or None if no timestamp is - available. - - Raises: - ValueError: if the timestamp cannot be determined. - """ - normalized_timestamp = self._GetNormalizedTimestamp() - if normalized_timestamp is None: - return None - - normalized_timestamp *= definitions.MICROSECONDS_PER_SECOND - - try: - normalized_timestamp = normalized_timestamp.quantize( - 1, rounding=decimal.ROUND_HALF_UP) - except decimal.InvalidOperation as exception: - raise ValueError( - f'Unable to round normalized timestamp with error: {exception!s}') - - return int(normalized_timestamp) - - def GetTimeOfDay(self): - """Retrieves the time of day represented by the date and time values. - - Note that the time is adjusted to UTC. - - Returns: - tuple[int, int, int]: hours, minutes, seconds or (None, None, None) - if the date and time values do not represent a time of day. - """ - _, _, _, hours, minutes, seconds = self._GetDateWithTimeOfDay() - return hours, minutes, seconds + remainder = int((normalized_timestamp % 1) * -remainder_multiplier) + + return int(normalized_timestamp), remainder + + @abc.abstractmethod + def CopyToDateTimeString(self): + """Copies the date time value to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp cannot be copied to a date and time string. + """ + + def CopyToDateTimeStringISO8601(self): + """Copies the date time value to an ISO 8601 date and time string. + + Returns: + str: date and time value formatted as an ISO 8601 date and time string or + None if the timestamp cannot be copied to a date and time string. + """ + date_time_string = self.CopyToDateTimeString() + if date_time_string: + date_time_string = date_time_string.replace(" ", "T") + + if self._time_zone_offset is not None or not self.is_local_time: + time_zone_offset_hours, time_zone_offset_minutes = divmod( + self._time_zone_offset or 0, 60 + ) + if time_zone_offset_hours >= 0: + time_zone_offset_sign = "+" + else: + time_zone_offset_sign = "-" + time_zone_offset_hours *= -1 + + time_zone_string = ( + f"{time_zone_offset_hours:02d}:{time_zone_offset_minutes:02d}" + ) + date_time_string = time_zone_offset_sign.join( + [date_time_string, time_zone_string] + ) + + return date_time_string + + def GetDate(self): + """Retrieves the date represented by the date and time values. + + Note that the date is adjusted to UTC. + + Returns: + tuple[int, int, int]: year, month, day of month or (None, None, None) + if the date and time values do not represent a date. + """ + year, month, day_of_month, _, _, _ = self._GetDateWithTimeOfDay() + return year, month, day_of_month + + def GetDateWithTimeOfDay(self): + """Retrieves the date with time of day. + + Note that the date and time are adjusted to UTC. + + Returns: + tuple[int, int, int, int, int, int]: year, month, day of month, hours, + minutes, seconds or (None, None, None, None, None, None) + if the date and time values do not represent a date or time of day. + """ + return self._GetDateWithTimeOfDay() + + # TODO: remove this method when there is no more need for it in Plaso. + def GetPlasoTimestamp(self): + """Retrieves a timestamp that is compatible with Plaso. + + Returns: + int: a POSIX timestamp in microseconds or None if no timestamp is + available. + + Raises: + ValueError: if the timestamp cannot be determined. + """ + normalized_timestamp = self._GetNormalizedTimestamp() + if normalized_timestamp is None: + return None + + normalized_timestamp *= definitions.MICROSECONDS_PER_SECOND + + try: + normalized_timestamp = normalized_timestamp.quantize( + 1, rounding=decimal.ROUND_HALF_UP + ) + except decimal.InvalidOperation as exception: + raise ValueError( + f"Unable to round normalized timestamp with error: {exception!s}" + ) + + return int(normalized_timestamp) + + def GetTimeOfDay(self): + """Retrieves the time of day represented by the date and time values. + + Note that the time is adjusted to UTC. + + Returns: + tuple[int, int, int]: hours, minutes, seconds or (None, None, None) + if the date and time values do not represent a time of day. + """ + _, _, _, hours, minutes, seconds = self._GetDateWithTimeOfDay() + return hours, minutes, seconds diff --git a/dfdatetime/java_time.py b/dfdatetime/java_time.py index 650d31b..97a46c7 100644 --- a/dfdatetime/java_time.py +++ b/dfdatetime/java_time.py @@ -8,52 +8,59 @@ class JavaTime(posix_time.PosixTimeInMilliseconds): - """Java java.util.Date timestamp. + """Java java.util.Date timestamp. - The Java java.util.Date timestamp is a signed integer that contains the - number of milliseconds since 1970-01-01 00:00:00 (also known as the POSIX - epoch). Negative values represent date and times predating the POSIX epoch. + The Java java.util.Date timestamp is a signed integer that contains the + number of milliseconds since 1970-01-01 00:00:00 (also known as the POSIX + epoch). Negative values represent date and times predating the POSIX epoch. - Also see: - https://docs.oracle.com/javase/8/docs/api/java/util/Date.html + Also see: + https://docs.oracle.com/javase/8/docs/api/java/util/Date.html - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= self._INT64_MIN and - self._timestamp <= self._INT64_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.MILLISECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if (self._timestamp is None or self._timestamp < self._INT64_MIN or - self._timestamp > self._INT64_MAX): - return None - return super().CopyToDateTimeString() + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= self._INT64_MIN + and self._timestamp <= self._INT64_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.MILLISECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if ( + self._timestamp is None + or self._timestamp < self._INT64_MIN + or self._timestamp > self._INT64_MAX + ): + return None + + return super().CopyToDateTimeString() factory.Factory.RegisterDateTimeValues(JavaTime) diff --git a/dfdatetime/ole_automation_date.py b/dfdatetime/ole_automation_date.py index e04fa0e..b463397 100644 --- a/dfdatetime/ole_automation_date.py +++ b/dfdatetime/ole_automation_date.py @@ -8,134 +8,140 @@ class OLEAutomationDateEpoch(interface.DateTimeEpoch): - """OLE automation date epoch.""" + """OLE automation date epoch.""" - def __init__(self): - """Initializes a OLE automation date epoch.""" - super().__init__(1899, 12, 30) + def __init__(self): + """Initializes a OLE automation date epoch.""" + super().__init__(1899, 12, 30) class OLEAutomationDate(interface.DateTimeValues): - """OLE Automation date. + """OLE Automation date. - The OLE Automation date is a floating point value that contains the number of - days since 1899-12-30 (also known as the OLE Automation date epoch), and the - fractional part represents the fraction of a day since midnight. Negative - values represent date and times predating the OLE Automation date epoch. + The OLE Automation date is a floating point value that contains the number of + days since 1899-12-30 (also known as the OLE Automation date epoch), and the + fractional part represents the fraction of a day since midnight. Negative + values represent date and times predating the OLE Automation date epoch. - Also see: - https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tooadate?view=net-8.0 + Also see: + https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tooadate?view=net-8.0 - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - _EPOCH = OLEAutomationDateEpoch() - - # The difference between December 30, 1899 and January 1, 1970 in days. - _OLE_AUTOMATION_DATE_TO_POSIX_BASE = 25569 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes an OLE Automation date. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[float]): OLE Automation date. - """ - super().__init__( - precision=precision or definitions.PRECISION_1_MICROSECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """float: OLE Automation date timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) - - self._OLE_AUTOMATION_DATE_TO_POSIX_BASE) - self._normalized_timestamp *= definitions.SECONDS_PER_DAY - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies an OLE Automation date from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - - timestamp = float(timestamp) - timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_SECOND - - timestamp /= definitions.SECONDS_PER_DAY - timestamp += self._OLE_AUTOMATION_DATE_TO_POSIX_BASE - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the OLE Automation date to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. - """ - if self._timestamp is None: - return None - - timestamp = self._timestamp * definitions.SECONDS_PER_DAY - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - int(timestamp)) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - microseconds = int((timestamp % 1) * definitions.MICROSECONDS_PER_SECOND) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + _EPOCH = OLEAutomationDateEpoch() + + # The difference between December 30, 1899 and January 1, 1970 in days. + _OLE_AUTOMATION_DATE_TO_POSIX_BASE = 25569 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes an OLE Automation date. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[float]): OLE Automation date. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MICROSECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """float: OLE Automation date timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + - self._OLE_AUTOMATION_DATE_TO_POSIX_BASE + ) + self._normalized_timestamp *= definitions.SECONDS_PER_DAY + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies an OLE Automation date from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + + timestamp = float(timestamp) + timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_SECOND + + timestamp /= definitions.SECONDS_PER_DAY + timestamp += self._OLE_AUTOMATION_DATE_TO_POSIX_BASE + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the OLE Automation date to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if self._timestamp is None: + return None + + timestamp = self._timestamp * definitions.SECONDS_PER_DAY + + number_of_days, hours, minutes, seconds = self._GetTimeValues(int(timestamp)) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + microseconds = int((timestamp % 1) * definitions.MICROSECONDS_PER_SECOND) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) factory.Factory.RegisterDateTimeValues(OLEAutomationDate) diff --git a/dfdatetime/posix_time.py b/dfdatetime/posix_time.py index 3a01a17..536c342 100644 --- a/dfdatetime/posix_time.py +++ b/dfdatetime/posix_time.py @@ -8,450 +8,473 @@ class PosixTimeEpoch(interface.DateTimeEpoch): - """POSIX time epoch.""" + """POSIX time epoch.""" - def __init__(self): - """Initializes a POSIX time epoch.""" - super().__init__(1970, 1, 1) + def __init__(self): + """Initializes a POSIX time epoch.""" + super().__init__(1970, 1, 1) class PosixTime(interface.DateTimeValues): - """POSIX timestamp. + """POSIX timestamp. - The POSIX timestamp is a signed integer that contains the number of - seconds since 1970-01-01 00:00:00 (also known as the POSIX epoch). - Negative values represent date and times predating the POSIX epoch. + The POSIX timestamp is a signed integer that contains the number of + seconds since 1970-01-01 00:00:00 (also known as the POSIX epoch). + Negative values represent date and times predating the POSIX epoch. - The POSIX timestamp was initially 32-bit though 64-bit variants - are known to be used. + The POSIX timestamp was initially 32-bit though 64-bit variants + are known to be used. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = PosixTimeEpoch() - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a POSIX timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): POSIX timestamp. - """ - super().__init__( - precision=precision or definitions.PRECISION_1_SECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: POSIX timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = decimal.Decimal(self._timestamp) - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a POSIX timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - self._timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None - if the timestamp is missing. - """ - if self._timestamp is None: - return None - - number_of_days, hours, minutes, seconds = self._GetTimeValues( - self._timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') + _EPOCH = PosixTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a POSIX timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): POSIX timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_SECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: POSIX timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = decimal.Decimal(self._timestamp) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a POSIX timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + self._timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None + if the timestamp is missing. + """ + if self._timestamp is None: + return None + + number_of_days, hours, minutes, seconds = self._GetTimeValues(self._timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) class PosixTimeInMilliseconds(interface.DateTimeValues): - """POSIX timestamp in milliseconds. - - Variant of the POSIX timestamp in milliseconds. - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ + """POSIX timestamp in milliseconds. - _EPOCH = PosixTimeEpoch() + Variant of the POSIX timestamp in milliseconds. - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a POSIX timestamp in milliseconds. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): POSIX timestamp in milliseconds. - """ - super().__init__( - precision=precision or definitions.PRECISION_1_MILLISECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: POSIX timestamp in milliseconds or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.MILLISECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a POSIX timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - milliseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp *= definitions.MILLISECONDS_PER_SECOND - timestamp += milliseconds - - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if self._timestamp is None: - return None - - timestamp, milliseconds = divmod( - self._timestamp, definitions.MILLISECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}') + _EPOCH = PosixTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a POSIX timestamp in milliseconds. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): POSIX timestamp in milliseconds. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MILLISECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: POSIX timestamp in milliseconds or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.MILLISECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a POSIX timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp *= definitions.MILLISECONDS_PER_SECOND + timestamp += milliseconds + + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if self._timestamp is None: + return None + + timestamp, milliseconds = divmod( + self._timestamp, definitions.MILLISECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}" + ) class PosixTimeInMicroseconds(interface.DateTimeValues): - """POSIX timestamp in microseconds. - - Variant of the POSIX timestamp in microseconds. - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = PosixTimeEpoch() + """POSIX timestamp in microseconds. - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a POSIX timestamp in microseconds. + Variant of the POSIX timestamp in microseconds. - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): POSIX timestamp in microseconds. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - super().__init__( - precision=precision or definitions.PRECISION_1_MICROSECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: POSIX timestamp in microseconds or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.MICROSECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a POSIX timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - milliseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp *= definitions.MICROSECONDS_PER_SECOND - timestamp += milliseconds - - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing. - """ - if self._timestamp is None: - return None - timestamp, microseconds = divmod( - self._timestamp, definitions.MICROSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + _EPOCH = PosixTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a POSIX timestamp in microseconds. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): POSIX timestamp in microseconds. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MICROSECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: POSIX timestamp in microseconds or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.MICROSECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a POSIX timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp *= definitions.MICROSECONDS_PER_SECOND + timestamp += milliseconds + + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing. + """ + if self._timestamp is None: + return None + + timestamp, microseconds = divmod( + self._timestamp, definitions.MICROSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) class PosixTimeInNanoseconds(interface.DateTimeValues): - """POSIX timestamp in nanoseconds. - - Variant of the POSIX timestamp in nanoseconds. - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ + """POSIX timestamp in nanoseconds. - _EPOCH = PosixTimeEpoch() + Variant of the POSIX timestamp in nanoseconds. - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a POSIX timestamp in nanoseconds. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): POSIX timestamp in nanoseconds. - """ - super().__init__( - precision=precision or definitions.PRECISION_1_NANOSECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: POSIX timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if self._normalized_timestamp is None: - if self._timestamp is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.NANOSECONDS_PER_SECOND) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - return self._normalized_timestamp - - def _CopyFromDateTimeString(self, time_string): - """Copies a POSIX timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp *= definitions.NANOSECONDS_PER_SECOND - timestamp += nanoseconds - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyFromDateTimeString(self, time_string): - """Copies a POSIX timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - self._CopyFromDateTimeString(time_string) - - def _CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or - None if the timestamp is missing or invalid. - """ - if self._timestamp is None: - return None - - timestamp, nanoseconds = divmod( - self._timestamp, definitions.NANOSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{nanoseconds:09d}') - - def CopyToDateTimeString(self): - """Copies the POSIX timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or - None if the timestamp is missing or invalid. - """ - return self._CopyToDateTimeString() + _EPOCH = PosixTimeEpoch() + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a POSIX timestamp in nanoseconds. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): POSIX timestamp in nanoseconds. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_NANOSECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: POSIX timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._timestamp is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.NANOSECONDS_PER_SECOND + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def _CopyFromDateTimeString(self, time_string): + """Copies a POSIX timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp *= definitions.NANOSECONDS_PER_SECOND + timestamp += nanoseconds + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyFromDateTimeString(self, time_string): + """Copies a POSIX timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + self._CopyFromDateTimeString(time_string) + + def _CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or + None if the timestamp is missing or invalid. + """ + if self._timestamp is None: + return None + + timestamp, nanoseconds = divmod( + self._timestamp, definitions.NANOSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{nanoseconds:09d}" + ) + + def CopyToDateTimeString(self): + """Copies the POSIX timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or + None if the timestamp is missing or invalid. + """ + return self._CopyToDateTimeString() factory.Factory.RegisterDateTimeValues(PosixTime) diff --git a/dfdatetime/precisions.py b/dfdatetime/precisions.py index 99f14d6..e437cb8 100644 --- a/dfdatetime/precisions.py +++ b/dfdatetime/precisions.py @@ -6,396 +6,420 @@ class DateTimePrecisionHelper: - """Date time precision helper interface. + """Date time precision helper interface. - This is the super class of different date and time precision helpers. + This is the super class of different date and time precision helpers. - Time precision helpers provide functionality for converting date and time - values between different precisions. - """ - - # pylint: disable=missing-raises-doc,redundant-returns-doc - - @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.0 and - 1.0. - """ - raise NotImplementedError() - - @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.0 and 1.0. - - Returns: - str: date and time value formatted as: YYYY-MM-DD hh:mm:ss with fraction - of second part that corresponds to the precision. + Time precision helpers provide functionality for converting date and time + values between different precisions. """ - raise NotImplementedError() - -class SecondsPrecisionHelper(DateTimePrecisionHelper): - """Seconds 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.0 and - 1.0. For the seconds precision helper this will always be 0.0. - - 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.') + # pylint: disable=missing-raises-doc,redundant-returns-doc - return decimal.Decimal(0.0) + @classmethod + def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): + """Copies the number of nanoseconds to a fraction of second value. - @classmethod - def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): - """Copies the time elements and fraction of second to a string. + Args: + nanoseconds (int): number of nanoseconds. - 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.0 and 1.0. + Returns: + decimal.Decimal: fraction of second, which must be a value between 0.0 and + 1.0. + """ + raise NotImplementedError() - Returns: - str: date and time value formatted as: - YYYY-MM-DD hh:mm:ss + @classmethod + def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): + """Copies the time elements and fraction of second to a string. - Raises: - ValueError: if the fraction of second is out of bounds. - """ - 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.') + 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.0 and 1.0. - year, month, day_of_month, hours, minutes, seconds = time_elements_tuple + Returns: + str: date and time value formatted as: YYYY-MM-DD hh:mm:ss with fraction + of second part that corresponds to the precision. + """ + raise NotImplementedError() - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') +class SecondsPrecisionHelper(DateTimePrecisionHelper): + """Seconds precision helper.""" -class CentisecondsPrecisionHelper(DateTimePrecisionHelper): - """Centiseconds (10 ms) precision helper.""" + @classmethod + def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): + """Copies the number of nanoseconds to a fraction of second value. - @classmethod - def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): - """Copies the number of nanoseconds to a fraction of second value. + Args: + nanoseconds (int): number of nanoseconds. - Args: - nanoseconds (int): number of nanoseconds. + Returns: + decimal.Decimal: fraction of second, which must be a value between 0.0 and + 1.0. For the seconds precision helper this will always be 0.0. - Returns: - 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. + """ + if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: + raise ValueError( + f"Number of nanoseconds value: {nanoseconds:d} out of bounds." + ) - 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.0 and 1.0. - - 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.0 or fraction_of_second >= 1.0: - raise ValueError( - f'Fraction of second value: {fraction_of_second:f} out of bounds.') + return decimal.Decimal(0.0) - year, month, day_of_month, hours, minutes, seconds = time_elements_tuple - centiseconds = int(fraction_of_second * 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. - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{centiseconds:02d}') + 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.0 and 1.0. + Returns: + str: date and time value formatted as: + YYYY-MM-DD hh:mm:ss -class MillisecondsPrecisionHelper(DateTimePrecisionHelper): - """Milliseconds precision helper.""" + Raises: + ValueError: if the fraction of second is out of bounds. + """ + 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." + ) - @classmethod - def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): - """Copies the number of nanoseconds to a fraction of second value. + year, month, day_of_month, hours, minutes, seconds = time_elements_tuple - Args: - nanoseconds (int): number of nanoseconds. + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) - Returns: - 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. - """ - if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: - raise ValueError( - f'Number of nanoseconds value: {nanoseconds:d} out of bounds.') - - milliseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) - return decimal.Decimal(milliseconds) / definitions.MILLISECONDS_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.0 and 1.0. - - 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.0 or fraction_of_second >= 1.0: - raise ValueError( - f'Fraction of second value: {fraction_of_second:f} out of bounds.') +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.0 and + 1.0. + + 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.0 and 1.0. + + 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.0 or fraction_of_second >= 1.0: + 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}" + ) - year, month, day_of_month, hours, minutes, seconds = time_elements_tuple - milliseconds = int(fraction_of_second * definitions.MILLISECONDS_PER_SECOND) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}') +class MillisecondsPrecisionHelper(DateTimePrecisionHelper): + """Milliseconds 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.0 and + 1.0. + + 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." + ) + + milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) + return decimal.Decimal(milliseconds) / definitions.MILLISECONDS_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.0 and 1.0. + + 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.0 or fraction_of_second >= 1.0: + 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 + milliseconds = int(fraction_of_second * definitions.MILLISECONDS_PER_SECOND) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + 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.0 - and 1.0. - - 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.0 and 1.0. - - 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.0 or fraction_of_second >= 1.0: - 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}') + """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.0 + and 1.0. + + 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.0 and 1.0. + + 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.0 or fraction_of_second >= 1.0: + 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.""" - - @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.0 and - 1.0. - - 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.') - - microseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) - return decimal.Decimal(microseconds) / definitions.MICROSECONDS_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.0 and 1.0. - - 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.0 or fraction_of_second >= 1.0: - 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 - microseconds = int(fraction_of_second * definitions.MICROSECONDS_PER_SECOND) - - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + """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.0 and + 1.0. + + 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." + ) + + microseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) + return decimal.Decimal(microseconds) / definitions.MICROSECONDS_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.0 and 1.0. + + 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.0 or fraction_of_second >= 1.0: + 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 + microseconds = int(fraction_of_second * definitions.MICROSECONDS_PER_SECOND) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) class NanosecondsPrecisionHelper(DateTimePrecisionHelper): - """Nanoseconds precision helper.""" + """Nanoseconds precision helper.""" - @classmethod - def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): - """Copies the number of nanoseconds to a fraction of second value. + @classmethod + def CopyNanosecondsToFractionOfSecond(cls, nanoseconds): + """Copies the number of nanoseconds to a fraction of second value. - Args: - nanoseconds (int): number of nanoseconds. + Args: + nanoseconds (int): number of nanoseconds. - Returns: - decimal.Decimal: fraction of second, which must be a value between 0.0 and - 1.0. + Returns: + 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. - """ - if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: - raise ValueError( - f'Number of nanoseconds value: {nanoseconds:d} out of bounds.') + 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." + ) - return decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND + return decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND - @classmethod - def CopyToDateTimeString(cls, time_elements_tuple, fraction_of_second): - """Copies the time elements and fraction of second to a string. + @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.0 and 1.0. + 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.0 and 1.0. - Returns: - str: date and time value formatted as: - YYYY-MM-DD hh:mm:ss.###### + 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.0 or fraction_of_second >= 1.0: - raise ValueError( - f'Fraction of second value: {fraction_of_second:f} out of bounds.') + Raises: + ValueError: if the fraction of second is out of bounds. + """ + 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." + ) - year, month, day_of_month, hours, minutes, seconds = time_elements_tuple - nanoseconds = int(fraction_of_second * definitions.NANOSECONDS_PER_SECOND) + year, month, day_of_month, hours, minutes, seconds = time_elements_tuple + nanoseconds = int(fraction_of_second * definitions.NANOSECONDS_PER_SECOND) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{nanoseconds:09d}') + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{nanoseconds:09d}" + ) class PrecisionHelperFactory: - """Date time precision helper factory.""" - - _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, - definitions.PRECISION_1_SECOND: SecondsPrecisionHelper} - - @classmethod - def CreatePrecisionHelper(cls, precision): - """Creates a precision helper. - - Args: - precision (str): precision of the date and time value, which should - be one of the PRECISION_VALUES in definitions. - - Returns: - class: date time precision helper class. - - Raises: - ValueError: if the precision value is unsupported. - """ - precision_helper_class = cls._PRECISION_CLASSES.get(precision) - if not precision_helper_class: - raise ValueError(f'Unsupported precision: {precision!s}') - - return precision_helper_class + """Date time precision helper factory.""" + + _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, + definitions.PRECISION_1_SECOND: SecondsPrecisionHelper, + } + + @classmethod + def CreatePrecisionHelper(cls, precision): + """Creates a precision helper. + + Args: + precision (str): precision of the date and time value, which should + be one of the PRECISION_VALUES in definitions. + + Returns: + class: date time precision helper class. + + Raises: + ValueError: if the precision value is unsupported. + """ + precision_helper_class = cls._PRECISION_CLASSES.get(precision) + if not precision_helper_class: + raise ValueError(f"Unsupported precision: {precision!s}") + + return precision_helper_class diff --git a/dfdatetime/rfc2579_date_time.py b/dfdatetime/rfc2579_date_time.py index fc60a4e..2af1535 100644 --- a/dfdatetime/rfc2579_date_time.py +++ b/dfdatetime/rfc2579_date_time.py @@ -8,240 +8,252 @@ class RFC2579DateTime(interface.DateTimeValues): - """RFC2579 date-time. - - The RFC2579 date-time structure is 11 bytes of size and contains: - - struct { - uin16_t year, - uint8_t month, - uint8_t day_of_month, - uint8_t hours, - uint8_t minutes, - uint8_t seconds, - uint8_t deciseconds, - char direction_from_utc, - uint8_t hours_from_utc, - uint8_t minutes_from_utc - } - - Also see: - https://datatracker.ietf.org/doc/html/rfc2579 - - Attributes: - year (int): year, 0 through 65536. - month (int): month of year, 1 through 12. - day_of_month (int): day of month, 1 through 31. - hours (int): hours, 0 through 23. - minutes (int): minutes, 0 through 59. - seconds (int): seconds, 0 through 59, where 60 is used to represent - a leap-second. - deciseconds (int): deciseconds, 0 through 9. - """ - - # TODO: make attributes read-only. - - # pylint: disable=missing-type-doc - - def __init__(self, precision=None, rfc2579_date_time_tuple=None): - """Initializes a RFC2579 date-time. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - rfc2579_date_time_tuple: - (Optional[tuple[int, int, int, int, int, int, int, str, int, int]]): - RFC2579 date-time time, contains year, month, day of month, hours, - minutes, seconds and deciseconds, and time zone offset in hours and - minutes from UTC. - - Raises: - ValueError: if the system time is invalid. + """RFC2579 date-time. + + The RFC2579 date-time structure is 11 bytes of size and contains: + + struct { + uin16_t year, + uint8_t month, + uint8_t day_of_month, + uint8_t hours, + uint8_t minutes, + uint8_t seconds, + uint8_t deciseconds, + char direction_from_utc, + uint8_t hours_from_utc, + uint8_t minutes_from_utc + } + + Also see: + https://datatracker.ietf.org/doc/html/rfc2579 + + Attributes: + year (int): year, 0 through 65536. + month (int): month of year, 1 through 12. + day_of_month (int): day of month, 1 through 31. + hours (int): hours, 0 through 23. + minutes (int): minutes, 0 through 59. + seconds (int): seconds, 0 through 59, where 60 is used to represent + a leap-second. + deciseconds (int): deciseconds, 0 through 9. """ - super().__init__( - precision=precision or definitions.PRECISION_100_MILLISECONDS) - self._day_of_month = None - self._deciseconds = None - self._hours = None - self._minutes = None - self._month = None - self._number_of_seconds = None - self._seconds = None - self._year = None - - if rfc2579_date_time_tuple: - if len(rfc2579_date_time_tuple) < 10: - raise ValueError( - 'Invalid RFC2579 date-time tuple 10 elements required.') - - if rfc2579_date_time_tuple[0] < 0 or rfc2579_date_time_tuple[0] > 65536: - raise ValueError('Year value out of bounds.') - - if rfc2579_date_time_tuple[1] not in range(1, 13): - raise ValueError('Month value out of bounds.') - - days_per_month = self._GetDaysPerMonth( - rfc2579_date_time_tuple[0], rfc2579_date_time_tuple[1]) - if (rfc2579_date_time_tuple[2] < 1 or - rfc2579_date_time_tuple[2] > days_per_month): - raise ValueError('Day of month value out of bounds.') - - if rfc2579_date_time_tuple[3] not in range(0, 24): - raise ValueError('Hours value out of bounds.') - - if rfc2579_date_time_tuple[4] not in range(0, 60): - raise ValueError('Minutes value out of bounds.') - - # TODO: support a leap second? - if rfc2579_date_time_tuple[5] not in range(0, 60): - raise ValueError('Seconds value out of bounds.') - - if rfc2579_date_time_tuple[6] < 0 or rfc2579_date_time_tuple[6] > 9: - raise ValueError('Deciseconds value out of bounds.') - - if rfc2579_date_time_tuple[7] not in ('+', '-'): - raise ValueError('Direction from UTC value out of bounds.') - - if rfc2579_date_time_tuple[8] not in range(0, 14): - raise ValueError('Hours from UTC value out of bounds.') - - if rfc2579_date_time_tuple[9] not in range(0, 60): - raise ValueError('Minutes from UTC value out of bounds.') - - time_zone_offset = ( - (rfc2579_date_time_tuple[8] * 60) + rfc2579_date_time_tuple[9]) - - if rfc2579_date_time_tuple[7] == '-': - time_zone_offset = -time_zone_offset - - self._time_zone_offset = time_zone_offset - - self._year = rfc2579_date_time_tuple[0] - self._month = rfc2579_date_time_tuple[1] - self._day_of_month = rfc2579_date_time_tuple[2] - self._hours = rfc2579_date_time_tuple[3] - self._minutes = rfc2579_date_time_tuple[4] - self._seconds = rfc2579_date_time_tuple[5] - self._deciseconds = rfc2579_date_time_tuple[6] - - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - self._year, self._month, self._day_of_month, self._hours, - self._minutes, self._seconds) - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._number_of_seconds is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._deciseconds) / - definitions.DECISECONDS_PER_SECOND) - self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - @property - def deciseconds(self): - """int: number of deciseconds or None if not set.""" - return self._deciseconds - - @property - def day_of_month(self): - """int: day of month or None if not set.""" - return self._day_of_month - - @property - def hours(self): - """int: number of hours or None if not set.""" - return self._hours - - @property - def minutes(self): - """int: number of minutes or None if not set.""" - return self._minutes - - @property - def month(self): - """int: month or None if not set.""" - return self._month - - @property - def seconds(self): - """int: number of seconds or None if not set.""" - return self._seconds - - @property - def year(self): - """int: year or None if not set.""" - return self._year - - def CopyFromDateTimeString(self, time_string): - """Copies a RFC2579 date-time from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the date string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - deciseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_DECISECOND) - - if year < 0 or year > 65536: - raise ValueError(f'Unsupported year value: {year:d}.') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_zone_offset = time_zone_offset - - self._year = year - self._month = month - self._day_of_month = day_of_month - self._hours = hours - self._minutes = minutes - self._seconds = seconds - self._deciseconds = deciseconds - - def CopyToDateTimeString(self): - """Copies the RFC2579 date-time to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#" or - None if the number of seconds is missing. - """ - if self._number_of_seconds is None: - return None - return (f'{self._year:04d}-{self._month:02d}-{self._day_of_month:02d} ' - f'{self._hours:02d}:{self._minutes:02d}:{self._seconds:02d}' - f'.{self._deciseconds:01d}') + # TODO: make attributes read-only. + + # pylint: disable=missing-type-doc + + def __init__(self, precision=None, rfc2579_date_time_tuple=None): + """Initializes a RFC2579 date-time. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + rfc2579_date_time_tuple: + (Optional[tuple[int, int, int, int, int, int, int, str, int, int]]): + RFC2579 date-time time, contains year, month, day of month, hours, + minutes, seconds and deciseconds, and time zone offset in hours and + minutes from UTC. + + Raises: + ValueError: if the system time is invalid. + """ + super().__init__(precision=precision or definitions.PRECISION_100_MILLISECONDS) + self._day_of_month = None + self._deciseconds = None + self._hours = None + self._minutes = None + self._month = None + self._number_of_seconds = None + self._seconds = None + self._year = None + + if rfc2579_date_time_tuple: + if len(rfc2579_date_time_tuple) < 10: + raise ValueError( + "Invalid RFC2579 date-time tuple 10 elements required." + ) + + if rfc2579_date_time_tuple[0] < 0 or rfc2579_date_time_tuple[0] > 65536: + raise ValueError("Year value out of bounds.") + + if rfc2579_date_time_tuple[1] not in range(1, 13): + raise ValueError("Month value out of bounds.") + + days_per_month = self._GetDaysPerMonth( + rfc2579_date_time_tuple[0], rfc2579_date_time_tuple[1] + ) + if ( + rfc2579_date_time_tuple[2] < 1 + or rfc2579_date_time_tuple[2] > days_per_month + ): + raise ValueError("Day of month value out of bounds.") + + if rfc2579_date_time_tuple[3] not in range(0, 24): + raise ValueError("Hours value out of bounds.") + + if rfc2579_date_time_tuple[4] not in range(0, 60): + raise ValueError("Minutes value out of bounds.") + + # TODO: support a leap second? + if rfc2579_date_time_tuple[5] not in range(0, 60): + raise ValueError("Seconds value out of bounds.") + + if rfc2579_date_time_tuple[6] < 0 or rfc2579_date_time_tuple[6] > 9: + raise ValueError("Deciseconds value out of bounds.") + + if rfc2579_date_time_tuple[7] not in ("+", "-"): + raise ValueError("Direction from UTC value out of bounds.") + + if rfc2579_date_time_tuple[8] not in range(0, 14): + raise ValueError("Hours from UTC value out of bounds.") + + if rfc2579_date_time_tuple[9] not in range(0, 60): + raise ValueError("Minutes from UTC value out of bounds.") + + time_zone_offset = ( + rfc2579_date_time_tuple[8] * 60 + ) + rfc2579_date_time_tuple[9] + + if rfc2579_date_time_tuple[7] == "-": + time_zone_offset = -time_zone_offset + + self._time_zone_offset = time_zone_offset + + self._year = rfc2579_date_time_tuple[0] + self._month = rfc2579_date_time_tuple[1] + self._day_of_month = rfc2579_date_time_tuple[2] + self._hours = rfc2579_date_time_tuple[3] + self._minutes = rfc2579_date_time_tuple[4] + self._seconds = rfc2579_date_time_tuple[5] + self._deciseconds = rfc2579_date_time_tuple[6] + + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + self._year, + self._month, + self._day_of_month, + self._hours, + self._minutes, + self._seconds, + ) + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._number_of_seconds is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._deciseconds) + / definitions.DECISECONDS_PER_SECOND + ) + self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + @property + def deciseconds(self): + """int: number of deciseconds or None if not set.""" + return self._deciseconds + + @property + def day_of_month(self): + """int: day of month or None if not set.""" + return self._day_of_month + + @property + def hours(self): + """int: number of hours or None if not set.""" + return self._hours + + @property + def minutes(self): + """int: number of minutes or None if not set.""" + return self._minutes + + @property + def month(self): + """int: month or None if not set.""" + return self._month + + @property + def seconds(self): + """int: number of seconds or None if not set.""" + return self._seconds + + @property + def year(self): + """int: year or None if not set.""" + return self._year + + def CopyFromDateTimeString(self, time_string): + """Copies a RFC2579 date-time from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the date string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + deciseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_DECISECOND) + + if year < 0 or year > 65536: + raise ValueError(f"Unsupported year value: {year:d}.") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_zone_offset = time_zone_offset + + self._year = year + self._month = month + self._day_of_month = day_of_month + self._hours = hours + self._minutes = minutes + self._seconds = seconds + self._deciseconds = deciseconds + + def CopyToDateTimeString(self): + """Copies the RFC2579 date-time to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#" or + None if the number of seconds is missing. + """ + if self._number_of_seconds is None: + return None + + return ( + f"{self._year:04d}-{self._month:02d}-{self._day_of_month:02d} " + f"{self._hours:02d}:{self._minutes:02d}:{self._seconds:02d}" + f".{self._deciseconds:01d}" + ) factory.Factory.RegisterDateTimeValues(RFC2579DateTime) diff --git a/dfdatetime/semantic_time.py b/dfdatetime/semantic_time.py index 0f9b0aa..3f39e1d 100644 --- a/dfdatetime/semantic_time.py +++ b/dfdatetime/semantic_time.py @@ -5,310 +5,310 @@ class SemanticTime(interface.DateTimeValues): - """Semantic time. + """Semantic time. - Semantic time is term to describe date and time values that have specific - meaning such as: "Never", "Yesterday", "Not set". + Semantic time is term to describe date and time values that have specific + meaning such as: "Never", "Yesterday", "Not set". - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ + Attributes: + is_local_time (bool): True if the date and time value is in local time. + """ - # pylint: disable=redundant-returns-doc + # pylint: disable=redundant-returns-doc - _SORT_ORDER = 50 + _SORT_ORDER = 50 - def __init__(self, string=None): - """Initializes a semantic time. + def __init__(self, string=None): + """Initializes a semantic time. - Args: - string (str): semantic representation of the time, such as: - "Never", "Not set". - """ - super().__init__() - self._string = string + Args: + string (str): semantic representation of the time, such as: + "Never", "Not set". + """ + super().__init__() + self._string = string - @property - def string(self): - """str: semantic representation of the time, such as: "Never".""" - return self._string + @property + def string(self): + """str: semantic representation of the time, such as: "Never".""" + return self._string - def __eq__(self, other): - """Determines if the date time values are equal to other. + def __eq__(self, other): + """Determines if the date time values are equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are equal to other. - """ - if not isinstance(other, SemanticTime): - return False + Returns: + bool: True if the date time values are equal to other. + """ + if not isinstance(other, SemanticTime): + return False - return self._SORT_ORDER == other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER == other._SORT_ORDER # pylint: disable=protected-access - def __ge__(self, other): - """Determines if the date time values are greater than or equal to other. + def __ge__(self, other): + """Determines if the date time values are greater than or equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than or equal to other. + Returns: + bool: True if the date time values are greater than or equal to other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - if not isinstance(other, SemanticTime): - return False + if not isinstance(other, SemanticTime): + return False - return self._SORT_ORDER >= other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER >= other._SORT_ORDER # pylint: disable=protected-access - def __gt__(self, other): - """Determines if the date time values are greater than other. + def __gt__(self, other): + """Determines if the date time values are greater than other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than other. + Returns: + bool: True if the date time values are greater than other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - if not isinstance(other, SemanticTime): - return False + if not isinstance(other, SemanticTime): + return False - return self._SORT_ORDER > other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER > other._SORT_ORDER # pylint: disable=protected-access - def __le__(self, other): - """Determines if the date time values are greater than or equal to other. + def __le__(self, other): + """Determines if the date time values are greater than or equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than or equal to other. + Returns: + bool: True if the date time values are greater than or equal to other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - if not isinstance(other, SemanticTime): - return True + if not isinstance(other, SemanticTime): + return True - return self._SORT_ORDER <= other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER <= other._SORT_ORDER # pylint: disable=protected-access - def __lt__(self, other): - """Determines if the date time values are less than other. + def __lt__(self, other): + """Determines if the date time values are less than other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are less than other. + Returns: + bool: True if the date time values are less than other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - if not isinstance(other, SemanticTime): - return True + if not isinstance(other, SemanticTime): + return True - return self._SORT_ORDER < other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER < other._SORT_ORDER # pylint: disable=protected-access - def __ne__(self, other): - """Determines if the date time values are not equal to other. + def __ne__(self, other): + """Determines if the date time values are not equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are not equal to other. - """ - if not isinstance(other, SemanticTime): - return True + Returns: + bool: True if the date time values are not equal to other. + """ + if not isinstance(other, SemanticTime): + return True - return self._SORT_ORDER != other._SORT_ORDER # pylint: disable=protected-access + return self._SORT_ORDER != other._SORT_ORDER # pylint: disable=protected-access - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - return None + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + return None - def CopyFromDateTimeString(self, time_string): - """Copies semantic time from a date and time string. + def CopyFromDateTimeString(self, time_string): + """Copies semantic time from a date and time string. - Args: - time_string (str): semantic representation of the time, such as: - "Never", "Not set". + Args: + time_string (str): semantic representation of the time, such as: + "Never", "Not set". - Raises: - ValueError: because semantic time cannot be copied from a string. - """ - self._string = time_string + Raises: + ValueError: because semantic time cannot be copied from a string. + """ + self._string = time_string - def CopyToDateTimeString(self): - """Copies the date time value to a date and time string. + def CopyToDateTimeString(self): + """Copies the date time value to a date and time string. - Returns: - str: semantic representation of the time, such as: "Never", "Not set". - """ - return self._string + Returns: + str: semantic representation of the time, such as: "Never", "Not set". + """ + return self._string - def CopyToDateTimeStringISO8601(self): - """Copies the date time value to an ISO 8601 date and time string. + def CopyToDateTimeStringISO8601(self): + """Copies the date time value to an ISO 8601 date and time string. - Returns: - str: date and time value formatted as an ISO 8601 date and time string, - which always be None since semantic time cannot be represented in - ISO 8601. - """ - return None + Returns: + str: date and time value formatted as an ISO 8601 date and time string, + which always be None since semantic time cannot be represented in + ISO 8601. + """ + return None - def GetPlasoTimestamp(self): - """Retrieves a timestamp that is compatible with plaso. + def GetPlasoTimestamp(self): + """Retrieves a timestamp that is compatible with plaso. - Returns: - int: a POSIX timestamp in microseconds, which will always be 0. - """ - return 0 + Returns: + int: a POSIX timestamp in microseconds, which will always be 0. + """ + return 0 class InvalidTime(SemanticTime): - """Semantic time that represents invalid.""" + """Semantic time that represents invalid.""" - _SORT_ORDER = 1 + _SORT_ORDER = 1 - def __init__(self): - """Initializes a semantic time that represents invalid.""" - super().__init__(string='Invalid') + def __init__(self): + """Initializes a semantic time that represents invalid.""" + super().__init__(string="Invalid") class Never(SemanticTime): - """Semantic time that represents never.""" + """Semantic time that represents never.""" - _SORT_ORDER = 99 + _SORT_ORDER = 99 - def __init__(self): - """Initializes a semantic time that represents never.""" - super().__init__(string='Never') + def __init__(self): + """Initializes a semantic time that represents never.""" + super().__init__(string="Never") - def __eq__(self, other): - """Determines if the date time values are equal to other. + def __eq__(self, other): + """Determines if the date time values are equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are equal to other. - """ - return isinstance(other, Never) + Returns: + bool: True if the date time values are equal to other. + """ + return isinstance(other, Never) - def __ge__(self, other): - """Determines if the date time values are greater than or equal to other. + def __ge__(self, other): + """Determines if the date time values are greater than or equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than or equal to other. + Returns: + bool: True if the date time values are greater than or equal to other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - return True + return True - def __gt__(self, other): - """Determines if the date time values are greater than other. + def __gt__(self, other): + """Determines if the date time values are greater than other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than other. + Returns: + bool: True if the date time values are greater than other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - return not isinstance(other, Never) + return not isinstance(other, Never) - def __le__(self, other): - """Determines if the date time values are less than or equal to other. + def __le__(self, other): + """Determines if the date time values are less than or equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are greater than or equal to other. + Returns: + bool: True if the date time values are greater than or equal to other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - return isinstance(other, Never) + return isinstance(other, Never) - def __lt__(self, other): - """Determines if the date time values are less than other. + def __lt__(self, other): + """Determines if the date time values are less than other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are less than other. + Returns: + bool: True if the date time values are less than other. - Raises: - ValueError: if other is not an instance of DateTimeValues. - """ - if not isinstance(other, interface.DateTimeValues): - raise ValueError('Other not an instance of DateTimeValues') + Raises: + ValueError: if other is not an instance of DateTimeValues. + """ + if not isinstance(other, interface.DateTimeValues): + raise ValueError("Other not an instance of DateTimeValues") - return False + return False - def __ne__(self, other): - """Determines if the date time values are not equal to other. + def __ne__(self, other): + """Determines if the date time values are not equal to other. - Args: - other (DateTimeValues): date time values to compare against. + Args: + other (DateTimeValues): date time values to compare against. - Returns: - bool: True if the date time values are not equal to other. - """ - return not isinstance(other, Never) + Returns: + bool: True if the date time values are not equal to other. + """ + return not isinstance(other, Never) class NotSet(SemanticTime): - """Semantic time that represents not set.""" + """Semantic time that represents not set.""" - _SORT_ORDER = 2 + _SORT_ORDER = 2 - def __init__(self): - """Initializes a semantic time that represents not set.""" - super().__init__(string='Not set') + def __init__(self): + """Initializes a semantic time that represents not set.""" + super().__init__(string="Not set") factory.Factory.RegisterDateTimeValues(SemanticTime) diff --git a/dfdatetime/serializer.py b/dfdatetime/serializer.py index 3950016..8efd624 100644 --- a/dfdatetime/serializer.py +++ b/dfdatetime/serializer.py @@ -5,223 +5,251 @@ class Serializer: - """Date and time values serializer.""" + """Date and time values serializer.""" - @classmethod - def ConvertDictToDateTimeValues(cls, json_dict): - """Converts a JSON dict into a date time values object. + @classmethod + def ConvertDictToDateTimeValues(cls, json_dict): + """Converts a JSON dict into a date time values object. - This method is deprecated use ConvertJSONToDateTimeValues instead. + This method is deprecated use ConvertJSONToDateTimeValues instead. - The dictionary of the JSON serialized objects consists of: - { - '__type__': 'DateTimeValues' - '__class_name__': 'RFC2579DateTime' - ... - } - - Here '__type__' indicates the object base type. In this case this should - be 'DateTimeValues'. The rest of the elements of the dictionary make up the - date time values object properties. - - Args: - json_dict (dict[str, object]): JSON serialized objects. - - Returns: - dfdatetime.DateTimeValues: date and time values. - """ - return cls.ConvertJSONToDateTimeValues(json_dict) - - @classmethod - def ConvertDateTimeValuesToDict(cls, date_time_values): - """Converts a date and time values object into a JSON dictionary. - - This method is deprecated use ConvertDateTimeValuesToJSON instead. - - The resulting dictionary of the JSON serialized objects consists of: - { - '__type__': 'DateTimeValues' - '__class_name__': 'RFC2579DateTime' - ... - } - - Here '__type__' indicates the object base type. In this case - 'DateTimeValues'. The rest of the elements of the dictionary make up the - date and time value object properties. - - Args: - date_time_values (dfdatetime.DateTimeValues): date and time values. - - Returns: - dict[str, object]: JSON serialized objects. - - Raises: - TypeError: if object is not an instance of DateTimeValues. - """ - if not isinstance(date_time_values, interface.DateTimeValues): - raise TypeError - - return cls.ConvertDateTimeValuesToJSON(date_time_values) - - @classmethod - def ConvertDateTimeValuesToJSON(cls, date_time_values): - """Converts a date and time values object into a JSON dictionary. - - The resulting dictionary of the JSON serialized objects consists of: - { - '__type__': 'DateTimeValues' - '__class_name__': 'RFC2579DateTime' - ... - } - - Here '__type__' indicates the object base type. In this case - 'DateTimeValues'. The rest of the elements of the dictionary make up the - date and time value object properties. - - Args: - date_time_values (dfdatetime.DateTimeValues): date and time values. - - Returns: - dict[str, object]: JSON serialized objects. - """ - class_name = type(date_time_values).__name__ - - json_dict = { - '__class_name__': class_name, - '__type__': 'DateTimeValues'} - - if hasattr(date_time_values, 'timestamp'): - json_dict['timestamp'] = date_time_values.timestamp - - elif hasattr(date_time_values, 'string'): - json_dict['string'] = date_time_values.string - - elif class_name == 'FATDateTime': - json_dict['fat_date_time'] = date_time_values.fat_date_time - - elif class_name == 'GolangTime': - json_dict['golang_timestamp'] = date_time_values.golang_timestamp - - elif class_name == 'RFC2579DateTime': - time_zone_hours, time_zone_minutes = divmod( - date_time_values.time_zone_offset, 60) - - if date_time_values.time_zone_offset < 0: - time_zone_sign = '-' - time_zone_hours *= -1 - else: - time_zone_sign = '+' - - json_dict['rfc2579_date_time_tuple'] = ( - date_time_values.year, date_time_values.month, - date_time_values.day_of_month, date_time_values.hours, - date_time_values.minutes, date_time_values.seconds, - date_time_values.deciseconds, time_zone_sign, time_zone_hours, - time_zone_minutes) - - elif class_name == 'Systemtime': - json_dict['system_time_tuple'] = ( - date_time_values.year, date_time_values.month, - date_time_values.day_of_week, date_time_values.day_of_month, - date_time_values.hours, date_time_values.minutes, - date_time_values.seconds, date_time_values.milliseconds) - - elif class_name == 'TimeElements': - json_dict['time_elements_tuple'] = ( - date_time_values.year, date_time_values.month, - date_time_values.day_of_month, date_time_values.hours, - date_time_values.minutes, date_time_values.seconds) - - elif class_name == 'TimeElementsInMilliseconds': - json_dict['time_elements_tuple'] = ( - date_time_values.year, date_time_values.month, - date_time_values.day_of_month, date_time_values.hours, - date_time_values.minutes, date_time_values.seconds, - date_time_values.milliseconds) - - elif class_name == 'TimeElementsInMicroseconds': - json_dict['time_elements_tuple'] = ( - date_time_values.year, date_time_values.month, - date_time_values.day_of_month, date_time_values.hours, - date_time_values.minutes, date_time_values.seconds, - date_time_values.microseconds) - - if date_time_values.time_zone_offset is not None and class_name not in ( - 'GolangTime', 'RFC2579DateTime'): - json_dict['time_zone_offset'] = date_time_values.time_zone_offset - - if date_time_values.is_delta and class_name in ( - 'TimeElements', 'TimeElementsInMilliseconds', - 'TimeElementsInMicroseconds'): - json_dict['is_delta'] = True - - if date_time_values.is_local_time: - json_dict['is_local_time'] = True - if date_time_values.time_zone_hint: - json_dict['time_zone_hint'] = date_time_values.time_zone_hint - - return json_dict - - @classmethod - def ConvertJSONToDateTimeValues(cls, json_dict): - """Converts a JSON dict into a date time values object. - - The dictionary of the JSON serialized objects consists of: - { - '__type__': 'DateTimeValues' - '__class_name__': 'RFC2579DateTime' - ... - } - - Here '__type__' indicates the object base type. In this case this should - be 'DateTimeValues'. The rest of the elements of the dictionary make up the - date time values object properties. - - Args: - json_dict (dict[str, object]): JSON serialized objects. - - Returns: - dfdatetime.DateTimeValues: date and time values. - - Raises: - KeyError: If date and time values type is not supported by factory. - """ - class_name = json_dict.get('__class_name__') - if class_name: - del json_dict['__class_name__'] - - # Remove the class type from the JSON dict since we cannot pass it. - del json_dict['__type__'] - - if class_name not in ( - 'TimeElements', 'TimeElementsInMilliseconds', - 'TimeElementsInMicroseconds'): - is_delta = json_dict.get('is_delta') - if is_delta is not None: - del json_dict['is_delta'] - - is_local_time = json_dict.get('is_local_time') - if is_local_time is not None: - del json_dict['is_local_time'] - - time_zone_hint = json_dict.get('time_zone_hint') - if time_zone_hint is not None: - del json_dict['time_zone_hint'] - - if class_name in ('InvalidTime', 'Never', 'NotSet'): - string = json_dict.get('string') - if string is not None: - del json_dict['string'] - - if class_name in ('GolangTime', 'RFC2579DateTime'): - time_zone_offset = json_dict.get('time_zone_offset') - if time_zone_offset is not None: - del json_dict['time_zone_offset'] - - date_time = factory.Factory.NewDateTimeValues(class_name, **json_dict) - if is_local_time: - date_time.is_local_time = is_local_time - if time_zone_hint: - date_time.time_zone_hint = time_zone_hint - - return date_time + The dictionary of the JSON serialized objects consists of: + { + '__type__': 'DateTimeValues' + '__class_name__': 'RFC2579DateTime' + ... + } + + Here '__type__' indicates the object base type. In this case this should + be 'DateTimeValues'. The rest of the elements of the dictionary make up the + date time values object properties. + + Args: + json_dict (dict[str, object]): JSON serialized objects. + + Returns: + dfdatetime.DateTimeValues: date and time values. + """ + return cls.ConvertJSONToDateTimeValues(json_dict) + + @classmethod + def ConvertDateTimeValuesToDict(cls, date_time_values): + """Converts a date and time values object into a JSON dictionary. + + This method is deprecated use ConvertDateTimeValuesToJSON instead. + + The resulting dictionary of the JSON serialized objects consists of: + { + '__type__': 'DateTimeValues' + '__class_name__': 'RFC2579DateTime' + ... + } + + Here '__type__' indicates the object base type. In this case + 'DateTimeValues'. The rest of the elements of the dictionary make up the + date and time value object properties. + + Args: + date_time_values (dfdatetime.DateTimeValues): date and time values. + + Returns: + dict[str, object]: JSON serialized objects. + + Raises: + TypeError: if object is not an instance of DateTimeValues. + """ + if not isinstance(date_time_values, interface.DateTimeValues): + raise TypeError + + return cls.ConvertDateTimeValuesToJSON(date_time_values) + + @classmethod + def ConvertDateTimeValuesToJSON(cls, date_time_values): + """Converts a date and time values object into a JSON dictionary. + + The resulting dictionary of the JSON serialized objects consists of: + { + '__type__': 'DateTimeValues' + '__class_name__': 'RFC2579DateTime' + ... + } + + Here '__type__' indicates the object base type. In this case + 'DateTimeValues'. The rest of the elements of the dictionary make up the + date and time value object properties. + + Args: + date_time_values (dfdatetime.DateTimeValues): date and time values. + + Returns: + dict[str, object]: JSON serialized objects. + """ + class_name = type(date_time_values).__name__ + + json_dict = {"__class_name__": class_name, "__type__": "DateTimeValues"} + + if hasattr(date_time_values, "timestamp"): + json_dict["timestamp"] = date_time_values.timestamp + + elif hasattr(date_time_values, "string"): + json_dict["string"] = date_time_values.string + + elif class_name == "FATDateTime": + json_dict["fat_date_time"] = date_time_values.fat_date_time + + elif class_name == "GolangTime": + json_dict["golang_timestamp"] = date_time_values.golang_timestamp + + elif class_name == "RFC2579DateTime": + time_zone_hours, time_zone_minutes = divmod( + date_time_values.time_zone_offset, 60 + ) + + if date_time_values.time_zone_offset < 0: + time_zone_sign = "-" + time_zone_hours *= -1 + else: + time_zone_sign = "+" + + json_dict["rfc2579_date_time_tuple"] = ( + date_time_values.year, + date_time_values.month, + date_time_values.day_of_month, + date_time_values.hours, + date_time_values.minutes, + date_time_values.seconds, + date_time_values.deciseconds, + time_zone_sign, + time_zone_hours, + time_zone_minutes, + ) + + elif class_name == "Systemtime": + json_dict["system_time_tuple"] = ( + date_time_values.year, + date_time_values.month, + date_time_values.day_of_week, + date_time_values.day_of_month, + date_time_values.hours, + date_time_values.minutes, + date_time_values.seconds, + date_time_values.milliseconds, + ) + + elif class_name == "TimeElements": + json_dict["time_elements_tuple"] = ( + date_time_values.year, + date_time_values.month, + date_time_values.day_of_month, + date_time_values.hours, + date_time_values.minutes, + date_time_values.seconds, + ) + + elif class_name == "TimeElementsInMilliseconds": + json_dict["time_elements_tuple"] = ( + date_time_values.year, + date_time_values.month, + date_time_values.day_of_month, + date_time_values.hours, + date_time_values.minutes, + date_time_values.seconds, + date_time_values.milliseconds, + ) + + elif class_name == "TimeElementsInMicroseconds": + json_dict["time_elements_tuple"] = ( + date_time_values.year, + date_time_values.month, + date_time_values.day_of_month, + date_time_values.hours, + date_time_values.minutes, + date_time_values.seconds, + date_time_values.microseconds, + ) + + if date_time_values.time_zone_offset is not None and class_name not in ( + "GolangTime", + "RFC2579DateTime", + ): + json_dict["time_zone_offset"] = date_time_values.time_zone_offset + + if date_time_values.is_delta and class_name in ( + "TimeElements", + "TimeElementsInMilliseconds", + "TimeElementsInMicroseconds", + ): + json_dict["is_delta"] = True + + if date_time_values.is_local_time: + json_dict["is_local_time"] = True + if date_time_values.time_zone_hint: + json_dict["time_zone_hint"] = date_time_values.time_zone_hint + + return json_dict + + @classmethod + def ConvertJSONToDateTimeValues(cls, json_dict): + """Converts a JSON dict into a date time values object. + + The dictionary of the JSON serialized objects consists of: + { + '__type__': 'DateTimeValues' + '__class_name__': 'RFC2579DateTime' + ... + } + + Here '__type__' indicates the object base type. In this case this should + be 'DateTimeValues'. The rest of the elements of the dictionary make up the + date time values object properties. + + Args: + json_dict (dict[str, object]): JSON serialized objects. + + Returns: + dfdatetime.DateTimeValues: date and time values. + + Raises: + KeyError: If date and time values type is not supported by factory. + """ + class_name = json_dict.get("__class_name__") + if class_name: + del json_dict["__class_name__"] + + # Remove the class type from the JSON dict since we cannot pass it. + del json_dict["__type__"] + + if class_name not in ( + "TimeElements", + "TimeElementsInMilliseconds", + "TimeElementsInMicroseconds", + ): + is_delta = json_dict.get("is_delta") + if is_delta is not None: + del json_dict["is_delta"] + + is_local_time = json_dict.get("is_local_time") + if is_local_time is not None: + del json_dict["is_local_time"] + + time_zone_hint = json_dict.get("time_zone_hint") + if time_zone_hint is not None: + del json_dict["time_zone_hint"] + + if class_name in ("InvalidTime", "Never", "NotSet"): + string = json_dict.get("string") + if string is not None: + del json_dict["string"] + + if class_name in ("GolangTime", "RFC2579DateTime"): + time_zone_offset = json_dict.get("time_zone_offset") + if time_zone_offset is not None: + del json_dict["time_zone_offset"] + + date_time = factory.Factory.NewDateTimeValues(class_name, **json_dict) + if is_local_time: + date_time.is_local_time = is_local_time + if time_zone_hint: + date_time.time_zone_hint = time_zone_hint + + return date_time diff --git a/dfdatetime/systemtime.py b/dfdatetime/systemtime.py index 80e372e..705c990 100644 --- a/dfdatetime/systemtime.py +++ b/dfdatetime/systemtime.py @@ -8,217 +8,226 @@ class Systemtime(interface.DateTimeValues): - """SYSTEMTIME structure. - - The SYSTEMTIME structure is 16 bytes of size and contains: - - struct { - WORD year, - WORD month, - WORD day_of_week, - WORD day_of_month, - WORD hour, - WORD minute, - WORD second, - WORD millisecond - } - """ - - def __init__( - self, precision=None, system_time_tuple=None, time_zone_offset=None): - """Initializes a SYSTEMTIME structure. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - system_time_tuple - (Optional[tuple[int, int, int, int, int, int, int, int]]): - system time, contains year, month, day of week, day of month, - hours, minutes, seconds and milliseconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the system time is invalid. + """SYSTEMTIME structure. + + The SYSTEMTIME structure is 16 bytes of size and contains: + + struct { + WORD year, + WORD month, + WORD day_of_week, + WORD day_of_month, + WORD hour, + WORD minute, + WORD second, + WORD millisecond + } """ - super().__init__( - precision=precision or definitions.PRECISION_1_MILLISECOND, - time_zone_offset=time_zone_offset) - self._number_of_seconds = None - self._day_of_month = None - self._day_of_week = None - self._hours = None - self._milliseconds = None - self._minutes = None - self._month = None - self._seconds = None - self._year = None - - if system_time_tuple: - if len(system_time_tuple) < 8: - raise ValueError('Invalid system time tuple 8 elements required.') - - if system_time_tuple[0] < 1601 or system_time_tuple[0] > 30827: - raise ValueError('Year value out of bounds.') - - if system_time_tuple[1] not in range(1, 13): - raise ValueError('Month value out of bounds.') - - if system_time_tuple[2] not in range(0, 7): - raise ValueError('Day of week value out of bounds.') - - days_per_month = self._GetDaysPerMonth( - system_time_tuple[0], system_time_tuple[1]) - if system_time_tuple[3] < 1 or system_time_tuple[3] > days_per_month: - raise ValueError('Day of month value out of bounds.') - - if system_time_tuple[4] not in range(0, 24): - raise ValueError('Hours value out of bounds.') - - if system_time_tuple[5] not in range(0, 60): - raise ValueError('Minutes value out of bounds.') - - # TODO: support a leap second? - if system_time_tuple[6] not in range(0, 60): - raise ValueError('Seconds value out of bounds.') - - if system_time_tuple[7] < 0 or system_time_tuple[7] > 999: - raise ValueError('Milliseconds value out of bounds.') - - self._day_of_month = system_time_tuple[3] - self._day_of_week = system_time_tuple[2] - self._hours = system_time_tuple[4] - self._milliseconds = system_time_tuple[7] - self._minutes = system_time_tuple[5] - self._month = system_time_tuple[1] - self._seconds = system_time_tuple[6] - self._year = system_time_tuple[0] - - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - self._year, self._month, self._day_of_month, self._hours, - self._minutes, self._seconds) - - @property - def day_of_month(self): - """day_of_month (int): day of month, 1 through 31.""" - return self._day_of_month - - @property - def day_of_week(self): - """day_of_week (int): day of week, 0 through 6.""" - return self._day_of_week - - @property - def hours(self): - """Hours (int): hours, 0 through 23.""" - return self._hours - - @property - def milliseconds(self): - """Milliseconds (int): milliseconds, 0 through 999.""" - return self._milliseconds - - @property - def minutes(self): - """Minutes (int): minutes, 0 through 59.""" - return self._minutes - - @property - def month(self): - """Month (int): month of year, 1 through 12.""" - return self._month - - @property - def seconds(self): - """Seconds (int): seconds, 0 through 59.""" - return self._seconds - - @property - def year(self): - """Year (int): year, 1601 through 30827.""" - return self._year - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._number_of_seconds is not None: - self._normalized_timestamp = ( - decimal.Decimal(self._milliseconds) / - definitions.MILLISECONDS_PER_SECOND) - self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a SYSTEMTIME structure from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the date string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - milliseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) - - if year < 1601 or year > 30827: - raise ValueError(f'Unsupported year value: {year:d}.') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_zone_offset = time_zone_offset - - self._year = year - self._month = month - self._day_of_month = day_of_month - # TODO: calculate day of week on demand. - self._day_of_week = None - self._hours = hours - self._minutes = minutes - self._seconds = seconds - self._milliseconds = milliseconds - - def CopyToDateTimeString(self): - """Copies the SYSTEMTIME structure to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.###" or - None if the number of seconds is missing. - """ - if self._number_of_seconds is None: - return None - return (f'{self._year:04d}-{self._month:02d}-{self._day_of_month:02d} ' - f'{self._hours:02d}:{self._minutes:02d}:{self._seconds:02d}' - f'.{self._milliseconds:03d}') + def __init__(self, precision=None, system_time_tuple=None, time_zone_offset=None): + """Initializes a SYSTEMTIME structure. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + system_time_tuple + (Optional[tuple[int, int, int, int, int, int, int, int]]): + system time, contains year, month, day of week, day of month, + hours, minutes, seconds and milliseconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the system time is invalid. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MILLISECOND, + time_zone_offset=time_zone_offset, + ) + self._number_of_seconds = None + self._day_of_month = None + self._day_of_week = None + self._hours = None + self._milliseconds = None + self._minutes = None + self._month = None + self._seconds = None + self._year = None + + if system_time_tuple: + if len(system_time_tuple) < 8: + raise ValueError("Invalid system time tuple 8 elements required.") + + if system_time_tuple[0] < 1601 or system_time_tuple[0] > 30827: + raise ValueError("Year value out of bounds.") + + if system_time_tuple[1] not in range(1, 13): + raise ValueError("Month value out of bounds.") + + if system_time_tuple[2] not in range(0, 7): + raise ValueError("Day of week value out of bounds.") + + days_per_month = self._GetDaysPerMonth( + system_time_tuple[0], system_time_tuple[1] + ) + if system_time_tuple[3] < 1 or system_time_tuple[3] > days_per_month: + raise ValueError("Day of month value out of bounds.") + + if system_time_tuple[4] not in range(0, 24): + raise ValueError("Hours value out of bounds.") + + if system_time_tuple[5] not in range(0, 60): + raise ValueError("Minutes value out of bounds.") + + # TODO: support a leap second? + if system_time_tuple[6] not in range(0, 60): + raise ValueError("Seconds value out of bounds.") + + if system_time_tuple[7] < 0 or system_time_tuple[7] > 999: + raise ValueError("Milliseconds value out of bounds.") + + self._day_of_month = system_time_tuple[3] + self._day_of_week = system_time_tuple[2] + self._hours = system_time_tuple[4] + self._milliseconds = system_time_tuple[7] + self._minutes = system_time_tuple[5] + self._month = system_time_tuple[1] + self._seconds = system_time_tuple[6] + self._year = system_time_tuple[0] + + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + self._year, + self._month, + self._day_of_month, + self._hours, + self._minutes, + self._seconds, + ) + + @property + def day_of_month(self): + """day_of_month (int): day of month, 1 through 31.""" + return self._day_of_month + + @property + def day_of_week(self): + """day_of_week (int): day of week, 0 through 6.""" + return self._day_of_week + + @property + def hours(self): + """Hours (int): hours, 0 through 23.""" + return self._hours + + @property + def milliseconds(self): + """Milliseconds (int): milliseconds, 0 through 999.""" + return self._milliseconds + + @property + def minutes(self): + """Minutes (int): minutes, 0 through 59.""" + return self._minutes + + @property + def month(self): + """Month (int): month of year, 1 through 12.""" + return self._month + + @property + def seconds(self): + """Seconds (int): seconds, 0 through 59.""" + return self._seconds + + @property + def year(self): + """Year (int): year, 1601 through 30827.""" + return self._year + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._number_of_seconds is not None: + self._normalized_timestamp = ( + decimal.Decimal(self._milliseconds) + / definitions.MILLISECONDS_PER_SECOND + ) + self._normalized_timestamp += decimal.Decimal(self._number_of_seconds) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a SYSTEMTIME structure from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the date string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND) + + if year < 1601 or year > 30827: + raise ValueError(f"Unsupported year value: {year:d}.") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_zone_offset = time_zone_offset + + self._year = year + self._month = month + self._day_of_month = day_of_month + # TODO: calculate day of week on demand. + self._day_of_week = None + self._hours = hours + self._minutes = minutes + self._seconds = seconds + self._milliseconds = milliseconds + + def CopyToDateTimeString(self): + """Copies the SYSTEMTIME structure to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.###" or + None if the number of seconds is missing. + """ + if self._number_of_seconds is None: + return None + + return ( + f"{self._year:04d}-{self._month:02d}-{self._day_of_month:02d} " + f"{self._hours:02d}:{self._minutes:02d}:{self._seconds:02d}" + f".{self._milliseconds:03d}" + ) factory.Factory.RegisterDateTimeValues(Systemtime) diff --git a/dfdatetime/time_elements.py b/dfdatetime/time_elements.py index 91b8a8f..7db6119 100644 --- a/dfdatetime/time_elements.py +++ b/dfdatetime/time_elements.py @@ -9,1542 +9,1687 @@ class TimeElements(interface.DateTimeValues): - """Time elements. - - Time elements contain separate values for year, month, day of month, - hours, minutes and seconds. - - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - # Maps the RFC 822, RFC 1123 and RFC 2822 definitions to their corresponding - # integer values. - _RFC_MONTH_MAPPINGS = { - 'Jan': 1, - 'Feb': 2, - 'Mar': 3, - 'Apr': 4, - 'May': 5, - 'Jun': 6, - 'Jul': 7, - 'Aug': 8, - 'Sep': 9, - 'Oct': 10, - 'Nov': 11, - 'Dec': 12} - - _RFC_TIME_ZONE_MAPPINGS = { - 'UT': 0, - 'GMT': 0, - 'EST': -5, - 'EDT': -4, - 'CST': -6, - 'CDT': -5, - 'MST': -7, - 'MDT': -6, - 'PST': -8, - 'PDT': -7, - 'A': -1, - 'B': -2, - 'C': -3, - 'D': -4, - 'E': -5, - 'F': -6, - 'G': -7, - 'H': -8, - 'I': -9, - 'K': -10, - 'L': -11, - 'M': -12, - 'N': 1, - 'O': 2, - 'P': 3, - 'Q': 4, - 'R': 5, - 'S': 6, - 'T': 7, - 'U': 8, - 'V': 9, - 'W': 10, - 'X': 11, - 'Y': 12, - 'Z': 0} - - _RFC_WEEKDAYS = frozenset(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) - - def __init__( - self, is_delta=False, precision=None, time_elements_tuple=None, - time_zone_offset=None): - """Initializes time elements. - - Args: - 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 - should be one of the PRECISION_VALUES in definitions. - time_elements_tuple (Optional[tuple[int, int, int, int, int, int]]): - time elements, contains year, month, day of month, hours, minutes and - seconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - super().__init__( - is_delta=is_delta, - precision=precision or definitions.PRECISION_1_SECOND, - time_zone_offset=time_zone_offset) - self._number_of_seconds = None - self._time_elements_tuple = time_elements_tuple - - if time_elements_tuple: - number_of_elements = len(time_elements_tuple) - if number_of_elements < 6: - raise ValueError(( - f'Invalid time elements tuple at least 6 elements required,' - f'got: {number_of_elements:d}')) - - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - time_elements_tuple[0], time_elements_tuple[1], - time_elements_tuple[2], time_elements_tuple[3], - time_elements_tuple[4], time_elements_tuple[5]) - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if self._number_of_seconds is not None: - self._normalized_timestamp = decimal.Decimal(self._number_of_seconds) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def _CopyDateTimeFromStringISO8601(self, time_string): - """Copies a date and time from an ISO 8601 date and time string. - - Args: - time_string (str): time value formatted as: - hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The fraction of second and - time zone offset are optional. - - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, nanoseconds, time zone offset in minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - if not time_string: - raise ValueError('Invalid time string.') - - time_string_length = len(time_string) - - year, month, day_of_month = self._CopyDateFromString(time_string) - - if time_string_length <= 10: - return { - 'year': year, - 'month': month, - 'day_of_month': day_of_month} - - # If a time of day is specified the time string it should at least - # contain 'YYYY-MM-DDThh'. - if time_string[10] != 'T': - raise ValueError('Invalid time string - missing date and time separator.') - - hours, minutes, seconds, nanoseconds, time_zone_offset = ( - self._CopyTimeFromStringISO8601(time_string[11:])) - - date_time_values = { - 'year': year, - 'month': month, - 'day_of_month': day_of_month, - 'hours': hours, - 'minutes': minutes, - 'seconds': seconds} - - if nanoseconds is not None: - date_time_values['nanoseconds'] = nanoseconds - if time_zone_offset is not None: - date_time_values['time_zone_offset'] = time_zone_offset - - return date_time_values - - def _CopyDateTimeFromStringRFC822(self, time_string): - """Copies a date and time from a RFC 822 date and time string. - - Args: - time_string (str): date and time value formatted as: - DAY, D MONTH YY hh:mm:ss ZONE - - Where weekday (DAY) and seconds (ss) are optional and day of - month (D) can consist of 1 or 2 digits. - - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, time zone offset in minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - if not time_string: - raise ValueError('Invalid time string.') - - string_segments = time_string.split(' ') - - if len(string_segments) not in (5, 6): - raise ValueError('Unsupported number of time string segments.') - - weekday_string = string_segments[0] - if weekday_string.endswith(','): - weekday_string = weekday_string[:-1] - if weekday_string not in self._RFC_WEEKDAYS: - raise ValueError(f'Invalid weekday: {weekday_string:s}.') - - string_segments.pop(0) - - day_of_month_string = string_segments[0] - - day_of_month = 0 - if len(day_of_month_string) in (1, 2): - try: - day_of_month = int(day_of_month_string, 10) - except ValueError: - pass - - if day_of_month == 0: - raise ValueError(f'Invalid day of month: {day_of_month_string:s}.') - - month_string = string_segments[1] - - month = self._RFC_MONTH_MAPPINGS.get(month_string) - if not month: - raise ValueError(f'Invalid month: {month_string:s}.') - - year_string = string_segments[2] - - year = None - if len(year_string) == 2: - try: - year = int(year_string, 10) - except ValueError: - pass - - if year is None: - raise ValueError(f'Invalid year: {0:s}.') - - year += 1900 - - hours, minutes, seconds, time_zone_offset = self._CopyTimeFromStringRFC( - string_segments[3], string_segments[4]) - - date_time_values = { - 'year': year, - 'month': month, - 'day_of_month': day_of_month, - 'hours': hours, - 'minutes': minutes, - 'time_zone_offset': time_zone_offset} - - if seconds is not None: - date_time_values['seconds'] = seconds - - return date_time_values - - def _CopyDateTimeFromStringRFC1123(self, time_string): - """Copies a date and time from a RFC 1123 date and time string. - - Args: - time_string (str): date and time value formatted as: - DAY, D MONTH YYYY hh:mm:ss ZONE - - Where weekday (DAY) and seconds (ss) are optional and day of - month (D) can consist of 1 or 2 digits. - - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, time zone offset in minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - if not time_string: - raise ValueError('Invalid time string.') - - string_segments = time_string.split(' ') - - if len(string_segments) not in (5, 6): - raise ValueError('Unsupported number of time string segments.') - - weekday_string = string_segments[0] - if weekday_string.endswith(','): - weekday_string = weekday_string[:-1] - if weekday_string not in self._RFC_WEEKDAYS: - raise ValueError(f'Invalid weekday: {weekday_string:s}.') + """Time elements. - string_segments.pop(0) + Time elements contain separate values for year, month, day of month, + hours, minutes and seconds. - day_of_month_string = string_segments[0] - - day_of_month = 0 - if len(day_of_month_string) in (1, 2): - try: - day_of_month = int(day_of_month_string, 10) - except ValueError: - pass - - if day_of_month == 0: - raise ValueError(f'Invalid day of month: {day_of_month_string:s}.') - - month_string = string_segments[1] - - month = self._RFC_MONTH_MAPPINGS.get(month_string) - if not month: - raise ValueError(f'Invalid month: {month_string:s}.') - - year_string = string_segments[2] - - year = None - if len(year_string) == 4: - try: - year = int(year_string, 10) - except ValueError: - pass - - if year is None: - raise ValueError(f'Invalid year: {year_string:s}.') - - hours, minutes, seconds, time_zone_offset = self._CopyTimeFromStringRFC( - string_segments[3], string_segments[4]) - - date_time_values = { - 'year': year, - 'month': month, - 'day_of_month': day_of_month, - 'hours': hours, - 'minutes': minutes, - 'time_zone_offset': time_zone_offset} - - if seconds is not None: - date_time_values['seconds'] = seconds - - return date_time_values - - def _CopyFromDateTimeValues(self, date_time_values): - """Copies time elements from date and time values. - - Args: - date_time_values (dict[str, int]): date and time values, such as year, - month, day of month, hours, minutes, seconds, nanoseconds, time zone - offset in minutes. - """ - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds) - self._time_zone_offset = time_zone_offset - - def _CopyTimeFromStringISO8601(self, time_string): - """Copies a time from an ISO 8601 time string. - - Args: - time_string (str): time value formatted as: - hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The fraction of second and - time zone offset are optional. - - Returns: - tuple[int, int, int, int, int]: hours, minutes, seconds, nanoseconds, - time zone offset in minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - if time_string.endswith('Z'): - time_string = ''.join([time_string[:-1], '+00:00']) - - time_string_length = len(time_string) - - # The time string should at least contain 'hh'. - if time_string_length < 2: - raise ValueError('Time string too short.') - - try: - hours = int(time_string[0:2], 10) - except ValueError: - raise ValueError('Unable to parse hours.') - - if hours not in range(0, 24): - raise ValueError(f'Hours value: {hours:d} out of bounds.') - - minutes = None - seconds = None - nanoseconds = None - time_zone_offset = None - - time_string_index = 2 - - # Minutes are either specified as 'hhmm', 'hh:mm' or as a fractional part - # 'hh[.,]###'. - if (time_string_index + 1 < time_string_length and - time_string[time_string_index] not in ('.', ',')): - if time_string[time_string_index] == ':': - time_string_index += 1 - - if time_string_index + 2 > time_string_length: - raise ValueError('Time string too short.') - - try: - minutes = time_string[time_string_index:time_string_index + 2] - minutes = int(minutes, 10) - except ValueError: - raise ValueError('Unable to parse minutes.') - - time_string_index += 2 - - # Seconds are either specified as 'hhmmss', 'hh:mm:ss' or as a fractional - # part 'hh:mm[.,]###' or 'hhmm[.,]###'. - if (time_string_index + 1 < time_string_length and - time_string[time_string_index] not in ('.', ',')): - if time_string[time_string_index] == ':': - time_string_index += 1 - - if time_string_index + 2 > time_string_length: - raise ValueError('Time string too short.') - - try: - seconds = time_string[time_string_index:time_string_index + 2] - seconds = int(seconds, 10) - except ValueError: - raise ValueError('Unable to parse day of seconds.') - - time_string_index += 2 - - time_zone_string_index = time_string_index - while time_zone_string_index < time_string_length: - if time_string[time_zone_string_index] in ('+', '-'): - break - - time_zone_string_index += 1 - - # The calculations that follow rely on the time zone string index - # to point beyond the string in case no time zone offset was defined. - if time_zone_string_index == time_string_length - 1: - time_zone_string_index += 1 - - if (time_string_length > time_string_index and - time_string[time_string_index] in ('.', ',')): - time_string_index += 1 - time_fraction_length = time_zone_string_index - time_string_index - - try: - time_fraction = time_string[time_string_index:time_zone_string_index] - time_fraction = int(time_fraction, 10) - time_fraction = ( - decimal.Decimal(time_fraction) / - decimal.Decimal(10 ** time_fraction_length)) - except ValueError: - raise ValueError('Unable to parse time fraction.') - - if minutes is None: - time_fraction *= 60 - minutes = int(time_fraction) - time_fraction -= minutes - - if seconds is None: - time_fraction *= 60 - seconds = int(time_fraction) - time_fraction -= seconds - - time_fraction *= definitions.NANOSECONDS_PER_SECOND - nanoseconds = int(time_fraction) - - if minutes is not None and minutes not in range(0, 60): - raise ValueError(f'Minutes value: {minutes:d} out of bounds.') - - # TODO: support a leap second? - if seconds is not None and seconds not in range(0, 60): - raise ValueError(f'Seconds value: {seconds:d} out of bounds.') - - if time_zone_string_index < time_string_length: - if (time_string_length - time_zone_string_index != 6 or - time_string[time_zone_string_index + 3] != ':'): - raise ValueError('Invalid time string.') - - try: - hours_from_utc = int(time_string[ - time_zone_string_index + 1:time_zone_string_index + 3]) - except ValueError: - raise ValueError('Unable to parse time zone hours offset.') - - if hours_from_utc not in range(0, 15): - raise ValueError('Time zone hours offset value out of bounds.') - - try: - minutes_from_utc = int(time_string[ - time_zone_string_index + 4:time_zone_string_index + 6]) - except ValueError: - raise ValueError('Unable to parse time zone minutes offset.') - - if minutes_from_utc not in range(0, 60): - raise ValueError('Time zone minutes offset value out of bounds.') - - # pylint: disable=invalid-unary-operand-type - time_zone_offset = (hours_from_utc * 60) + minutes_from_utc - - if time_string[time_zone_string_index] == '-': - time_zone_offset = -time_zone_offset - - return hours, minutes, seconds, nanoseconds, time_zone_offset - - def _CopyTimeFromStringRFC(self, time_string, time_zone_string): - """Copies a time from a RFC 822, RFC 1123 or RFC 2822 time string. - - Args: - time_string (str): time value formatted as: hh:mm[:ss], where seconds (ss) - are optional. - time_zone_string (str): time zone value formatted as predefined time zone - indicator or [+-]HHMM - - Returns: - tuple[int, int, int, int]: hours, minutes, seconds, time zone offset in - minutes. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - time_string_length = len(time_string) - - # The time string should at least contain 'hh:mm'. - if time_string_length < 5: - raise ValueError('Time string too short.') - - if time_string_length > 8: - raise ValueError('Time string too long.') - - if time_string[2] != ':': - raise ValueError('Invalid hours and minutes separator.') - - try: - hours = int(time_string[0:2], 10) - except ValueError: - raise ValueError('Unable to parse hours.') - - if hours not in range(0, 24): - raise ValueError(f'Hours value: {hours:d} out of bounds.') - - try: - minutes = int(time_string[3:5], 10) - except ValueError: - raise ValueError('Unable to parse minutes.') - - if minutes not in range(0, 60): - raise ValueError(f'Minutes value: {minutes:d} out of bounds.') - - seconds = None - - if time_string_length > 5: - if time_string_length < 8: - raise ValueError('Time string too short.') - - if time_string[5] != ':': - raise ValueError('Invalid minutes and seconds separator.') - - try: - seconds = int(time_string[6:8], 10) - except ValueError: - raise ValueError('Unable to parse seconds.') - - if seconds not in range(0, 60): - raise ValueError(f'Seconds value: {seconds:d} out of bounds.') - - time_zone_string_length = len(time_zone_string) - if time_zone_string_length > 5: - raise ValueError('Time zone string too long.') - - if time_zone_string_length < 5: - hours_from_utc = self._RFC_TIME_ZONE_MAPPINGS.get(time_zone_string) - minutes_from_utc = 0 - if hours_from_utc is None: - raise ValueError(f'Invalid time zone: {time_zone_string:s}.') - - else: - if time_zone_string[0] not in ('+', '-'): - raise ValueError(f'Invalid time zone: {time_zone_string:s}.') - - try: - hours_from_utc = int(time_zone_string[1:3], 10) - except ValueError: - raise ValueError('Unable to parse time zone hours offset.') - - if hours_from_utc not in range(0, 15): - raise ValueError('Time zone hours offset value out of bounds.') - - try: - minutes_from_utc = int(time_zone_string[3:5], 10) - except ValueError: - raise ValueError('Unable to parse time zone minutes offset.') - - if minutes_from_utc not in range(0, 60): - raise ValueError('Time zone minutes offset value out of bounds.') - - time_zone_offset = (hours_from_utc * 60) + minutes_from_utc - if time_zone_string[0] == '-': - time_zone_offset = -time_zone_offset - - return hours, minutes, seconds, time_zone_offset - - @property - def day_of_month(self): - """int: day of month or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[2] - - @property - def hours(self): - """int: number of hours or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[3] - - @property - def minutes(self): - """int: number of minutes or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[4] - - @property - def month(self): - """int: month or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[1] - - @property - def seconds(self): - """int: number of seconds or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[5] - - @property - def year(self): - """int: year or None if not set.""" - if not self._time_elements_tuple: - return None - return self._time_elements_tuple[0] - - def CopyFromDatetime(self, datetime_object): - """Copies time elements from a Python datetime object. - - A naive datetime object is considered in local time. - - Args: - datetime_object (datetime.datetime): Python datetime object. - """ - year, month, day_of_month, hours, minutes, seconds, _, _, _ = ( - datetime_object.utctimetuple()) - - date_time_values = { - 'year': year, - 'month': month, - 'day_of_month': day_of_month, - 'hours': hours, - 'minutes': minutes, - 'seconds': seconds} - - self._CopyFromDateTimeValues(date_time_values) - - self.is_local_time = bool(datetime_object.tzinfo is None) - - def CopyFromDateTimeString(self, time_string): - """Copies time elements from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - self._CopyFromDateTimeValues(date_time_values) - - def CopyFromStringISO8601(self, time_string): - """Copies time elements from an ISO 8601 date and time string. - - Currently not supported: - * Duration notation: "P..." - * Week notation "2016-W33" - * Date with week number notation "2016-W33-3" - * Date without year notation "--08-17" - * Ordinal date notation "2016-230" - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DDThh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - date_time_values = self._CopyDateTimeFromStringISO8601(time_string) - self._CopyFromDateTimeValues(date_time_values) + # Maps the RFC 822, RFC 1123 and RFC 2822 definitions to their corresponding + # integer values. + _RFC_MONTH_MAPPINGS = { + "Jan": 1, + "Feb": 2, + "Mar": 3, + "Apr": 4, + "May": 5, + "Jun": 6, + "Jul": 7, + "Aug": 8, + "Sep": 9, + "Oct": 10, + "Nov": 11, + "Dec": 12, + } + + _RFC_TIME_ZONE_MAPPINGS = { + "UT": 0, + "GMT": 0, + "EST": -5, + "EDT": -4, + "CST": -6, + "CDT": -5, + "MST": -7, + "MDT": -6, + "PST": -8, + "PDT": -7, + "A": -1, + "B": -2, + "C": -3, + "D": -4, + "E": -5, + "F": -6, + "G": -7, + "H": -8, + "I": -9, + "K": -10, + "L": -11, + "M": -12, + "N": 1, + "O": 2, + "P": 3, + "Q": 4, + "R": 5, + "S": 6, + "T": 7, + "U": 8, + "V": 9, + "W": 10, + "X": 11, + "Y": 12, + "Z": 0, + } + + _RFC_WEEKDAYS = frozenset(["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]) + + def __init__( + self, + is_delta=False, + precision=None, + time_elements_tuple=None, + time_zone_offset=None, + ): + """Initializes time elements. + + Args: + 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 + should be one of the PRECISION_VALUES in definitions. + time_elements_tuple (Optional[tuple[int, int, int, int, int, int]]): + time elements, contains year, month, day of month, hours, minutes and + seconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + super().__init__( + is_delta=is_delta, + precision=precision or definitions.PRECISION_1_SECOND, + time_zone_offset=time_zone_offset, + ) + self._number_of_seconds = None + self._time_elements_tuple = time_elements_tuple + + if time_elements_tuple: + number_of_elements = len(time_elements_tuple) + if number_of_elements < 6: + raise ValueError( + ( + f"Invalid time elements tuple at least 6 elements required," + f"got: {number_of_elements:d}" + ) + ) + + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + time_elements_tuple[0], + time_elements_tuple[1], + time_elements_tuple[2], + time_elements_tuple[3], + time_elements_tuple[4], + time_elements_tuple[5], + ) + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if self._number_of_seconds is not None: + self._normalized_timestamp = decimal.Decimal(self._number_of_seconds) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def _CopyDateTimeFromStringISO8601(self, time_string): + """Copies a date and time from an ISO 8601 date and time string. + + Args: + time_string (str): time value formatted as: + hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The fraction of second and + time zone offset are optional. + + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, nanoseconds, time zone offset in minutes. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + if not time_string: + raise ValueError("Invalid time string.") + + time_string_length = len(time_string) + + year, month, day_of_month = self._CopyDateFromString(time_string) + + if time_string_length <= 10: + return {"year": year, "month": month, "day_of_month": day_of_month} + + # If a time of day is specified the time string it should at least + # contain 'YYYY-MM-DDThh'. + if time_string[10] != "T": + raise ValueError("Invalid time string - missing date and time separator.") + + hours, minutes, seconds, nanoseconds, time_zone_offset = ( + self._CopyTimeFromStringISO8601(time_string[11:]) + ) + + date_time_values = { + "year": year, + "month": month, + "day_of_month": day_of_month, + "hours": hours, + "minutes": minutes, + "seconds": seconds, + } + + if nanoseconds is not None: + date_time_values["nanoseconds"] = nanoseconds + if time_zone_offset is not None: + date_time_values["time_zone_offset"] = time_zone_offset + + return date_time_values + + def _CopyDateTimeFromStringRFC822(self, time_string): + """Copies a date and time from a RFC 822 date and time string. + + Args: + time_string (str): date and time value formatted as: + DAY, D MONTH YY hh:mm:ss ZONE + + Where weekday (DAY) and seconds (ss) are optional and day of + month (D) can consist of 1 or 2 digits. + + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, time zone offset in minutes. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + if not time_string: + raise ValueError("Invalid time string.") - def CopyFromStringRFC822(self, time_string): - """Copies time elements from a RFC 822 date and time string. + string_segments = time_string.split(" ") - Args: - time_string (str): date and time value formatted as: - DAY, D MONTH YY hh:mm:ss ZONE + if len(string_segments) not in (5, 6): + raise ValueError("Unsupported number of time string segments.") - Where weekday (DAY) and seconds (ss) are optional and day of - month (D) can consist of 1 or 2 digits. + weekday_string = string_segments[0] + if weekday_string.endswith(","): + weekday_string = weekday_string[:-1] + if weekday_string not in self._RFC_WEEKDAYS: + raise ValueError(f"Invalid weekday: {weekday_string:s}.") - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromStringRFC822(time_string) + string_segments.pop(0) - self._CopyFromDateTimeValues(date_time_values) + day_of_month_string = string_segments[0] - def CopyFromStringRFC1123(self, time_string): - """Copies time elements from a RFC 1123 date and time string. + day_of_month = 0 + if len(day_of_month_string) in (1, 2): + try: + day_of_month = int(day_of_month_string, 10) + except ValueError: + pass - Args: - time_string (str): date and time value formatted as: - DAY, D MONTH YYYY hh:mm:ss ZONE + if day_of_month == 0: + raise ValueError(f"Invalid day of month: {day_of_month_string:s}.") - Where weekday (DAY) and seconds (ss) are optional and day of - month (D) can consist of 1 or 2 digits. + month_string = string_segments[1] - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromStringRFC1123(time_string) - - self._CopyFromDateTimeValues(date_time_values) - - def CopyFromStringTuple(self, time_elements_tuple): - """Copies time elements from string-based time elements tuple. + month = self._RFC_MONTH_MAPPINGS.get(month_string) + if not month: + raise ValueError(f"Invalid month: {month_string:s}.") - Args: - time_elements_tuple (Optional[tuple[str, str, str, str, str, str]]): - time elements, contains year, month, day of month, hours, minutes and - seconds. + year_string = string_segments[2] - Raises: - ValueError: if the time elements tuple is invalid. - """ - number_of_elements = len(time_elements_tuple) - if number_of_elements < 6: - raise ValueError(( - f'Invalid time elements tuple at least 6 elements required,' - f'got: {number_of_elements:d}')) - - year_string = time_elements_tuple[0] - month_string = time_elements_tuple[1] - day_of_month_string = time_elements_tuple[2] - hours_string = time_elements_tuple[3] - minutes_string = time_elements_tuple[4] - seconds_string = time_elements_tuple[5] - - try: - year = int(year_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid year value: {year_string!s}') - - try: - month = int(month_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid month value: {month_string!s}') - - try: - day_of_month = int(day_of_month_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid day of month value: {day_of_month_string!s}') - - try: - hours = int(hours_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid hours value: {hours_string!s}') - - try: - minutes = int(minutes_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid minutes value: {minutes_string!s}') - - try: - seconds = int(seconds_string, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid seconds value: {seconds_string!s}') - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds) - - def CopyToDateTimeString(self): - """Copies the time elements to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None - if time elements are missing. - """ - if self._number_of_seconds is None: - return None + year = None + if len(year_string) == 2: + try: + year = int(year_string, 10) + except ValueError: + pass - year, month, day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) + if year is None: + raise ValueError(f"Invalid year: {0:s}.") - return ( - f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}') + year += 1900 - def NewFromDeltaAndDate(self, year, month, day_of_month): - """Creates a new time elements instance from a date time delta and a date. + hours, minutes, seconds, time_zone_offset = self._CopyTimeFromStringRFC( + string_segments[3], string_segments[4] + ) - 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. + date_time_values = { + "year": year, + "month": month, + "day_of_month": day_of_month, + "hours": hours, + "minutes": minutes, + "time_zone_offset": time_zone_offset, + } + + if seconds is not None: + date_time_values["seconds"] = seconds + + return date_time_values + + def _CopyDateTimeFromStringRFC1123(self, time_string): + """Copies a date and time from a RFC 1123 date and time string. + + Args: + time_string (str): date and time value formatted as: + DAY, D MONTH YYYY hh:mm:ss ZONE - Returns: - TimeElements: time elements or None if time elements are missing. + Where weekday (DAY) and seconds (ss) are optional and day of + month (D) can consist of 1 or 2 digits. - Raises: - ValueError: if the instance is not a date time delta. - """ - if not self._is_delta: - raise ValueError('Not a date time delta.') + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, time zone offset in minutes. - if self._time_elements_tuple is None: - return None + Raises: + ValueError: if the time string is invalid or not supported. + """ + if not time_string: + raise ValueError("Invalid time string.") - delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) + string_segments = time_string.split(" ") + + if len(string_segments) not in (5, 6): + raise ValueError("Unsupported number of time string segments.") + + weekday_string = string_segments[0] + if weekday_string.endswith(","): + weekday_string = weekday_string[:-1] + if weekday_string not in self._RFC_WEEKDAYS: + raise ValueError(f"Invalid weekday: {weekday_string:s}.") - time_elements_tuple = ( - year + delta_year, month + delta_month, - day_of_month + delta_day_of_month, hours, minutes, seconds) + string_segments.pop(0) + + day_of_month_string = string_segments[0] + + day_of_month = 0 + if len(day_of_month_string) in (1, 2): + try: + day_of_month = int(day_of_month_string, 10) + except ValueError: + pass + + if day_of_month == 0: + raise ValueError(f"Invalid day of month: {day_of_month_string:s}.") + + month_string = string_segments[1] - date_time = TimeElements( - precision=self._precision, time_elements_tuple=time_elements_tuple, - time_zone_offset=self._time_zone_offset) - - date_time.is_local_time = self.is_local_time - - 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) + month = self._RFC_MONTH_MAPPINGS.get(month_string) + if not month: + raise ValueError(f"Invalid month: {month_string:s}.") + + year_string = string_segments[2] + + year = None + if len(year_string) == 4: + try: + year = int(year_string, 10) + except ValueError: + pass + + if year is None: + raise ValueError(f"Invalid year: {year_string:s}.") + + hours, minutes, seconds, time_zone_offset = self._CopyTimeFromStringRFC( + string_segments[3], string_segments[4] + ) + + date_time_values = { + "year": year, + "month": month, + "day_of_month": day_of_month, + "hours": hours, + "minutes": minutes, + "time_zone_offset": time_zone_offset, + } + + if seconds is not None: + date_time_values["seconds"] = seconds + + return date_time_values + + def _CopyFromDateTimeValues(self, date_time_values): + """Copies time elements from date and time values. + + Args: + date_time_values (dict[str, int]): date and time values, such as year, + month, day of month, hours, minutes, seconds, nanoseconds, time zone + offset in minutes. + """ + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_elements_tuple = (year, month, day_of_month, hours, minutes, seconds) + self._time_zone_offset = time_zone_offset + + def _CopyTimeFromStringISO8601(self, time_string): + """Copies a time from an ISO 8601 time string. + + Args: + time_string (str): time value formatted as: + hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The fraction of second and + time zone offset are optional. + + Returns: + tuple[int, int, int, int, int]: hours, minutes, seconds, nanoseconds, + time zone offset in minutes. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + if time_string.endswith("Z"): + time_string = "".join([time_string[:-1], "+00:00"]) + + time_string_length = len(time_string) + + # The time string should at least contain 'hh'. + if time_string_length < 2: + raise ValueError("Time string too short.") + + try: + hours = int(time_string[0:2], 10) + except ValueError: + raise ValueError("Unable to parse hours.") + + if hours not in range(0, 24): + raise ValueError(f"Hours value: {hours:d} out of bounds.") + + minutes = None + seconds = None + nanoseconds = None + time_zone_offset = None + + time_string_index = 2 + + # Minutes are either specified as 'hhmm', 'hh:mm' or as a fractional part + # 'hh[.,]###'. + if time_string_index + 1 < time_string_length and time_string[ + time_string_index + ] not in (".", ","): + if time_string[time_string_index] == ":": + time_string_index += 1 + + if time_string_index + 2 > time_string_length: + raise ValueError("Time string too short.") + + try: + minutes = time_string[time_string_index : time_string_index + 2] + minutes = int(minutes, 10) + except ValueError: + raise ValueError("Unable to parse minutes.") + + time_string_index += 2 + + # Seconds are either specified as 'hhmmss', 'hh:mm:ss' or as a fractional + # part 'hh:mm[.,]###' or 'hhmm[.,]###'. + if time_string_index + 1 < time_string_length and time_string[ + time_string_index + ] not in (".", ","): + if time_string[time_string_index] == ":": + time_string_index += 1 + + if time_string_index + 2 > time_string_length: + raise ValueError("Time string too short.") + + try: + seconds = time_string[time_string_index : time_string_index + 2] + seconds = int(seconds, 10) + except ValueError: + raise ValueError("Unable to parse day of seconds.") + + time_string_index += 2 + + time_zone_string_index = time_string_index + while time_zone_string_index < time_string_length: + if time_string[time_zone_string_index] in ("+", "-"): + break + + time_zone_string_index += 1 + + # The calculations that follow rely on the time zone string index + # to point beyond the string in case no time zone offset was defined. + if time_zone_string_index == time_string_length - 1: + time_zone_string_index += 1 + + if time_string_length > time_string_index and time_string[ + time_string_index + ] in (".", ","): + time_string_index += 1 + time_fraction_length = time_zone_string_index - time_string_index + + try: + time_fraction = time_string[time_string_index:time_zone_string_index] + time_fraction = int(time_fraction, 10) + time_fraction = decimal.Decimal(time_fraction) / decimal.Decimal( + 10**time_fraction_length + ) + except ValueError: + raise ValueError("Unable to parse time fraction.") + + if minutes is None: + time_fraction *= 60 + minutes = int(time_fraction) + time_fraction -= minutes + + if seconds is None: + time_fraction *= 60 + seconds = int(time_fraction) + time_fraction -= seconds + + time_fraction *= definitions.NANOSECONDS_PER_SECOND + nanoseconds = int(time_fraction) + + if minutes is not None and minutes not in range(0, 60): + raise ValueError(f"Minutes value: {minutes:d} out of bounds.") + + # TODO: support a leap second? + if seconds is not None and seconds not in range(0, 60): + raise ValueError(f"Seconds value: {seconds:d} out of bounds.") + + if time_zone_string_index < time_string_length: + if ( + time_string_length - time_zone_string_index != 6 + or time_string[time_zone_string_index + 3] != ":" + ): + raise ValueError("Invalid time string.") + + try: + hours_from_utc = int( + time_string[time_zone_string_index + 1 : time_zone_string_index + 3] + ) + except ValueError: + raise ValueError("Unable to parse time zone hours offset.") + + if hours_from_utc not in range(0, 15): + raise ValueError("Time zone hours offset value out of bounds.") + + try: + minutes_from_utc = int( + time_string[time_zone_string_index + 4 : time_zone_string_index + 6] + ) + except ValueError: + raise ValueError("Unable to parse time zone minutes offset.") + + if minutes_from_utc not in range(0, 60): + raise ValueError("Time zone minutes offset value out of bounds.") + + # pylint: disable=invalid-unary-operand-type + time_zone_offset = (hours_from_utc * 60) + minutes_from_utc + + if time_string[time_zone_string_index] == "-": + time_zone_offset = -time_zone_offset + + return hours, minutes, seconds, nanoseconds, time_zone_offset + + def _CopyTimeFromStringRFC(self, time_string, time_zone_string): + """Copies a time from a RFC 822, RFC 1123 or RFC 2822 time string. + + Args: + time_string (str): time value formatted as: hh:mm[:ss], where seconds (ss) + are optional. + time_zone_string (str): time zone value formatted as predefined time zone + indicator or [+-]HHMM + + Returns: + tuple[int, int, int, int]: hours, minutes, seconds, time zone offset in + minutes. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + time_string_length = len(time_string) + + # The time string should at least contain 'hh:mm'. + if time_string_length < 5: + raise ValueError("Time string too short.") + + if time_string_length > 8: + raise ValueError("Time string too long.") + + if time_string[2] != ":": + raise ValueError("Invalid hours and minutes separator.") + + try: + hours = int(time_string[0:2], 10) + except ValueError: + raise ValueError("Unable to parse hours.") + + if hours not in range(0, 24): + raise ValueError(f"Hours value: {hours:d} out of bounds.") + + try: + minutes = int(time_string[3:5], 10) + except ValueError: + raise ValueError("Unable to parse minutes.") + + if minutes not in range(0, 60): + raise ValueError(f"Minutes value: {minutes:d} out of bounds.") + + seconds = None + + if time_string_length > 5: + if time_string_length < 8: + raise ValueError("Time string too short.") + + if time_string[5] != ":": + raise ValueError("Invalid minutes and seconds separator.") + + try: + seconds = int(time_string[6:8], 10) + except ValueError: + raise ValueError("Unable to parse seconds.") + + if seconds not in range(0, 60): + raise ValueError(f"Seconds value: {seconds:d} out of bounds.") + + time_zone_string_length = len(time_zone_string) + if time_zone_string_length > 5: + raise ValueError("Time zone string too long.") + + if time_zone_string_length < 5: + hours_from_utc = self._RFC_TIME_ZONE_MAPPINGS.get(time_zone_string) + minutes_from_utc = 0 + if hours_from_utc is None: + raise ValueError(f"Invalid time zone: {time_zone_string:s}.") + + else: + if time_zone_string[0] not in ("+", "-"): + raise ValueError(f"Invalid time zone: {time_zone_string:s}.") + + try: + hours_from_utc = int(time_zone_string[1:3], 10) + except ValueError: + raise ValueError("Unable to parse time zone hours offset.") + + if hours_from_utc not in range(0, 15): + raise ValueError("Time zone hours offset value out of bounds.") + + try: + minutes_from_utc = int(time_zone_string[3:5], 10) + except ValueError: + raise ValueError("Unable to parse time zone minutes offset.") + + if minutes_from_utc not in range(0, 60): + raise ValueError("Time zone minutes offset value out of bounds.") + + time_zone_offset = (hours_from_utc * 60) + minutes_from_utc + if time_zone_string[0] == "-": + time_zone_offset = -time_zone_offset + + return hours, minutes, seconds, time_zone_offset + + @property + def day_of_month(self): + """int: day of month or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[2] + + @property + def hours(self): + """int: number of hours or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[3] + + @property + def minutes(self): + """int: number of minutes or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[4] + + @property + def month(self): + """int: month or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[1] + + @property + def seconds(self): + """int: number of seconds or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[5] + + @property + def year(self): + """int: year or None if not set.""" + if not self._time_elements_tuple: + return None + return self._time_elements_tuple[0] + + def CopyFromDatetime(self, datetime_object): + """Copies time elements from a Python datetime object. + + A naive datetime object is considered in local time. + + Args: + datetime_object (datetime.datetime): Python datetime object. + """ + year, month, day_of_month, hours, minutes, seconds, _, _, _ = ( + datetime_object.utctimetuple() + ) + + date_time_values = { + "year": year, + "month": month, + "day_of_month": day_of_month, + "hours": hours, + "minutes": minutes, + "seconds": seconds, + } + + self._CopyFromDateTimeValues(date_time_values) + + self.is_local_time = bool(datetime_object.tzinfo is None) + + def CopyFromDateTimeString(self, time_string): + """Copies time elements from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + self._CopyFromDateTimeValues(date_time_values) + + def CopyFromStringISO8601(self, time_string): + """Copies time elements from an ISO 8601 date and time string. + + Currently not supported: + * Duration notation: "P..." + * Week notation "2016-W33" + * Date with week number notation "2016-W33-3" + * Date without year notation "--08-17" + * Ordinal date notation "2016-230" + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DDThh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromStringISO8601(time_string) + + self._CopyFromDateTimeValues(date_time_values) + + def CopyFromStringRFC822(self, time_string): + """Copies time elements from a RFC 822 date and time string. + + Args: + time_string (str): date and time value formatted as: + DAY, D MONTH YY hh:mm:ss ZONE + + Where weekday (DAY) and seconds (ss) are optional and day of + month (D) can consist of 1 or 2 digits. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromStringRFC822(time_string) + + self._CopyFromDateTimeValues(date_time_values) + + def CopyFromStringRFC1123(self, time_string): + """Copies time elements from a RFC 1123 date and time string. + + Args: + time_string (str): date and time value formatted as: + DAY, D MONTH YYYY hh:mm:ss ZONE + + Where weekday (DAY) and seconds (ss) are optional and day of + month (D) can consist of 1 or 2 digits. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromStringRFC1123(time_string) + + self._CopyFromDateTimeValues(date_time_values) + + def CopyFromStringTuple(self, time_elements_tuple): + """Copies time elements from string-based time elements tuple. + + Args: + time_elements_tuple (Optional[tuple[str, str, str, str, str, str]]): + time elements, contains year, month, day of month, hours, minutes and + seconds. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + number_of_elements = len(time_elements_tuple) + if number_of_elements < 6: + raise ValueError( + ( + f"Invalid time elements tuple at least 6 elements required," + f"got: {number_of_elements:d}" + ) + ) + + year_string = time_elements_tuple[0] + month_string = time_elements_tuple[1] + day_of_month_string = time_elements_tuple[2] + hours_string = time_elements_tuple[3] + minutes_string = time_elements_tuple[4] + seconds_string = time_elements_tuple[5] + + try: + year = int(year_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid year value: {year_string!s}") + + try: + month = int(month_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid month value: {month_string!s}") + + try: + day_of_month = int(day_of_month_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid day of month value: {day_of_month_string!s}") + + try: + hours = int(hours_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid hours value: {hours_string!s}") + + try: + minutes = int(minutes_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid minutes value: {minutes_string!s}") + + try: + seconds = int(seconds_string, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid seconds value: {seconds_string!s}") + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_elements_tuple = (year, month, day_of_month, hours, minutes, seconds) + + def CopyToDateTimeString(self): + """Copies the time elements to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None + if time elements are missing. + """ + if self._number_of_seconds is None: + return None + + year, month, day_of_month, hours, minutes, seconds = self._time_elements_tuple + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}" + ) + + 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. + + Raises: + ValueError: if the instance is not a date time delta. + """ + if not self._is_delta: + raise ValueError("Not a date time delta.") + + if self._time_elements_tuple is None: + return None + + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( + self._time_elements_tuple + ) + + time_elements_tuple = ( + 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, + time_zone_offset=self._time_zone_offset, + ) + + date_time.is_local_time = self.is_local_time + + 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. - - Attributes: - fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.0 and 1.0. - is_local_time (bool): True if the date and time value is in local time. - """ - - def __init__( - self, fraction_of_second=None, is_delta=False, precision=None, - time_elements_tuple=None, time_zone_offset=None): - """Initializes time elements. - - Args: - fraction_of_second (Optional[decimal.Decimal]): fraction of second, which - 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 - should be one of the PRECISION_VALUES in definitions. - time_elements_tuple (Optional[tuple[int, int, int, int, int, int]]): - time elements, contains year, month, day of month, hours, minutes and - seconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the time elements tuple is invalid or fraction of second - value is out of bounds. - """ - if fraction_of_second is not None: - 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.') - - super().__init__( - is_delta=is_delta, - precision=precision or definitions.PRECISION_1_SECOND, - time_elements_tuple=time_elements_tuple, - time_zone_offset=time_zone_offset) - self.fraction_of_second = fraction_of_second - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - if self._normalized_timestamp is None: - if (self._number_of_seconds is not None and - self.fraction_of_second is not None): - self._normalized_timestamp = ( - decimal.Decimal(self._number_of_seconds) + self.fraction_of_second) - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def _CopyFromDateTimeValues(self, date_time_values): - """Copies time elements from date and time values. + """Time elements with a fraction of second interface. - Args: - date_time_values (dict[str, int]): date and time values, such as year, - month, day of month, hours, minutes, seconds, nanoseconds, time zone - offset in minutes. - - Raises: - ValueError: if no helper can be created for the current precision. - """ - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( - self._precision) - - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - nanoseconds) - - self._normalized_timestamp = None - self._number_of_seconds = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - self._time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds) - self._time_zone_offset = time_zone_offset - - self.fraction_of_second = fraction_of_second - - def CopyFromDatetime(self, datetime_object): - """Copies time elements from a Python datetime object. - - A naive datetime object is considered in local time. - - Args: - datetime_object (datetime.datetime): Python datetime object. - """ - super().CopyFromDatetime( - datetime_object) - - precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( - self._precision) - - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - datetime_object.microsecond * definitions.NANOSECONDS_PER_MICROSECOND) - self.fraction_of_second = fraction_of_second - - def CopyFromStringTuple(self, time_elements_tuple): - """Copies time elements from string-based time elements tuple. - - Args: - time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and fraction of seconds. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - number_of_elements = len(time_elements_tuple) - if number_of_elements < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - super().CopyFromStringTuple( - time_elements_tuple) - - fraction_of_second_string = time_elements_tuple[6] - - try: - fraction_of_second = decimal.Decimal(fraction_of_second_string) - except (TypeError, ValueError): - 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: - raise ValueError( - f'Fraction of second value: {fraction_of_second:f} out of bounds.') - - self.fraction_of_second = fraction_of_second - - def CopyToDateTimeString(self): - """Copies the time elements to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or - "YYYY-MM-DD hh:mm:ss.######" or None if time elements are missing. - - Raises: - ValueError: if the precision value is unsupported. - """ - if self._number_of_seconds is None or self.fraction_of_second is None: - return None - - precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( - self._precision) - - return precision_helper.CopyToDateTimeString( - self._time_elements_tuple, self.fraction_of_second) - - 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 - are missing. - - Raises: - ValueError: if the instance is not a date time delta. + Attributes: + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.0 and 1.0. + is_local_time (bool): True if the date and time value is in local time. """ - if not self._is_delta: - raise ValueError('Not a date time delta.') - - if self._time_elements_tuple is None: - return None - delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) - - time_elements_tuple = ( - 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) + def __init__( + self, + fraction_of_second=None, + is_delta=False, + precision=None, + time_elements_tuple=None, + time_zone_offset=None, + ): + """Initializes time elements. + + Args: + fraction_of_second (Optional[decimal.Decimal]): fraction of second, which + 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 + should be one of the PRECISION_VALUES in definitions. + time_elements_tuple (Optional[tuple[int, int, int, int, int, int]]): + time elements, contains year, month, day of month, hours, minutes and + seconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the time elements tuple is invalid or fraction of second + value is out of bounds. + """ + if fraction_of_second is not None: + 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." + ) + + super().__init__( + is_delta=is_delta, + precision=precision or definitions.PRECISION_1_SECOND, + time_elements_tuple=time_elements_tuple, + time_zone_offset=time_zone_offset, + ) + self.fraction_of_second = fraction_of_second + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + if self._normalized_timestamp is None: + if ( + self._number_of_seconds is not None + and self.fraction_of_second is not None + ): + self._normalized_timestamp = ( + decimal.Decimal(self._number_of_seconds) + self.fraction_of_second + ) + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def _CopyFromDateTimeValues(self, date_time_values): + """Copies time elements from date and time values. + + Args: + date_time_values (dict[str, int]): date and time values, such as year, + month, day of month, hours, minutes, seconds, nanoseconds, time zone + offset in minutes. + + Raises: + ValueError: if no helper can be created for the current precision. + """ + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( + self._precision + ) + + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + nanoseconds + ) + + self._normalized_timestamp = None + self._number_of_seconds = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + self._time_elements_tuple = (year, month, day_of_month, hours, minutes, seconds) + self._time_zone_offset = time_zone_offset + + self.fraction_of_second = fraction_of_second + + def CopyFromDatetime(self, datetime_object): + """Copies time elements from a Python datetime object. + + A naive datetime object is considered in local time. + + Args: + datetime_object (datetime.datetime): Python datetime object. + """ + super().CopyFromDatetime(datetime_object) + + precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( + self._precision + ) + + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + datetime_object.microsecond * definitions.NANOSECONDS_PER_MICROSECOND + ) + self.fraction_of_second = fraction_of_second + + def CopyFromStringTuple(self, time_elements_tuple): + """Copies time elements from string-based time elements tuple. + + Args: + time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and fraction of seconds. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + number_of_elements = len(time_elements_tuple) + if number_of_elements < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + super().CopyFromStringTuple(time_elements_tuple) + + fraction_of_second_string = time_elements_tuple[6] + + try: + fraction_of_second = decimal.Decimal(fraction_of_second_string) + except (TypeError, ValueError): + 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: + raise ValueError( + f"Fraction of second value: {fraction_of_second:f} out of bounds." + ) + + self.fraction_of_second = fraction_of_second + + def CopyToDateTimeString(self): + """Copies the time elements to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or + "YYYY-MM-DD hh:mm:ss.######" or None if time elements are missing. + + Raises: + ValueError: if the precision value is unsupported. + """ + if self._number_of_seconds is None or self.fraction_of_second is None: + return None + + precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( + self._precision + ) + + return precision_helper.CopyToDateTimeString( + self._time_elements_tuple, self.fraction_of_second + ) + + 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 + are missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + if not self._is_delta: + raise ValueError("Not a date time delta.") + + if self._time_elements_tuple is None: + return None + + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( + self._time_elements_tuple + ) + + time_elements_tuple = ( + 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. - - Attributes: - fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.0 and 1.0. - is_local_time (bool): True if the date and time value is in local time. - precision (str): precision of the date of the date and time value, that - represents 1 millisecond (PRECISION_1_MILLISECOND). - """ - - def __init__( - self, is_delta=False, precision=None, time_elements_tuple=None, - time_zone_offset=None): - """Initializes time elements. - - Args: - 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 - should be one of the PRECISION_VALUES in definitions. - time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and milliseconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - fraction_of_second = None - if time_elements_tuple: - number_of_elements = len(time_elements_tuple) - if number_of_elements < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - milliseconds = time_elements_tuple[6] - time_elements_tuple = time_elements_tuple[:6] - - if (milliseconds < 0 or - milliseconds >= definitions.MILLISECONDS_PER_SECOND): - raise ValueError('Invalid number of milliseconds.') - - fraction_of_second = ( - decimal.Decimal(milliseconds) / definitions.MILLISECONDS_PER_SECOND) - - super().__init__( - fraction_of_second=fraction_of_second, is_delta=is_delta, - precision=precision or definitions.PRECISION_1_MILLISECOND, - time_elements_tuple=time_elements_tuple, - time_zone_offset=time_zone_offset) - - @property - def milliseconds(self): - """int: number of milliseconds.""" - return int(self.fraction_of_second * definitions.MILLISECONDS_PER_SECOND) - - def CopyFromStringTuple(self, time_elements_tuple): - """Copies time elements from string-based time elements tuple. - - Args: - time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and milliseconds. - - Raises: - ValueError: if the time elements tuple is invalid. + """Time elements in milliseconds. + + Attributes: + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.0 and 1.0. + is_local_time (bool): True if the date and time value is in local time. + precision (str): precision of the date of the date and time value, that + represents 1 millisecond (PRECISION_1_MILLISECOND). """ - number_of_elements = len(time_elements_tuple) - if len(time_elements_tuple) < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - year, month, day_of_month, hours, minutes, seconds, milliseconds = ( - time_elements_tuple) - - try: - milliseconds = int(milliseconds, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid millisecond value: {milliseconds!s}') - - if milliseconds < 0 or milliseconds >= definitions.MILLISECONDS_PER_SECOND: - raise ValueError('Invalid number of milliseconds.') - - fraction_of_second = ( - decimal.Decimal(milliseconds) / definitions.MILLISECONDS_PER_SECOND) - time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds, - str(fraction_of_second)) - - super().CopyFromStringTuple( - time_elements_tuple) - - 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 - missing. - - Raises: - ValueError: if the instance is not a date time delta. - """ - if not self._is_delta: - raise ValueError('Not a date time delta.') - - if self._time_elements_tuple is None: - return None - - delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) - - time_elements_tuple = ( - 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) + def __init__( + self, + is_delta=False, + precision=None, + time_elements_tuple=None, + time_zone_offset=None, + ): + """Initializes time elements. + + Args: + 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 + should be one of the PRECISION_VALUES in definitions. + time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and milliseconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + fraction_of_second = None + if time_elements_tuple: + number_of_elements = len(time_elements_tuple) + if number_of_elements < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + milliseconds = time_elements_tuple[6] + time_elements_tuple = time_elements_tuple[:6] + + if milliseconds < 0 or milliseconds >= definitions.MILLISECONDS_PER_SECOND: + raise ValueError("Invalid number of milliseconds.") + + fraction_of_second = ( + decimal.Decimal(milliseconds) / definitions.MILLISECONDS_PER_SECOND + ) + + super().__init__( + fraction_of_second=fraction_of_second, + is_delta=is_delta, + precision=precision or definitions.PRECISION_1_MILLISECOND, + time_elements_tuple=time_elements_tuple, + time_zone_offset=time_zone_offset, + ) + + @property + def milliseconds(self): + """int: number of milliseconds.""" + return int(self.fraction_of_second * definitions.MILLISECONDS_PER_SECOND) + + def CopyFromStringTuple(self, time_elements_tuple): + """Copies time elements from string-based time elements tuple. + + Args: + time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and milliseconds. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + number_of_elements = len(time_elements_tuple) + if len(time_elements_tuple) < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + year, month, day_of_month, hours, minutes, seconds, milliseconds = ( + time_elements_tuple + ) + + try: + milliseconds = int(milliseconds, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid millisecond value: {milliseconds!s}") + + if milliseconds < 0 or milliseconds >= definitions.MILLISECONDS_PER_SECOND: + raise ValueError("Invalid number of milliseconds.") + + fraction_of_second = ( + decimal.Decimal(milliseconds) / definitions.MILLISECONDS_PER_SECOND + ) + + time_elements_tuple = ( + year, + month, + day_of_month, + hours, + minutes, + seconds, + str(fraction_of_second), + ) + + super().CopyFromStringTuple(time_elements_tuple) + + 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 + missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + if not self._is_delta: + raise ValueError("Not a date time delta.") + + if self._time_elements_tuple is None: + return None + + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( + self._time_elements_tuple + ) + + time_elements_tuple = ( + 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. - - Attributes: - fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.0 and 1.0. - is_local_time (bool): True if the date and time value is in local time. - precision (str): precision of the date of the date and time value, that - represents 1 microsecond (PRECISION_1_MICROSECOND). - """ - - def __init__( - self, is_delta=False, precision=None, time_elements_tuple=None, - time_zone_offset=None): - """Initializes time elements. - - Args: - 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 - should be one of the PRECISION_VALUES in definitions. - time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and microseconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - fraction_of_second = None - if time_elements_tuple: - number_of_elements = len(time_elements_tuple) - if number_of_elements < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - microseconds = time_elements_tuple[6] - time_elements_tuple = time_elements_tuple[:6] - - if (microseconds < 0 or - microseconds >= definitions.MICROSECONDS_PER_SECOND): - raise ValueError('Invalid number of microseconds.') - - fraction_of_second = ( - decimal.Decimal(microseconds) / definitions.MICROSECONDS_PER_SECOND) - - super().__init__( - fraction_of_second=fraction_of_second, is_delta=is_delta, - precision=precision or definitions.PRECISION_1_MICROSECOND, - time_elements_tuple=time_elements_tuple, - time_zone_offset=time_zone_offset) - - @property - def microseconds(self): - """int: number of microseconds.""" - return int(self.fraction_of_second * definitions.MICROSECONDS_PER_SECOND) - - def CopyFromStringTuple(self, time_elements_tuple): - """Copies time elements from string-based time elements tuple. - - Args: - time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and microseconds. - - Raises: - ValueError: if the time elements tuple is invalid. + """Time elements in microseconds. + + Attributes: + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.0 and 1.0. + is_local_time (bool): True if the date and time value is in local time. + precision (str): precision of the date of the date and time value, that + represents 1 microsecond (PRECISION_1_MICROSECOND). """ - number_of_elements = len(time_elements_tuple) - if len(time_elements_tuple) < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - year, month, day_of_month, hours, minutes, seconds, microseconds = ( - time_elements_tuple) - - try: - microseconds = int(microseconds, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid microsecond value: {microseconds!s}') - - if microseconds < 0 or microseconds >= definitions.MICROSECONDS_PER_SECOND: - raise ValueError('Invalid number of microseconds.') - - fraction_of_second = ( - decimal.Decimal(microseconds) / definitions.MICROSECONDS_PER_SECOND) - - time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds, - str(fraction_of_second)) - - super().CopyFromStringTuple( - time_elements_tuple) - - 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 - missing. - - Raises: - ValueError: if the instance is not a date time delta. - """ - if not self._is_delta: - raise ValueError('Not a date time delta.') - - if self._time_elements_tuple is None: - return None - - delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) - - time_elements_tuple = ( - 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) + def __init__( + self, + is_delta=False, + precision=None, + time_elements_tuple=None, + time_zone_offset=None, + ): + """Initializes time elements. + + Args: + 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 + should be one of the PRECISION_VALUES in definitions. + time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and microseconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + fraction_of_second = None + if time_elements_tuple: + number_of_elements = len(time_elements_tuple) + if number_of_elements < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + microseconds = time_elements_tuple[6] + time_elements_tuple = time_elements_tuple[:6] + + if microseconds < 0 or microseconds >= definitions.MICROSECONDS_PER_SECOND: + raise ValueError("Invalid number of microseconds.") + + fraction_of_second = ( + decimal.Decimal(microseconds) / definitions.MICROSECONDS_PER_SECOND + ) + + super().__init__( + fraction_of_second=fraction_of_second, + is_delta=is_delta, + precision=precision or definitions.PRECISION_1_MICROSECOND, + time_elements_tuple=time_elements_tuple, + time_zone_offset=time_zone_offset, + ) + + @property + def microseconds(self): + """int: number of microseconds.""" + return int(self.fraction_of_second * definitions.MICROSECONDS_PER_SECOND) + + def CopyFromStringTuple(self, time_elements_tuple): + """Copies time elements from string-based time elements tuple. + + Args: + time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and microseconds. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + number_of_elements = len(time_elements_tuple) + if len(time_elements_tuple) < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + year, month, day_of_month, hours, minutes, seconds, microseconds = ( + time_elements_tuple + ) + + try: + microseconds = int(microseconds, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid microsecond value: {microseconds!s}") + + if microseconds < 0 or microseconds >= definitions.MICROSECONDS_PER_SECOND: + raise ValueError("Invalid number of microseconds.") + + fraction_of_second = ( + decimal.Decimal(microseconds) / definitions.MICROSECONDS_PER_SECOND + ) + + time_elements_tuple = ( + year, + month, + day_of_month, + hours, + minutes, + seconds, + str(fraction_of_second), + ) + + super().CopyFromStringTuple(time_elements_tuple) + + 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 + missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + if not self._is_delta: + raise ValueError("Not a date time delta.") + + if self._time_elements_tuple is None: + return None + + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( + self._time_elements_tuple + ) + + time_elements_tuple = ( + 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) class TimeElementsInNanoseconds(TimeElementsWithFractionOfSecond): - """Time elements in nanoseconds. - - Attributes: - fraction_of_second (decimal.Decimal): fraction of second, which must be a - value between 0.0 and 1.0. - is_local_time (bool): True if the date and time value is in local time. - precision (str): precision of the date of the date and time value, that - represents 1 nanosecond (PRECISION_1_NANOSECOND). - """ - - def __init__( - self, is_delta=False, precision=None, time_elements_tuple=None, - time_zone_offset=None): - """Initializes time elements. - - Args: - 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 - should be one of the PRECISION_VALUES in definitions. - time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and nanoseconds. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - fraction_of_second = None - if time_elements_tuple: - number_of_elements = len(time_elements_tuple) - if number_of_elements < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - nanoseconds = time_elements_tuple[6] - time_elements_tuple = time_elements_tuple[:6] - - if (nanoseconds < 0 or - nanoseconds >= definitions.NANOSECONDS_PER_SECOND): - raise ValueError('Invalid number of nanoseconds.') - - fraction_of_second = ( - decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND) - - super().__init__( - fraction_of_second=fraction_of_second, is_delta=is_delta, - precision=precision or definitions.PRECISION_1_NANOSECOND, - time_elements_tuple=time_elements_tuple, - time_zone_offset=time_zone_offset) - - @property - def nanoseconds(self): - """int: number of nanoseconds.""" - return int(self.fraction_of_second * definitions.NANOSECONDS_PER_SECOND) - - def CopyFromStringTuple(self, time_elements_tuple): - """Copies time elements from string-based time elements tuple. - - Args: - time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): - time elements, contains year, month, day of month, hours, minutes, - seconds and nanoseconds. - - Raises: - ValueError: if the time elements tuple is invalid. - """ - number_of_elements = len(time_elements_tuple) - if len(time_elements_tuple) < 7: - raise ValueError(( - f'Invalid time elements tuple at least 7 elements required,' - f'got: {number_of_elements:d}')) - - year, month, day_of_month, hours, minutes, seconds, nanoseconds = ( - time_elements_tuple) - - try: - nanoseconds = int(nanoseconds, 10) - except (TypeError, ValueError): - raise ValueError(f'Invalid nanosecond value: {nanoseconds!s}') - - if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: - raise ValueError('Invalid number of nanoseconds.') - - fraction_of_second = ( - decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND) - - time_elements_tuple = ( - year, month, day_of_month, hours, minutes, seconds, - str(fraction_of_second)) - - super().CopyFromStringTuple( - time_elements_tuple) - - 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: - TimeElementsInNanoseconds: time elements or None if time elements are - missing. - - Raises: - ValueError: if the instance is not a date time delta. + """Time elements in nanoseconds. + + Attributes: + fraction_of_second (decimal.Decimal): fraction of second, which must be a + value between 0.0 and 1.0. + is_local_time (bool): True if the date and time value is in local time. + precision (str): precision of the date of the date and time value, that + represents 1 nanosecond (PRECISION_1_NANOSECOND). """ - if not self._is_delta: - raise ValueError('Not a date time delta.') - - if self._time_elements_tuple is None: - return None - - delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( - self._time_elements_tuple) - time_elements_tuple = ( - year + delta_year, month + delta_month, - day_of_month + delta_day_of_month, hours, minutes, seconds, - self.nanoseconds) - - return TimeElementsInNanoseconds( - 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: - TimeElementsInNanoseconds: 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) + def __init__( + self, + is_delta=False, + precision=None, + time_elements_tuple=None, + time_zone_offset=None, + ): + """Initializes time elements. + + Args: + 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 + should be one of the PRECISION_VALUES in definitions. + time_elements_tuple (Optional[tuple[int, int, int, int, int, int, int]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and nanoseconds. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + fraction_of_second = None + if time_elements_tuple: + number_of_elements = len(time_elements_tuple) + if number_of_elements < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + nanoseconds = time_elements_tuple[6] + time_elements_tuple = time_elements_tuple[:6] + + if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: + raise ValueError("Invalid number of nanoseconds.") + + fraction_of_second = ( + decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND + ) + + super().__init__( + fraction_of_second=fraction_of_second, + is_delta=is_delta, + precision=precision or definitions.PRECISION_1_NANOSECOND, + time_elements_tuple=time_elements_tuple, + time_zone_offset=time_zone_offset, + ) + + @property + def nanoseconds(self): + """int: number of nanoseconds.""" + return int(self.fraction_of_second * definitions.NANOSECONDS_PER_SECOND) + + def CopyFromStringTuple(self, time_elements_tuple): + """Copies time elements from string-based time elements tuple. + + Args: + time_elements_tuple (Optional[tuple[str, str, str, str, str, str, str]]): + time elements, contains year, month, day of month, hours, minutes, + seconds and nanoseconds. + + Raises: + ValueError: if the time elements tuple is invalid. + """ + number_of_elements = len(time_elements_tuple) + if len(time_elements_tuple) < 7: + raise ValueError( + ( + f"Invalid time elements tuple at least 7 elements required," + f"got: {number_of_elements:d}" + ) + ) + + year, month, day_of_month, hours, minutes, seconds, nanoseconds = ( + time_elements_tuple + ) + + try: + nanoseconds = int(nanoseconds, 10) + except (TypeError, ValueError): + raise ValueError(f"Invalid nanosecond value: {nanoseconds!s}") + + if nanoseconds < 0 or nanoseconds >= definitions.NANOSECONDS_PER_SECOND: + raise ValueError("Invalid number of nanoseconds.") + + fraction_of_second = ( + decimal.Decimal(nanoseconds) / definitions.NANOSECONDS_PER_SECOND + ) + + time_elements_tuple = ( + year, + month, + day_of_month, + hours, + minutes, + seconds, + str(fraction_of_second), + ) + + super().CopyFromStringTuple(time_elements_tuple) + + 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: + TimeElementsInNanoseconds: time elements or None if time elements are + missing. + + Raises: + ValueError: if the instance is not a date time delta. + """ + if not self._is_delta: + raise ValueError("Not a date time delta.") + + if self._time_elements_tuple is None: + return None + + delta_year, delta_month, delta_day_of_month, hours, minutes, seconds = ( + self._time_elements_tuple + ) + + time_elements_tuple = ( + year + delta_year, + month + delta_month, + day_of_month + delta_day_of_month, + hours, + minutes, + seconds, + self.nanoseconds, + ) + + return TimeElementsInNanoseconds( + 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: + TimeElementsInNanoseconds: 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) diff --git a/dfdatetime/uuid_time.py b/dfdatetime/uuid_time.py index 420ccb7..dc0267f 100644 --- a/dfdatetime/uuid_time.py +++ b/dfdatetime/uuid_time.py @@ -8,139 +8,152 @@ class UUIDTimeEpoch(interface.DateTimeEpoch): - """UUID version 1 time epoch.""" + """UUID version 1 time epoch.""" - def __init__(self): - """Initializes an UUID version 1 time epoch.""" - super().__init__(1582, 10, 15) + def __init__(self): + """Initializes an UUID version 1 time epoch.""" + super().__init__(1582, 10, 15) class UUIDTime(interface.DateTimeValues): - """UUID version 1 timestamp. + """UUID version 1 timestamp. - The UUID version 1 timestamp is an unsigned 60-bit value that contains - the number of 100th nano seconds intervals since 1582-10-15 00:00:00. + The UUID version 1 timestamp is an unsigned 60-bit value that contains + the number of 100th nano seconds intervals since 1582-10-15 00:00:00. - Also see: - https://en.wikipedia.org/wiki/Universally_unique_identifier + Also see: + https://en.wikipedia.org/wiki/Universally_unique_identifier - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = UUIDTimeEpoch() - - # The difference between October 15, 1582 and January 1, 1970 in seconds. - _UUID_TO_POSIX_BASE = 12219292800 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes an UUID version 1 timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): UUID version 1 timestamp. - - Raises: - ValueError: if the UUID version 1 timestamp is invalid. - """ - if timestamp and (timestamp < 0 or timestamp > self._UINT60_MAX): - raise ValueError('Invalid UUID version 1 timestamp.') - - super().__init__( - precision=precision or definitions.PRECISION_100_NANOSECONDS, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """int: UUID timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second - used for increased precision, or None if the normalized timestamp - cannot be determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= 0 and - self._timestamp <= self._UINT60_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND) - self._normalized_timestamp -= self._UUID_TO_POSIX_BASE - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies an UUID timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - if year < 1582: - raise ValueError('Year value not supported.') - - nanoseconds, _ = divmod(nanoseconds, 100) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp += self._UUID_TO_POSIX_BASE - timestamp *= self._100_NANOSECONDS_PER_SECOND - timestamp += nanoseconds - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the UUID timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#######" or - None if the timestamp is missing or invalid. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - if (self._timestamp is None or self._timestamp < 0 or - self._timestamp > self._UINT60_MAX): - return None - - timestamp, fraction_of_second = divmod( - self._timestamp, self._100_NANOSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}') + _EPOCH = UUIDTimeEpoch() + + # The difference between October 15, 1582 and January 1, 1970 in seconds. + _UUID_TO_POSIX_BASE = 12219292800 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes an UUID version 1 timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): UUID version 1 timestamp. + + Raises: + ValueError: if the UUID version 1 timestamp is invalid. + """ + if timestamp and (timestamp < 0 or timestamp > self._UINT60_MAX): + raise ValueError("Invalid UUID version 1 timestamp.") + + super().__init__( + precision=precision or definitions.PRECISION_100_NANOSECONDS, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """int: UUID timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second + used for increased precision, or None if the normalized timestamp + cannot be determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= 0 + and self._timestamp <= self._UINT60_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND + ) + self._normalized_timestamp -= self._UUID_TO_POSIX_BASE + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies an UUID timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + if year < 1582: + raise ValueError("Year value not supported.") + + nanoseconds, _ = divmod(nanoseconds, 100) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp += self._UUID_TO_POSIX_BASE + timestamp *= self._100_NANOSECONDS_PER_SECOND + timestamp += nanoseconds + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the UUID timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#######" or + None if the timestamp is missing or invalid. + """ + if ( + self._timestamp is None + or self._timestamp < 0 + or self._timestamp > self._UINT60_MAX + ): + return None + + timestamp, fraction_of_second = divmod( + self._timestamp, self._100_NANOSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}" + ) factory.Factory.RegisterDateTimeValues(UUIDTime) diff --git a/dfdatetime/webkit_time.py b/dfdatetime/webkit_time.py index c5db4ab..7b33b3c 100644 --- a/dfdatetime/webkit_time.py +++ b/dfdatetime/webkit_time.py @@ -8,128 +8,140 @@ class WebKitTimeEpoch(interface.DateTimeEpoch): - """WebKit time epoch.""" + """WebKit time epoch.""" - def __init__(self): - """Initializes a WebKit time epoch.""" - super().__init__(1601, 1, 1) + def __init__(self): + """Initializes a WebKit time epoch.""" + super().__init__(1601, 1, 1) class WebKitTime(interface.DateTimeValues): - """WebKit timestamp. + """WebKit timestamp. - The WebKit timestamp is a signed 64-bit integer that contains the number of - microseconds since 1601-01-01 00:00:00. + The WebKit timestamp is a signed 64-bit integer that contains the number of + microseconds since 1601-01-01 00:00:00. - Attributes: - is_local_time (bool): True if the date and time value is in local time. - """ - - _EPOCH = WebKitTimeEpoch() - - # The difference between January 1, 1601 and January 1, 1970 in seconds. - _WEBKIT_TO_POSIX_BASE = 11644473600 - - def __init__(self, precision=None, time_zone_offset=None, timestamp=None): - """Initializes a WebKit timestamp. - - Args: - precision (Optional[str]): precision of the date and time value, which - should be one of the PRECISION_VALUES in definitions. - time_zone_offset (Optional[int]): time zone offset in number of minutes - from UTC or None if not set. - timestamp (Optional[int]): WebKit timestamp. + Attributes: + is_local_time (bool): True if the date and time value is in local time. """ - super().__init__( - precision=precision or definitions.PRECISION_1_MICROSECOND, - time_zone_offset=time_zone_offset) - self._timestamp = timestamp - - @property - def timestamp(self): - """decimal.Decimal: WebKit timestamp or None if not set.""" - return self._timestamp - - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. - - Returns: - float: normalized timestamp, which contains the number of seconds since - January 1, 1970 00:00:00 and a fraction of second used for increased - precision, or None if the normalized timestamp cannot be determined. - """ - if self._normalized_timestamp is None: - if (self._timestamp is not None and self._timestamp >= self._INT64_MIN and - self._timestamp <= self._INT64_MAX): - self._normalized_timestamp = ( - decimal.Decimal(self._timestamp) / - definitions.MICROSECONDS_PER_SECOND) - self._normalized_timestamp -= self._WEBKIT_TO_POSIX_BASE - - if self._time_zone_offset: - self._normalized_timestamp -= self._time_zone_offset * 60 - - return self._normalized_timestamp - - def CopyFromDateTimeString(self, time_string): - """Copies a WebKit timestamp from a date and time string. - - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## - - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3, 6 or 9 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. - - Raises: - ValueError: if the time string is invalid or not supported. - """ - date_time_values = self._CopyDateTimeFromString(time_string) - - year = date_time_values.get('year', 0) - month = date_time_values.get('month', 0) - day_of_month = date_time_values.get('day_of_month', 0) - hours = date_time_values.get('hours', 0) - minutes = date_time_values.get('minutes', 0) - seconds = date_time_values.get('seconds', 0) - nanoseconds = date_time_values.get('nanoseconds', 0) - time_zone_offset = date_time_values.get('time_zone_offset') - - microseconds, _ = divmod( - nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) - - timestamp = self._GetNumberOfSecondsFromElements( - year, month, day_of_month, hours, minutes, seconds) - timestamp += self._WEBKIT_TO_POSIX_BASE - timestamp *= definitions.MICROSECONDS_PER_SECOND - timestamp += microseconds - - self._normalized_timestamp = None - self._timestamp = timestamp - self._time_zone_offset = time_zone_offset - - def CopyToDateTimeString(self): - """Copies the WebKit timestamp to a date and time string. - - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp is missing or invalid. - """ - if (self._timestamp is None or self._timestamp < self._INT64_MIN or - self._timestamp > self._INT64_MAX): - return None - - timestamp, microseconds = divmod( - self._timestamp, definitions.MICROSECONDS_PER_SECOND) - number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) - - year, month, day_of_month = self._GetDateValuesWithEpoch( - number_of_days, self._EPOCH) - return (f'{year:04d}-{month:02d}-{day_of_month:02d} ' - f'{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}') + _EPOCH = WebKitTimeEpoch() + + # The difference between January 1, 1601 and January 1, 1970 in seconds. + _WEBKIT_TO_POSIX_BASE = 11644473600 + + def __init__(self, precision=None, time_zone_offset=None, timestamp=None): + """Initializes a WebKit timestamp. + + Args: + precision (Optional[str]): precision of the date and time value, which + should be one of the PRECISION_VALUES in definitions. + time_zone_offset (Optional[int]): time zone offset in number of minutes + from UTC or None if not set. + timestamp (Optional[int]): WebKit timestamp. + """ + super().__init__( + precision=precision or definitions.PRECISION_1_MICROSECOND, + time_zone_offset=time_zone_offset, + ) + self._timestamp = timestamp + + @property + def timestamp(self): + """decimal.Decimal: WebKit timestamp or None if not set.""" + return self._timestamp + + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. + + Returns: + float: normalized timestamp, which contains the number of seconds since + January 1, 1970 00:00:00 and a fraction of second used for increased + precision, or None if the normalized timestamp cannot be determined. + """ + if self._normalized_timestamp is None: + if ( + self._timestamp is not None + and self._timestamp >= self._INT64_MIN + and self._timestamp <= self._INT64_MAX + ): + self._normalized_timestamp = ( + decimal.Decimal(self._timestamp) + / definitions.MICROSECONDS_PER_SECOND + ) + self._normalized_timestamp -= self._WEBKIT_TO_POSIX_BASE + + if self._time_zone_offset: + self._normalized_timestamp -= self._time_zone_offset * 60 + + return self._normalized_timestamp + + def CopyFromDateTimeString(self, time_string): + """Copies a WebKit timestamp from a date and time string. + + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## + + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3, 6 or 9 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. + + Raises: + ValueError: if the time string is invalid or not supported. + """ + date_time_values = self._CopyDateTimeFromString(time_string) + + year = date_time_values.get("year", 0) + month = date_time_values.get("month", 0) + day_of_month = date_time_values.get("day_of_month", 0) + hours = date_time_values.get("hours", 0) + minutes = date_time_values.get("minutes", 0) + seconds = date_time_values.get("seconds", 0) + nanoseconds = date_time_values.get("nanoseconds", 0) + time_zone_offset = date_time_values.get("time_zone_offset") + + microseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND) + + timestamp = self._GetNumberOfSecondsFromElements( + year, month, day_of_month, hours, minutes, seconds + ) + timestamp += self._WEBKIT_TO_POSIX_BASE + timestamp *= definitions.MICROSECONDS_PER_SECOND + timestamp += microseconds + + self._normalized_timestamp = None + self._timestamp = timestamp + self._time_zone_offset = time_zone_offset + + def CopyToDateTimeString(self): + """Copies the WebKit timestamp to a date and time string. + + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp is missing or invalid. + """ + if ( + self._timestamp is None + or self._timestamp < self._INT64_MIN + or self._timestamp > self._INT64_MAX + ): + return None + + timestamp, microseconds = divmod( + self._timestamp, definitions.MICROSECONDS_PER_SECOND + ) + number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp) + + year, month, day_of_month = self._GetDateValuesWithEpoch( + number_of_days, self._EPOCH + ) + + return ( + f"{year:04d}-{month:02d}-{day_of_month:02d} " + f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}" + ) factory.Factory.RegisterDateTimeValues(WebKitTime) diff --git a/docs/conf.py b/docs/conf.py index 06e68d4..b620b3d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,30 +9,29 @@ from docutils import transforms # Change PYTHONPATH to include dfdatetime module and dependencies. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) import dfdatetime # pylint: disable=wrong-import-position import utils.dependencies # pylint: disable=wrong-import-position - # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '2.0.1' +needs_sphinx = "2.0.1" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'recommonmark', - 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', - 'sphinx.ext.doctest', - 'sphinx.ext.napoleon', - 'sphinx.ext.viewcode', - 'sphinx_markdown_tables', - 'sphinx_rtd_theme', + "recommonmark", + "sphinx.ext.autodoc", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx_markdown_tables", + "sphinx_rtd_theme", ] # We cannot install architecture dependent Python modules on readthedocs, @@ -40,8 +39,9 @@ pip_installed_modules = set() dependency_helper = utils.dependencies.DependencyHelper( - dependencies_file=os.path.join('..', 'dependencies.ini'), - test_dependencies_file=os.path.join('..', 'test_dependencies.ini')) + dependencies_file=os.path.join("..", "dependencies.ini"), + test_dependencies_file=os.path.join("..", "test_dependencies.ini"), +) modules_to_mock = set(dependency_helper.dependencies.keys()) modules_to_mock = modules_to_mock.difference(pip_installed_modules) @@ -57,39 +57,38 @@ # General information about the project. # pylint: disable=redefined-builtin -project = 'dfDateTime' -copyright = 'The dfDateTime authors' +project = "dfDateTime" +copyright = "The dfDateTime authors" version = dfdatetime.__version__ release = dfdatetime.__version__ # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The master toctree document. -master_doc = 'index' +master_doc = "index" # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Output file base name for HTML help builder. -htmlhelp_basename = 'dfdatetimedoc' +htmlhelp_basename = "dfdatetimedoc" # -- Options linkcheck ---------------------------------------------------- -linkcheck_ignore = [ -] +linkcheck_ignore = [] # -- Code to rewrite links for readthedocs -------------------------------- @@ -97,74 +96,74 @@ # This function is a Sphinx core event callback, the format of which is detailed # here: https://www.sphinx-doc.org/en/master/extdev/appapi.html#events + # pylint: disable=unused-argument def RunSphinxAPIDoc(app): - """Runs sphinx-apidoc to auto-generate documentation. + """Runs sphinx-apidoc to auto-generate documentation. - Args: - app (sphinx.application.Sphinx): Sphinx application. Required by the - the Sphinx event callback API. - """ - current_directory = os.path.abspath(os.path.dirname(__file__)) - module_path = os.path.join(current_directory, '..', 'dfdatetime') - api_directory = os.path.join(current_directory, 'sources', 'api') - apidoc.main(['-o', api_directory, module_path, '--force']) + Args: + app (sphinx.application.Sphinx): Sphinx application. Required by the + the Sphinx event callback API. + """ + current_directory = os.path.abspath(os.path.dirname(__file__)) + module_path = os.path.join(current_directory, "..", "dfdatetime") + api_directory = os.path.join(current_directory, "sources", "api") + apidoc.main(["-o", api_directory, module_path, "--force"]) class MarkdownLinkFixer(transforms.Transform): - """Transform definition to parse .md references to internal pages.""" + """Transform definition to parse .md references to internal pages.""" - default_priority = 1000 + default_priority = 1000 - _URI_PREFIXES = [] + _URI_PREFIXES = [] - def _FixLinks(self, node): - """Corrects links to .md files not part of the documentation. + def _FixLinks(self, node): + """Corrects links to .md files not part of the documentation. - Args: - node (docutils.nodes.Node): docutils node. + Args: + node (docutils.nodes.Node): docutils node. - Returns: - docutils.nodes.Node: docutils node, with correct URIs outside - of Markdown pages outside the documentation. - """ - if isinstance(node, nodes.reference) and 'refuri' in node: - reference_uri = node['refuri'] - for uri_prefix in self._URI_PREFIXES: - if (reference_uri.startswith(uri_prefix) and not ( - reference_uri.endswith('.asciidoc') or - reference_uri.endswith('.md'))): - node['refuri'] = reference_uri + '.md' - break + Returns: + docutils.nodes.Node: docutils node, with correct URIs outside + of Markdown pages outside the documentation. + """ + if isinstance(node, nodes.reference) and "refuri" in node: + reference_uri = node["refuri"] + for uri_prefix in self._URI_PREFIXES: + if reference_uri.startswith(uri_prefix) and not ( + reference_uri.endswith(".asciidoc") or reference_uri.endswith(".md") + ): + node["refuri"] = reference_uri + ".md" + break - return node + return node - def _Traverse(self, node): - """Traverses the document tree rooted at node. + def _Traverse(self, node): + """Traverses the document tree rooted at node. - Args: - node (docutils.nodes.Node): docutils node. - """ - self._FixLinks(node) + Args: + node (docutils.nodes.Node): docutils node. + """ + self._FixLinks(node) - for child_node in node.children: - self._Traverse(child_node) + for child_node in node.children: + self._Traverse(child_node) - # pylint: disable=arguments-differ - def apply(self): - """Applies this transform on document tree.""" - self._Traverse(self.document) + # pylint: disable=arguments-differ + def apply(self): + """Applies this transform on document tree.""" + self._Traverse(self.document) # pylint: invalid-name def setup(app): - """Called at Sphinx initialization. - - Args: - app (sphinx.application.Sphinx): Sphinx application. - """ - # Triggers sphinx-apidoc to generate API documentation. - app.connect('builder-inited', RunSphinxAPIDoc) - app.add_config_value( - 'recommonmark_config', {'enable_auto_toc_tree': True}, True) - app.add_transform(MarkdownLinkFixer) + """Called at Sphinx initialization. + + Args: + app (sphinx.application.Sphinx): Sphinx application. + """ + # Triggers sphinx-apidoc to generate API documentation. + app.connect("builder-inited", RunSphinxAPIDoc) + app.add_config_value("recommonmark_config", {"enable_auto_toc_tree": True}, True) + app.add_transform(MarkdownLinkFixer) diff --git a/pyproject.toml b/pyproject.toml index 59e6a3f..aa4e20c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "dfdatetime" -version = "20260513" +version = "20260515" description = "Digital Forensics date and time (dfDateTime)" maintainers = [ { name = "Log2Timeline maintainers", email = "log2timeline-maintainers@googlegroups.com" }, @@ -23,5 +23,10 @@ Documentation = "https://dfdatetime.readthedocs.io/en/latest" Homepage = "https://github.com/log2timeline/dfdatetime" Repository = "https://github.com/log2timeline/dfdatetime" +[tool.black] +line-length = 88 +target-version = ["py310"] +include = "\\.pyi?$" + [tool.setuptools] package-dir = {"dfdatetime" = "dfdatetime"} diff --git a/run_tests.py b/run_tests.py index 70955eb..b06dbbc 100755 --- a/run_tests.py +++ b/run_tests.py @@ -5,27 +5,26 @@ import unittest # Change PYTHONPATH to include dependencies. -sys.path.insert(0, '.') +sys.path.insert(0, ".") import utils.dependencies # pylint: disable=wrong-import-position +if __name__ == "__main__": + print(f"Using Python version {sys.version!s}") -if __name__ == '__main__': - print(f'Using Python version {sys.version!s}') + fail_unless_has_test_file = "--fail-unless-has-test-file" in sys.argv + setattr(unittest, "fail_unless_has_test_file", fail_unless_has_test_file) + if fail_unless_has_test_file: + # Remove --fail-unless-has-test-file otherwise it will conflict with + # the argparse tests. + sys.argv.remove("--fail-unless-has-test-file") - fail_unless_has_test_file = '--fail-unless-has-test-file' in sys.argv - setattr(unittest, 'fail_unless_has_test_file', fail_unless_has_test_file) - if fail_unless_has_test_file: - # Remove --fail-unless-has-test-file otherwise it will conflict with - # the argparse tests. - sys.argv.remove('--fail-unless-has-test-file') + dependency_helper = utils.dependencies.DependencyHelper() - dependency_helper = utils.dependencies.DependencyHelper() + if not dependency_helper.CheckTestDependencies(): + sys.exit(1) - if not dependency_helper.CheckTestDependencies(): - sys.exit(1) - - test_suite = unittest.TestLoader().discover('tests', pattern='*.py') - test_results = unittest.TextTestRunner(verbosity=2).run(test_suite) - if not test_results.wasSuccessful(): - sys.exit(1) + test_suite = unittest.TestLoader().discover("tests", pattern="*.py") + test_results = unittest.TextTestRunner(verbosity=2).run(test_suite) + if not test_results.wasSuccessful(): + sys.exit(1) diff --git a/tests/apfs_time.py b/tests/apfs_time.py index 76e1191..49ee91a 100644 --- a/tests/apfs_time.py +++ b/tests/apfs_time.py @@ -8,65 +8,63 @@ class APFSTimeTest(unittest.TestCase): - """Tests for the APFS timestamp.""" + """Tests for the APFS timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) - normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281643591.987654321')) + normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.987654321")) - apfs_time_object = apfs_time.APFSTime( - time_zone_offset=60, timestamp=1281643591987654321) + apfs_time_object = apfs_time.APFSTime( + time_zone_offset=60, timestamp=1281643591987654321 + ) - normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.987654321')) + normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.987654321")) - apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) - apfs_time_object.time_zone_offset = 60 + apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) + apfs_time_object.time_zone_offset = 60 - normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.987654321')) + normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.987654321")) - apfs_time_object = apfs_time.APFSTime() + apfs_time_object = apfs_time.APFSTime() - normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = apfs_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - apfs_time_object = apfs_time.APFSTime(timestamp=9223372036854775810) + apfs_time_object = apfs_time.APFSTime(timestamp=9223372036854775810) - date_time_string = apfs_time_object._GetNormalizedTimestamp() - self.assertIsNone(date_time_string) + date_time_string = apfs_time_object._GetNormalizedTimestamp() + self.assertIsNone(date_time_string) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - apfs_time_object = apfs_time.APFSTime() - with self.assertRaises(ValueError): - apfs_time_object.CopyFromDateTimeString('2554-07-21 23:34:34.000000') + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + apfs_time_object = apfs_time.APFSTime() + with self.assertRaises(ValueError): + apfs_time_object.CopyFromDateTimeString("2554-07-21 23:34:34.000000") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + apfs_time_object = apfs_time.APFSTime(timestamp=1281643591987654321) - date_time_string = apfs_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.987654321') + date_time_string = apfs_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.987654321") - apfs_time_object = apfs_time.APFSTime(timestamp=9223372036854775810) + apfs_time_object = apfs_time.APFSTime(timestamp=9223372036854775810) - date_time_string = apfs_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = apfs_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - apfs_time_object = apfs_time.APFSTime() + apfs_time_object = apfs_time.APFSTime() - date_time_string = apfs_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = apfs_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/cocoa_time.py b/tests/cocoa_time.py index e98900b..92845a7 100644 --- a/tests/cocoa_time.py +++ b/tests/cocoa_time.py @@ -8,156 +8,158 @@ class CocoaTimeEpochTest(unittest.TestCase): - """Tests for the Cocoa time epoch.""" + """Tests for the Cocoa time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - cocoa_time_epoch = cocoa_time.CocoaTimeEpoch() - self.assertIsNotNone(cocoa_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + cocoa_time_epoch = cocoa_time.CocoaTimeEpoch() + self.assertIsNotNone(cocoa_time_epoch) class CocoaTimeTest(unittest.TestCase): - """Tests for the Cocoa timestamp.""" + """Tests for the Cocoa timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) - self.assertEqual(cocoa_time_object.timestamp, 395011845.0) + def testProperties(self): + """Tests the properties.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) + self.assertEqual(cocoa_time_object.timestamp, 395011845.0) - cocoa_time_object = cocoa_time.CocoaTime() - self.assertIsNone(cocoa_time_object.timestamp) + cocoa_time_object = cocoa_time.CocoaTime() + self.assertIsNone(cocoa_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) - normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1373319045.0')) + normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1373319045.0")) - cocoa_time_object = cocoa_time.CocoaTime( - time_zone_offset=60, timestamp=395011845.0) + cocoa_time_object = cocoa_time.CocoaTime( + time_zone_offset=60, timestamp=395011845.0 + ) - normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1373315445.0')) + normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1373315445.0")) - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) - cocoa_time_object.time_zone_offset = 60 + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) + cocoa_time_object.time_zone_offset = 60 - normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1373315445.0')) + normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1373315445.0")) - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = cocoa_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - cocoa_time_object = cocoa_time.CocoaTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + cocoa_time_object = cocoa_time.CocoaTime() - cocoa_time_object.CopyFromDateTimeString('2013-07-08') - self.assertEqual(cocoa_time_object._timestamp, 394934400.0) - self.assertEqual(cocoa_time_object._time_zone_offset, None) + cocoa_time_object.CopyFromDateTimeString("2013-07-08") + self.assertEqual(cocoa_time_object._timestamp, 394934400.0) + self.assertEqual(cocoa_time_object._time_zone_offset, None) - cocoa_time_object.CopyFromDateTimeString('2013-07-08 21:30:45') - self.assertEqual(cocoa_time_object._timestamp, 395011845.0) - self.assertEqual(cocoa_time_object._time_zone_offset, None) + cocoa_time_object.CopyFromDateTimeString("2013-07-08 21:30:45") + self.assertEqual(cocoa_time_object._timestamp, 395011845.0) + self.assertEqual(cocoa_time_object._time_zone_offset, None) - cocoa_time_object.CopyFromDateTimeString('2013-07-08 21:30:45.546875') - self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) - self.assertEqual(cocoa_time_object._time_zone_offset, None) + cocoa_time_object.CopyFromDateTimeString("2013-07-08 21:30:45.546875") + self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) + self.assertEqual(cocoa_time_object._time_zone_offset, None) - cocoa_time_object.CopyFromDateTimeString('2013-07-08 21:30:45.546875-01:00') - self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) - self.assertEqual(cocoa_time_object._time_zone_offset, -60) + cocoa_time_object.CopyFromDateTimeString("2013-07-08 21:30:45.546875-01:00") + self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) + self.assertEqual(cocoa_time_object._time_zone_offset, -60) - cocoa_time_object.CopyFromDateTimeString('2013-07-08 21:30:45.546875+01:00') - self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) - self.assertEqual(cocoa_time_object._time_zone_offset, 60) + cocoa_time_object.CopyFromDateTimeString("2013-07-08 21:30:45.546875+01:00") + self.assertEqual(cocoa_time_object._timestamp, 395011845.546875) + self.assertEqual(cocoa_time_object._time_zone_offset, 60) - cocoa_time_object.CopyFromDateTimeString('2001-01-02 00:00:00') - self.assertEqual(cocoa_time_object._timestamp, 86400.0) - self.assertEqual(cocoa_time_object._time_zone_offset, None) + cocoa_time_object.CopyFromDateTimeString("2001-01-02 00:00:00") + self.assertEqual(cocoa_time_object._timestamp, 86400.0) + self.assertEqual(cocoa_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) - date_time_string = cocoa_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2013-07-08 21:30:45.546875') + date_time_string = cocoa_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2013-07-08 21:30:45.546875") - epoch_year = cocoa_time_object._EPOCH.year - cocoa_time_object._EPOCH.year = -1 + epoch_year = cocoa_time_object._EPOCH.year + cocoa_time_object._EPOCH.year = -1 - with self.assertRaises(ValueError): - cocoa_time_object.CopyToDateTimeString() + with self.assertRaises(ValueError): + cocoa_time_object.CopyToDateTimeString() - cocoa_time_object._EPOCH.year = epoch_year + cocoa_time_object._EPOCH.year = epoch_year - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - date_time_string = cocoa_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = cocoa_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) - date_time_string = cocoa_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2013-07-08T21:30:45.546875+00:00') + date_time_string = cocoa_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2013-07-08T21:30:45.546875+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) + def testGetDate(self): + """Tests the GetDate function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) - date_tuple = cocoa_time_object.GetDate() - self.assertEqual(date_tuple, (2013, 7, 8)) + date_tuple = cocoa_time_object.GetDate() + self.assertEqual(date_tuple, (2013, 7, 8)) - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - date_tuple = cocoa_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = cocoa_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) - date_with_time_of_day_tuple = cocoa_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2013, 7, 8, 21, 30, 45)) + date_with_time_of_day_tuple = cocoa_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2013, 7, 8, 21, 30, 45)) - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - date_with_time_of_day_tuple = cocoa_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = cocoa_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - # TODO: remove this method when there is no more need for it in Plaso. - def testGetPlasoTimestamp(self): - """Tests the GetPlasoTimestamp function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) + # TODO: remove this method when there is no more need for it in Plaso. + def testGetPlasoTimestamp(self): + """Tests the GetPlasoTimestamp function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.0) - micro_posix_timestamp = cocoa_time_object.GetPlasoTimestamp() - self.assertEqual(micro_posix_timestamp, 1373319045000000) + micro_posix_timestamp = cocoa_time_object.GetPlasoTimestamp() + self.assertEqual(micro_posix_timestamp, 1373319045000000) - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - micro_posix_timestamp = cocoa_time_object.GetPlasoTimestamp() - self.assertIsNone(micro_posix_timestamp) + micro_posix_timestamp = cocoa_time_object.GetPlasoTimestamp() + self.assertIsNone(micro_posix_timestamp) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875) - time_of_day_tuple = cocoa_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (21, 30, 45)) + time_of_day_tuple = cocoa_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (21, 30, 45)) - cocoa_time_object = cocoa_time.CocoaTime() + cocoa_time_object = cocoa_time.CocoaTime() - time_of_day_tuple = cocoa_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = cocoa_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/decorators.py b/tests/decorators.py index 0111de4..b612fa4 100644 --- a/tests/decorators.py +++ b/tests/decorators.py @@ -8,37 +8,37 @@ class TestClass: - """Class for testing deprecated decorator.""" + """Class for testing deprecated decorator.""" - def Method(self): - """Test method.""" - return 'result' + def Method(self): + """Test method.""" + return "result" - @decorators.deprecated - def DeprecatedMethod(self): - """Deprecated test method.""" - return 'deprecated_result' + @decorators.deprecated + def DeprecatedMethod(self): + """Deprecated test method.""" + return "deprecated_result" class DeprecatedTest(unittest.TestCase): - """Tests for the deprecated decorator.""" + """Tests for the deprecated decorator.""" - def test_deprecated(self): - """Tests the deprecated decorator.""" - test_object = TestClass() + def test_deprecated(self): + """Tests the deprecated decorator.""" + test_object = TestClass() - result = test_object.Method() - self.assertEqual(result, 'result') + result = test_object.Method() + self.assertEqual(result, "result") - with warnings.catch_warnings(record=True) as warning: - warnings.simplefilter('always', DeprecationWarning) + with warnings.catch_warnings(record=True) as warning: + warnings.simplefilter("always", DeprecationWarning) - result = test_object.DeprecatedMethod() + result = test_object.DeprecatedMethod() - self.assertEqual(result, 'deprecated_result') - self.assertEqual(len(warning), 1) - self.assertIn('DeprecatedMethod', str(warning[0].message)) + self.assertEqual(result, "deprecated_result") + self.assertEqual(len(warning), 1) + self.assertIn("DeprecatedMethod", str(warning[0].message)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/delphi_date_time.py b/tests/delphi_date_time.py index c6ea886..fd4e344 100644 --- a/tests/delphi_date_time.py +++ b/tests/delphi_date_time.py @@ -8,212 +8,221 @@ class DelphiDateTimeEpochTest(unittest.TestCase): - """Tests for the Delphi TDateTime epoch.""" + """Tests for the Delphi TDateTime epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - delphi_date_time_epoch = delphi_date_time.DelphiDateTimeEpoch() - self.assertIsNotNone(delphi_date_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + delphi_date_time_epoch = delphi_date_time.DelphiDateTimeEpoch() + self.assertIsNotNone(delphi_date_time_epoch) class DelphiDateTimeInvalidYear(delphi_date_time.DelphiDateTime): - """Delphi TDateTime timestamp for testing invalid year.""" + """Delphi TDateTime timestamp for testing invalid year.""" - def _CopyDateTimeFromString(self, time_string): - """Copies a date and time from a string. + def _CopyDateTimeFromString(self, time_string): + """Copies a date and time from a string. - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3 or 6 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3 or 6 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, microseconds. + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, microseconds. - Raises: - ValueError: if the time string is invalid or not supported. - """ - return { - 'year': 10000, - 'month': 1, - 'day_of_month': 2, - 'hours': 0, - 'minutes': 0, - 'seconds': 0} + Raises: + ValueError: if the time string is invalid or not supported. + """ + return { + "year": 10000, + "month": 1, + "day_of_month": 2, + "hours": 0, + "minutes": 0, + "seconds": 0, + } class DelphiDateTimeTest(unittest.TestCase): - """Tests for the Delphi TDateTime timestamp.""" + """Tests for the Delphi TDateTime timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) - self.assertEqual(delphi_date_time_object.timestamp, 41443.8263953) + def testProperties(self): + """Tests the properties.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) + self.assertEqual(delphi_date_time_object.timestamp, 41443.8263953) - delphi_date_time_object = delphi_date_time.DelphiDateTime() - self.assertIsNone(delphi_date_time_object.timestamp) + delphi_date_time_object = delphi_date_time.DelphiDateTime() + self.assertIsNone(delphi_date_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - expected_normalized_timestamp = decimal.Decimal( - '1371585000.553919887170195579') - normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + expected_normalized_timestamp = decimal.Decimal("1371585000.553919887170195579") + normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - delphi_date_time_object = delphi_date_time.DelphiDateTime( - time_zone_offset=60, timestamp=41443.8263953) + delphi_date_time_object = delphi_date_time.DelphiDateTime( + time_zone_offset=60, timestamp=41443.8263953 + ) - expected_normalized_timestamp = decimal.Decimal( - '1371581400.553919887170195579') - normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + expected_normalized_timestamp = decimal.Decimal("1371581400.553919887170195579") + normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) - delphi_date_time_object.time_zone_offset = 60 + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) + delphi_date_time_object.time_zone_offset = 60 - expected_normalized_timestamp = decimal.Decimal( - '1371581400.553919887170195579') - normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + expected_normalized_timestamp = decimal.Decimal("1371581400.553919887170195579") + normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = delphi_date_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime() - delphi_date_time_object.CopyFromDateTimeString('2013-06-18') - self.assertEqual(delphi_date_time_object._timestamp, 41443.0) - self.assertEqual(delphi_date_time_object._time_zone_offset, None) + delphi_date_time_object.CopyFromDateTimeString("2013-06-18") + self.assertEqual(delphi_date_time_object._timestamp, 41443.0) + self.assertEqual(delphi_date_time_object._time_zone_offset, None) - delphi_date_time_object.CopyFromDateTimeString('2013-06-18 19:50:00') - self.assertEqual(delphi_date_time_object._timestamp, 41443.82638888889) - self.assertEqual(delphi_date_time_object._time_zone_offset, None) + delphi_date_time_object.CopyFromDateTimeString("2013-06-18 19:50:00") + self.assertEqual(delphi_date_time_object._timestamp, 41443.82638888889) + self.assertEqual(delphi_date_time_object._time_zone_offset, None) - delphi_date_time_object.CopyFromDateTimeString('2013-06-18 19:50:00.546875') - self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) - self.assertEqual(delphi_date_time_object._time_zone_offset, None) + delphi_date_time_object.CopyFromDateTimeString("2013-06-18 19:50:00.546875") + self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) + self.assertEqual(delphi_date_time_object._time_zone_offset, None) - delphi_date_time_object.CopyFromDateTimeString( - '2013-06-18 19:50:00.546875-01:00') - self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) - self.assertEqual(delphi_date_time_object._time_zone_offset, -60) + delphi_date_time_object.CopyFromDateTimeString( + "2013-06-18 19:50:00.546875-01:00" + ) + self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) + self.assertEqual(delphi_date_time_object._time_zone_offset, -60) - delphi_date_time_object.CopyFromDateTimeString( - '2013-06-18 19:50:00.546875+01:00') - self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) - self.assertEqual(delphi_date_time_object._time_zone_offset, 60) + delphi_date_time_object.CopyFromDateTimeString( + "2013-06-18 19:50:00.546875+01:00" + ) + self.assertEqual(delphi_date_time_object._timestamp, 41443.826395218464) + self.assertEqual(delphi_date_time_object._time_zone_offset, 60) - delphi_date_time_object.CopyFromDateTimeString('1899-12-31 00:00:00') - self.assertEqual(delphi_date_time_object._timestamp, 1.0) - self.assertEqual(delphi_date_time_object._time_zone_offset, None) + delphi_date_time_object.CopyFromDateTimeString("1899-12-31 00:00:00") + self.assertEqual(delphi_date_time_object._timestamp, 1.0) + self.assertEqual(delphi_date_time_object._time_zone_offset, None) - delphi_date_time_object = DelphiDateTimeInvalidYear() + delphi_date_time_object = DelphiDateTimeInvalidYear() - with self.assertRaises(ValueError): - delphi_date_time_object.CopyFromDateTimeString('9999-01-02 00:00:00') + with self.assertRaises(ValueError): + delphi_date_time_object.CopyFromDateTimeString("9999-01-02 00:00:00") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - date_time_string = delphi_date_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2013-06-18 19:50:00.553919') + date_time_string = delphi_date_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2013-06-18 19:50:00.553919") - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - date_time_string = delphi_date_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = delphi_date_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - date_time_string = delphi_date_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2013-06-18T19:50:00.553919+00:00') + date_time_string = delphi_date_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2013-06-18T19:50:00.553919+00:00") - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=8.0e+174) - date_time_string = delphi_date_time_object.CopyToDateTimeStringISO8601() - self.assertIsNone(date_time_string) + delphi_date_time_object = delphi_date_time.DelphiDateTime(timestamp=8.0e174) + date_time_string = delphi_date_time_object.CopyToDateTimeStringISO8601() + self.assertIsNone(date_time_string) - def testGetDate(self): - """Tests the GetDate function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testGetDate(self): + """Tests the GetDate function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - date_tuple = delphi_date_time_object.GetDate() - self.assertEqual(date_tuple, (2013, 6, 18)) + date_tuple = delphi_date_time_object.GetDate() + self.assertEqual(date_tuple, (2013, 6, 18)) - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - date_tuple = delphi_date_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = delphi_date_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - date_with_time_of_day_tuple = delphi_date_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2013, 6, 18, 19, 50, 0)) + date_with_time_of_day_tuple = delphi_date_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2013, 6, 18, 19, 50, 0)) - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - date_with_time_of_day_tuple = delphi_date_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = delphi_date_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - # TODO: remove this method when there is no more need for it in Plaso. - def testGetPlasoTimestamp(self): - """Tests the GetPlasoTimestamp function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + # TODO: remove this method when there is no more need for it in Plaso. + def testGetPlasoTimestamp(self): + """Tests the GetPlasoTimestamp function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - micro_posix_timestamp = delphi_date_time_object.GetPlasoTimestamp() - self.assertEqual(micro_posix_timestamp, 1371585000553920) + micro_posix_timestamp = delphi_date_time_object.GetPlasoTimestamp() + self.assertEqual(micro_posix_timestamp, 1371585000553920) - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - micro_posix_timestamp = delphi_date_time_object.GetPlasoTimestamp() - self.assertIsNone(micro_posix_timestamp) + micro_posix_timestamp = delphi_date_time_object.GetPlasoTimestamp() + self.assertIsNone(micro_posix_timestamp) - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=8.0e+174) + delphi_date_time_object = delphi_date_time.DelphiDateTime(timestamp=8.0e174) - with self.assertRaises(ValueError): - delphi_date_time_object.GetPlasoTimestamp() + with self.assertRaises(ValueError): + delphi_date_time_object.GetPlasoTimestamp() - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - delphi_date_time_object = delphi_date_time.DelphiDateTime( - timestamp=41443.8263953) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + delphi_date_time_object = delphi_date_time.DelphiDateTime( + timestamp=41443.8263953 + ) - time_of_day_tuple = delphi_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (19, 50, 0)) + time_of_day_tuple = delphi_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (19, 50, 0)) - delphi_date_time_object = delphi_date_time.DelphiDateTime() + delphi_date_time_object = delphi_date_time.DelphiDateTime() - time_of_day_tuple = delphi_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = delphi_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/dotnet_datetime.py b/tests/dotnet_datetime.py index f6a4613..7faf374 100644 --- a/tests/dotnet_datetime.py +++ b/tests/dotnet_datetime.py @@ -8,104 +8,100 @@ class DotNetDateTimeEpochTest(unittest.TestCase): - """Tests for the .NET DateTime epoch.""" + """Tests for the .NET DateTime epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - dotnet_date_time_epoch = dotnet_datetime.DotNetDateTimeEpoch() - self.assertIsNotNone(dotnet_date_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + dotnet_date_time_epoch = dotnet_datetime.DotNetDateTimeEpoch() + self.assertIsNotNone(dotnet_date_time_epoch) class DotNetDateTimeTest(unittest.TestCase): - """Tests for the ,NET DateTime timestamp.""" + """Tests for the ,NET DateTime timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - dotnet_date_time = dotnet_datetime.DotNetDateTime() - self.assertEqual(dotnet_date_time.timestamp, 0) + def testProperties(self): + """Tests the properties.""" + dotnet_date_time = dotnet_datetime.DotNetDateTime() + self.assertEqual(dotnet_date_time.timestamp, 0) - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637751130027210000) - self.assertEqual(dotnet_date_time.timestamp, 637751130027210000) + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637751130027210000) + self.assertEqual(dotnet_date_time.timestamp, 637751130027210000) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637433719321230000) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637433719321230000) - expected_normalized_timestamp = decimal.Decimal(1607775132123) / 1000 + expected_normalized_timestamp = decimal.Decimal(1607775132123) / 1000 - normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - dotnet_date_time = dotnet_datetime.DotNetDateTime( - time_zone_offset=60, timestamp=637433719321230000) + dotnet_date_time = dotnet_datetime.DotNetDateTime( + time_zone_offset=60, timestamp=637433719321230000 + ) - expected_normalized_timestamp = decimal.Decimal(1607771532123) / 1000 + expected_normalized_timestamp = decimal.Decimal(1607771532123) / 1000 - normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637433719321230000) - dotnet_date_time.time_zone_offset = 60 + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637433719321230000) + dotnet_date_time.time_zone_offset = 60 - expected_normalized_timestamp = decimal.Decimal(1607771532123) / 1000 + expected_normalized_timestamp = decimal.Decimal(1607771532123) / 1000 - normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + normalized_timestamp = dotnet_date_time._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - dotnet_date_time = dotnet_datetime.DotNetDateTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + dotnet_date_time = dotnet_datetime.DotNetDateTime() - dotnet_date_time.CopyFromDateTimeString('2020-12-12') - self.assertEqual(dotnet_date_time._timestamp, 637433280000000000) - self.assertEqual(dotnet_date_time._time_zone_offset, None) + dotnet_date_time.CopyFromDateTimeString("2020-12-12") + self.assertEqual(dotnet_date_time._timestamp, 637433280000000000) + self.assertEqual(dotnet_date_time._time_zone_offset, None) - dotnet_date_time.CopyFromDateTimeString('2020-12-12 12:12:12') - self.assertEqual(dotnet_date_time._timestamp, 637433719320000000) - self.assertEqual(dotnet_date_time._time_zone_offset, None) + dotnet_date_time.CopyFromDateTimeString("2020-12-12 12:12:12") + self.assertEqual(dotnet_date_time._timestamp, 637433719320000000) + self.assertEqual(dotnet_date_time._time_zone_offset, None) - dotnet_date_time.CopyFromDateTimeString('2020-12-12 12:12:12.123') - self.assertEqual(dotnet_date_time._timestamp, 637433719321230000) - self.assertEqual(dotnet_date_time._time_zone_offset, None) + dotnet_date_time.CopyFromDateTimeString("2020-12-12 12:12:12.123") + self.assertEqual(dotnet_date_time._timestamp, 637433719321230000) + self.assertEqual(dotnet_date_time._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637433280000000000) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637433280000000000) - dotnet_date_string = dotnet_date_time.CopyToDateTimeString() - self.assertEqual(dotnet_date_string, '2020-12-12 00:00:00.0000000') + dotnet_date_string = dotnet_date_time.CopyToDateTimeString() + self.assertEqual(dotnet_date_string, "2020-12-12 00:00:00.0000000") - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637433719320000000) + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637433719320000000) - dotnet_date_string = dotnet_date_time.CopyToDateTimeString() - self.assertEqual(dotnet_date_string, '2020-12-12 12:12:12.0000000') + dotnet_date_string = dotnet_date_time.CopyToDateTimeString() + self.assertEqual(dotnet_date_string, "2020-12-12 12:12:12.0000000") - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=637433719321230000) + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=637433719321230000) - dotnet_date_string = dotnet_date_time.CopyToDateTimeString() - self.assertEqual(dotnet_date_string, '2020-12-12 12:12:12.1230000') + dotnet_date_string = dotnet_date_time.CopyToDateTimeString() + self.assertEqual(dotnet_date_string, "2020-12-12 12:12:12.1230000") - # Test out of range timestamp - dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=-1) - self.assertIsNone(dotnet_date_time.CopyToDateTimeString()) + # Test out of range timestamp + dotnet_date_time = dotnet_datetime.DotNetDateTime(timestamp=-1) + self.assertIsNone(dotnet_date_time.CopyToDateTimeString()) - dotnet_date_time = dotnet_datetime.DotNetDateTime( - timestamp=dotnet_datetime.DotNetDateTime._UINT64_MAX + 1) - self.assertIsNone(dotnet_date_time.CopyToDateTimeString()) + dotnet_date_time = dotnet_datetime.DotNetDateTime( + timestamp=dotnet_datetime.DotNetDateTime._UINT64_MAX + 1 + ) + self.assertIsNone(dotnet_date_time.CopyToDateTimeString()) - # Test year > 9999 - dotnet_date_time = dotnet_datetime.DotNetDateTime() - with self.assertRaises(ValueError): - dotnet_date_time.CopyFromDateTimeString('10000-01-01') + # Test year > 9999 + dotnet_date_time = dotnet_datetime.DotNetDateTime() + with self.assertRaises(ValueError): + dotnet_date_time.CopyFromDateTimeString("10000-01-01") -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/factory.py b/tests/factory.py index 8b4a592..db1fd0b 100644 --- a/tests/factory.py +++ b/tests/factory.py @@ -8,80 +8,82 @@ class TestDateTimeValues(interface.DateTimeValues): - """Date and time values for testing.""" + """Date and time values for testing.""" - # pylint: disable=redundant-returns-doc + # pylint: disable=redundant-returns-doc - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. - Returns: - decimal.Decimal: normalized timestamp, which contains the number of - seconds since January 1, 1970 00:00:00 and a fraction of second used - for increased precision, or None if the normalized timestamp cannot be - determined. - """ - return None + Returns: + decimal.Decimal: normalized timestamp, which contains the number of + seconds since January 1, 1970 00:00:00 and a fraction of second used + for increased precision, or None if the normalized timestamp cannot be + determined. + """ + return None - def CopyFromDateTimeString(self, time_string): - """Copies a date time value from a date and time string. + def CopyFromDateTimeString(self, time_string): + """Copies a date time value from a date and time string. - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3 or 6 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3 or 6 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. - Raises: - ValueError: if the time string is invalid or not supported. - """ - return + Raises: + ValueError: if the time string is invalid or not supported. + """ + return - def CopyToDateTimeString(self): - """Copies the date time value to a date and time string. + def CopyToDateTimeString(self): + """Copies the date time value to a date and time string. - Returns: - str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or - None if the timestamp cannot be copied to a date and time string. - """ - return None + Returns: + str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or + None if the timestamp cannot be copied to a date and time string. + """ + return None class FactoryTest(unittest.TestCase): - """Tests the date and time values factory.""" + """Tests the date and time values factory.""" - def testDateTimeValuesRegistration(self): - """Tests the Register and DeregisterDateTimeValues functions.""" - # pylint: disable=protected-access - number_of_date_time_values_types = len( - factory.Factory._date_time_values_types) + def testDateTimeValuesRegistration(self): + """Tests the Register and DeregisterDateTimeValues functions.""" + # pylint: disable=protected-access + number_of_date_time_values_types = len(factory.Factory._date_time_values_types) - factory.Factory.RegisterDateTimeValues(TestDateTimeValues) - self.assertEqual( - len(factory.Factory._date_time_values_types), - number_of_date_time_values_types + 1) + factory.Factory.RegisterDateTimeValues(TestDateTimeValues) + self.assertEqual( + len(factory.Factory._date_time_values_types), + number_of_date_time_values_types + 1, + ) - with self.assertRaises(KeyError): - factory.Factory.RegisterDateTimeValues(TestDateTimeValues) + with self.assertRaises(KeyError): + factory.Factory.RegisterDateTimeValues(TestDateTimeValues) - factory.Factory.DeregisterDateTimeValues(TestDateTimeValues) - self.assertEqual( - len(factory.Factory._date_time_values_types), - number_of_date_time_values_types) + factory.Factory.DeregisterDateTimeValues(TestDateTimeValues) + self.assertEqual( + len(factory.Factory._date_time_values_types), + number_of_date_time_values_types, + ) - with self.assertRaises(KeyError): - factory.Factory.DeregisterDateTimeValues(TestDateTimeValues) + with self.assertRaises(KeyError): + factory.Factory.DeregisterDateTimeValues(TestDateTimeValues) - def testNewDateTimeValues(self): - """Tests the NewDateTimeValues function.""" - test_date_time_values = factory.Factory.NewDateTimeValues( - 'Filetime', timestamp=0x01cb3a623d0a17ce) + def testNewDateTimeValues(self): + """Tests the NewDateTimeValues function.""" + test_date_time_values = factory.Factory.NewDateTimeValues( + "Filetime", timestamp=0x01CB3A623D0A17CE + ) - self.assertIsNotNone(test_date_time_values) + self.assertIsNotNone(test_date_time_values) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/fake_time.py b/tests/fake_time.py index 1d9ba5c..5bc118c 100644 --- a/tests/fake_time.py +++ b/tests/fake_time.py @@ -8,144 +8,144 @@ class FakeTimeTest(unittest.TestCase): - """Tests for the fake time.""" + """Tests for the fake time.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - normalized_timestamp = fake_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281647191.546875')) + normalized_timestamp = fake_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281647191.546875")) - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") - normalized_timestamp = fake_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = fake_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - fake_time_object.time_zone_offset = 60 + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + fake_time_object.time_zone_offset = 60 - normalized_timestamp = fake_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = fake_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - fake_time_object = fake_time.FakeTime() - fake_time_object._number_of_seconds = None + fake_time_object = fake_time.FakeTime() + fake_time_object._number_of_seconds = None - normalized_timestamp = fake_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = fake_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testGetPlasoTimestamp(self): - """Tests the GetPlasoTimestamp function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object._normalized_timestamp = decimal.Decimal( - '1333794697.6252465') - plaso_timestamp = fake_time_object.GetPlasoTimestamp() - self.assertEqual(plaso_timestamp, 1333794697625247) + def testGetPlasoTimestamp(self): + """Tests the GetPlasoTimestamp function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object._normalized_timestamp = decimal.Decimal("1333794697.6252465") + plaso_timestamp = fake_time_object.GetPlasoTimestamp() + self.assertEqual(plaso_timestamp, 1333794697625247) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - fake_time_object = fake_time.FakeTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(fake_time_object._number_of_seconds, 1281571200) - self.assertIsNone(fake_time_object._microseconds) - self.assertEqual(fake_time_object._time_zone_offset, None) + fake_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(fake_time_object._number_of_seconds, 1281571200) + self.assertIsNone(fake_time_object._microseconds) + self.assertEqual(fake_time_object._time_zone_offset, None) - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(fake_time_object._number_of_seconds, 1281647191) - self.assertIsNone(fake_time_object._microseconds) - self.assertEqual(fake_time_object._time_zone_offset, None) + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(fake_time_object._number_of_seconds, 1281647191) + self.assertIsNone(fake_time_object._microseconds) + self.assertEqual(fake_time_object._time_zone_offset, None) - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(fake_time_object._number_of_seconds, 1281647191) - self.assertEqual(fake_time_object._microseconds, 546875) - self.assertEqual(fake_time_object._time_zone_offset, None) + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(fake_time_object._number_of_seconds, 1281647191) + self.assertEqual(fake_time_object._microseconds, 546875) + self.assertEqual(fake_time_object._time_zone_offset, None) - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(fake_time_object._number_of_seconds, 1281647191) - self.assertEqual(fake_time_object._microseconds, 546875) - self.assertEqual(fake_time_object._time_zone_offset, -60) + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(fake_time_object._number_of_seconds, 1281647191) + self.assertEqual(fake_time_object._microseconds, 546875) + self.assertEqual(fake_time_object._time_zone_offset, -60) - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(fake_time_object._number_of_seconds, 1281647191) - self.assertEqual(fake_time_object._microseconds, 546875) - self.assertEqual(fake_time_object._time_zone_offset, 60) + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(fake_time_object._number_of_seconds, 1281647191) + self.assertEqual(fake_time_object._microseconds, 546875) + self.assertEqual(fake_time_object._time_zone_offset, 60) - fake_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(fake_time_object._number_of_seconds, -11644387200) - self.assertIsNone(fake_time_object._microseconds) - self.assertEqual(fake_time_object._time_zone_offset, None) + fake_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(fake_time_object._number_of_seconds, -11644387200) + self.assertIsNone(fake_time_object._microseconds) + self.assertEqual(fake_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - date_time_string = fake_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 21:06:31.546875') + date_time_string = fake_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 21:06:31.546875") - fake_time_object = fake_time.FakeTime() - fake_time_object._number_of_seconds = None + fake_time_object = fake_time.FakeTime() + fake_time_object._number_of_seconds = None - date_time_string = fake_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = fake_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - date_time_string = fake_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875+00:00') + date_time_string = fake_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T21:06:31.546875+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testGetDate(self): + """Tests the GetDate function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - date_tuple = fake_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = fake_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - fake_time_object = fake_time.FakeTime() - fake_time_object._number_of_seconds = None + fake_time_object = fake_time.FakeTime() + fake_time_object._number_of_seconds = None - date_tuple = fake_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = fake_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - date_with_time_of_day_tuple = fake_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) + date_with_time_of_day_tuple = fake_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) - fake_time_object = fake_time.FakeTime() - fake_time_object._number_of_seconds = None + fake_time_object = fake_time.FakeTime() + fake_time_object._number_of_seconds = None - date_with_time_of_day_tuple = fake_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = fake_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - fake_time_object = fake_time.FakeTime() - fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + fake_time_object = fake_time.FakeTime() + fake_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") - time_of_day_tuple = fake_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (21, 6, 31)) + time_of_day_tuple = fake_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (21, 6, 31)) - fake_time_object = fake_time.FakeTime() - fake_time_object._number_of_seconds = None + fake_time_object = fake_time.FakeTime() + fake_time_object._number_of_seconds = None - time_of_day_tuple = fake_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = fake_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/fat_date_time.py b/tests/fat_date_time.py index 754af67..914d42a 100644 --- a/tests/fat_date_time.py +++ b/tests/fat_date_time.py @@ -8,300 +8,302 @@ class FATDateTimeEpochTest(unittest.TestCase): - """Tests for the FAT date time epoch.""" + """Tests for the FAT date time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - fat_date_time_epoch = fat_date_time.FATDateTimeEpoch() - self.assertIsNotNone(fat_date_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + fat_date_time_epoch = fat_date_time.FATDateTimeEpoch() + self.assertIsNotNone(fat_date_time_epoch) class FATDateTime(unittest.TestCase): - """Tests for the FAT date time.""" + """Tests for the FAT date time.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281647192.0')) + normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281647192.0")) - fat_date_time_object = fat_date_time.FATDateTime( - fat_date_time=0xa8d03d0c, time_zone_offset=60) + fat_date_time_object = fat_date_time.FATDateTime( + fat_date_time=0xA8D03D0C, time_zone_offset=60 + ) - normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643592.0')) + normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643592.0")) - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) - fat_date_time_object.time_zone_offset = 60 + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) + fat_date_time_object.time_zone_offset = 60 - normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643592.0')) + normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643592.0")) - fat_date_time_object = fat_date_time.FATDateTime() + fat_date_time_object = fat_date_time.FATDateTime() - normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = fat_date_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - fat_date_time_object = fat_date_time.FATDateTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + fat_date_time_object = fat_date_time.FATDateTime() - fat_date_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(fat_date_time_object._number_of_seconds, 966038400) - self.assertEqual(fat_date_time_object._time_zone_offset, None) + fat_date_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(fat_date_time_object._number_of_seconds, 966038400) + self.assertEqual(fat_date_time_object._time_zone_offset, None) - fat_date_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) - self.assertEqual(fat_date_time_object._time_zone_offset, None) + fat_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) + self.assertEqual(fat_date_time_object._time_zone_offset, None) - fat_date_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) - self.assertEqual(fat_date_time_object._time_zone_offset, None) + fat_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) + self.assertEqual(fat_date_time_object._time_zone_offset, None) - fat_date_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) - self.assertEqual(fat_date_time_object._time_zone_offset, -60) + fat_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) + self.assertEqual(fat_date_time_object._time_zone_offset, -60) - fat_date_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) - self.assertEqual(fat_date_time_object._time_zone_offset, 60) + fat_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(fat_date_time_object._number_of_seconds, 966114391) + self.assertEqual(fat_date_time_object._time_zone_offset, 60) - fat_date_time_object.CopyFromDateTimeString('1980-01-02 00:00:00') - self.assertEqual(fat_date_time_object._number_of_seconds, 86400) - self.assertEqual(fat_date_time_object._time_zone_offset, None) + fat_date_time_object.CopyFromDateTimeString("1980-01-02 00:00:00") + self.assertEqual(fat_date_time_object._number_of_seconds, 86400) + self.assertEqual(fat_date_time_object._time_zone_offset, None) - with self.assertRaises(ValueError): - fat_date_time_object.CopyFromDateTimeString('2200-01-02 00:00:00') + with self.assertRaises(ValueError): + fat_date_time_object.CopyFromDateTimeString("2200-01-02 00:00:00") - def testGetNumberOfSeconds(self): - """Tests the _GetNumberOfSeconds function.""" - fat_date_time_object = fat_date_time.FATDateTime() + def testGetNumberOfSeconds(self): + """Tests the _GetNumberOfSeconds function.""" + fat_date_time_object = fat_date_time.FATDateTime() - fat_date_time_object._GetNumberOfSeconds(0xa8d03d0c) + fat_date_time_object._GetNumberOfSeconds(0xA8D03D0C) - # Invalid number of seconds. - test_fat_date_time = (0xa8d03d0c & ~(0x1f << 16)) | ((30 & 0x1f) << 16) - with self.assertRaises(ValueError): - fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) + # Invalid number of seconds. + test_fat_date_time = (0xA8D03D0C & ~(0x1F << 16)) | ((30 & 0x1F) << 16) + with self.assertRaises(ValueError): + fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) - # Invalid number of minutes. - test_fat_date_time = (0xa8d03d0c & ~(0x3f << 21)) | ((60 & 0x3f) << 21) - with self.assertRaises(ValueError): - fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) + # Invalid number of minutes. + test_fat_date_time = (0xA8D03D0C & ~(0x3F << 21)) | ((60 & 0x3F) << 21) + with self.assertRaises(ValueError): + fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) - # Invalid number of hours. - test_fat_date_time = (0xa8d03d0c & ~(0x1f << 27)) | ((24 & 0x1f) << 27) - with self.assertRaises(ValueError): - fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) + # Invalid number of hours. + test_fat_date_time = (0xA8D03D0C & ~(0x1F << 27)) | ((24 & 0x1F) << 27) + with self.assertRaises(ValueError): + fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) - # Invalid day of month. - test_fat_date_time = (0xa8d03d0c & ~0x1f) | (32 & 0x1f) - with self.assertRaises(ValueError): - fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) + # Invalid day of month. + test_fat_date_time = (0xA8D03D0C & ~0x1F) | (32 & 0x1F) + with self.assertRaises(ValueError): + fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) - # Invalid month. - test_fat_date_time = (0xa8d03d0c & ~(0x0f << 5)) | ((13 & 0x0f) << 5) - with self.assertRaises(ValueError): - fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) + # Invalid month. + test_fat_date_time = (0xA8D03D0C & ~(0x0F << 5)) | ((13 & 0x0F) << 5) + with self.assertRaises(ValueError): + fat_date_time_object._GetNumberOfSeconds(test_fat_date_time) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - date_time_string = fat_date_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 21:06:32') + date_time_string = fat_date_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 21:06:32") - fat_date_time_object = fat_date_time.FATDateTime() + fat_date_time_object = fat_date_time.FATDateTime() - date_time_string = fat_date_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = fat_date_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - date_time_string = fat_date_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T21:06:32+00:00') + date_time_string = fat_date_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T21:06:32+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testGetDate(self): + """Tests the GetDate function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - date_tuple = fat_date_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = fat_date_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - fat_date_time_object = fat_date_time.FATDateTime() + fat_date_time_object = fat_date_time.FATDateTime() - date_tuple = fat_date_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = fat_date_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - date_with_time_of_day_tuple = fat_date_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 32)) + date_with_time_of_day_tuple = fat_date_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 32)) - fat_date_time_object = fat_date_time.FATDateTime() + fat_date_time_object = fat_date_time.FATDateTime() - date_with_time_of_day_tuple = fat_date_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = fat_date_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) - time_of_day_tuple = fat_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (21, 6, 32)) + time_of_day_tuple = fat_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (21, 6, 32)) - fat_date_time_object = fat_date_time.FATDateTime() + fat_date_time_object = fat_date_time.FATDateTime() - time_of_day_tuple = fat_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = fat_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) class FATTimestampTest(unittest.TestCase): - """Tests for the POSIX timestamp.""" + """Tests for the POSIX timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - self.assertEqual(fat_timestamp_object.timestamp, 131033589024) + def testProperties(self): + """Tests the properties.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + self.assertEqual(fat_timestamp_object.timestamp, 131033589024) - fat_timestamp_object = fat_date_time.FATTimestamp() - self.assertIsNone(fat_timestamp_object.timestamp) + fat_timestamp_object = fat_date_time.FATTimestamp() + self.assertIsNone(fat_timestamp_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1625868690.24')) + normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1625868690.24")) - fat_timestamp_object = fat_date_time.FATTimestamp( - time_zone_offset=60, timestamp=131033589024) + fat_timestamp_object = fat_date_time.FATTimestamp( + time_zone_offset=60, timestamp=131033589024 + ) - normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1625865090.24')) + normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1625865090.24")) - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = fat_timestamp_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - fat_timestamp_object = fat_date_time.FATTimestamp() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + fat_timestamp_object = fat_date_time.FATTimestamp() - fat_timestamp_object.CopyFromDateTimeString('2021-07-09') - self.assertEqual(fat_timestamp_object._timestamp, 131025600000) - self.assertEqual(fat_timestamp_object._time_zone_offset, None) + fat_timestamp_object.CopyFromDateTimeString("2021-07-09") + self.assertEqual(fat_timestamp_object._timestamp, 131025600000) + self.assertEqual(fat_timestamp_object._time_zone_offset, None) - fat_timestamp_object.CopyFromDateTimeString('2021-07-09 22:11:30') - self.assertEqual(fat_timestamp_object._timestamp, 131033589000) - self.assertEqual(fat_timestamp_object._time_zone_offset, None) + fat_timestamp_object.CopyFromDateTimeString("2021-07-09 22:11:30") + self.assertEqual(fat_timestamp_object._timestamp, 131033589000) + self.assertEqual(fat_timestamp_object._time_zone_offset, None) - fat_timestamp_object.CopyFromDateTimeString('2021-07-09 22:11:30.246875') - self.assertEqual(fat_timestamp_object._timestamp, 131033589024) - self.assertEqual(fat_timestamp_object._time_zone_offset, None) + fat_timestamp_object.CopyFromDateTimeString("2021-07-09 22:11:30.246875") + self.assertEqual(fat_timestamp_object._timestamp, 131033589024) + self.assertEqual(fat_timestamp_object._time_zone_offset, None) - fat_timestamp_object.CopyFromDateTimeString( - '2021-07-09 22:11:30.246875-01:00') - self.assertEqual(fat_timestamp_object._timestamp, 131033589024) - self.assertEqual(fat_timestamp_object._time_zone_offset, -60) + fat_timestamp_object.CopyFromDateTimeString("2021-07-09 22:11:30.246875-01:00") + self.assertEqual(fat_timestamp_object._timestamp, 131033589024) + self.assertEqual(fat_timestamp_object._time_zone_offset, -60) - fat_timestamp_object.CopyFromDateTimeString( - '2021-07-09 22:11:30.246875+01:00') - self.assertEqual(fat_timestamp_object._timestamp, 131033589024) - self.assertEqual(fat_timestamp_object._time_zone_offset, 60) + fat_timestamp_object.CopyFromDateTimeString("2021-07-09 22:11:30.246875+01:00") + self.assertEqual(fat_timestamp_object._timestamp, 131033589024) + self.assertEqual(fat_timestamp_object._time_zone_offset, 60) - fat_timestamp_object.CopyFromDateTimeString('1980-01-02 00:00:00') - self.assertEqual(fat_timestamp_object._timestamp, 8640000) - self.assertEqual(fat_timestamp_object._time_zone_offset, None) + fat_timestamp_object.CopyFromDateTimeString("1980-01-02 00:00:00") + self.assertEqual(fat_timestamp_object._timestamp, 8640000) + self.assertEqual(fat_timestamp_object._time_zone_offset, None) - with self.assertRaises(ValueError): - fat_timestamp_object.CopyFromDateTimeString('2200-01-02 00:00:00') + with self.assertRaises(ValueError): + fat_timestamp_object.CopyFromDateTimeString("2200-01-02 00:00:00") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - date_time_string = fat_timestamp_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2021-07-09 22:11:30.24') + date_time_string = fat_timestamp_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2021-07-09 22:11:30.24") - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - date_time_string = fat_timestamp_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = fat_timestamp_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - date_time_string = fat_timestamp_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2021-07-09T22:11:30.24+00:00') + date_time_string = fat_timestamp_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2021-07-09T22:11:30.24+00:00") - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - posix_timestamp, fraction_of_second = ( - fat_timestamp_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1625868690) - self.assertEqual(fraction_of_second, 24) + posix_timestamp, fraction_of_second = ( + fat_timestamp_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1625868690) + self.assertEqual(fraction_of_second, 24) - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - posix_timestamp, fraction_of_second = ( - fat_timestamp_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + fat_timestamp_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testGetDate(self): + """Tests the GetDate function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - date_tuple = fat_timestamp_object.GetDate() - self.assertEqual(date_tuple, (2021, 7, 9)) + date_tuple = fat_timestamp_object.GetDate() + self.assertEqual(date_tuple, (2021, 7, 9)) - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - date_tuple = fat_timestamp_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = fat_timestamp_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - date_with_time_of_day_tuple = fat_timestamp_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2021, 7, 9, 22, 11, 30)) + date_with_time_of_day_tuple = fat_timestamp_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2021, 7, 9, 22, 11, 30)) - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - date_with_time_of_day_tuple = fat_timestamp_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = fat_timestamp_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + fat_timestamp_object = fat_date_time.FATTimestamp(timestamp=131033589024) - time_of_day_tuple = fat_timestamp_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (22, 11, 30)) + time_of_day_tuple = fat_timestamp_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (22, 11, 30)) - fat_timestamp_object = fat_date_time.FATTimestamp() + fat_timestamp_object = fat_date_time.FATTimestamp() - time_of_day_tuple = fat_timestamp_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = fat_timestamp_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/filetime.py b/tests/filetime.py index 88f2f97..dea4070 100644 --- a/tests/filetime.py +++ b/tests/filetime.py @@ -8,184 +8,189 @@ class FiletimeEpochTest(unittest.TestCase): - """Tests for the FILETIME epoch.""" + """Tests for the FILETIME epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - filetime_epoch = filetime.FiletimeEpoch() - self.assertIsNotNone(filetime_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + filetime_epoch = filetime.FiletimeEpoch() + self.assertIsNotNone(filetime_epoch) class FiletimeTest(unittest.TestCase): - """Tests for the FILETIME timestamp.""" + """Tests for the FILETIME timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) - self.assertEqual(filetime_object.timestamp, 0x01cb3a623d0a17ce) + def testProperties(self): + """Tests the properties.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) + self.assertEqual(filetime_object.timestamp, 0x01CB3A623D0A17CE) - filetime_object = filetime.Filetime() - self.assertIsNone(filetime_object.timestamp) + filetime_object = filetime.Filetime() + self.assertIsNone(filetime_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281647191.546875')) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281647191.546875")) - filetime_object = filetime.Filetime( - time_zone_offset=60, timestamp=0x01cb3a623d0a17ce) + filetime_object = filetime.Filetime( + time_zone_offset=60, timestamp=0x01CB3A623D0A17CE + ) - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) - filetime_object.time_zone_offset = 60 + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) + filetime_object.time_zone_offset = 60 - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - filetime_object = filetime.Filetime(timestamp=0x0000000000000000) + filetime_object = filetime.Filetime(timestamp=0x0000000000000000) - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('-11644473600.0')) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("-11644473600.0")) - filetime_object = filetime.Filetime(timestamp=0x0000000000008000) + filetime_object = filetime.Filetime(timestamp=0x0000000000008000) - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('-11644473599.9967232')) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("-11644473599.9967232")) - filetime_object = filetime.Filetime(timestamp=0x1ffffffffffffffff) + filetime_object = filetime.Filetime(timestamp=0x1FFFFFFFFFFFFFFFF) - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - normalized_timestamp = filetime_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = filetime_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - filetime_object = filetime.Filetime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + filetime_object = filetime.Filetime() - filetime_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(filetime_object._timestamp, 0x1cb39b14e8c4000) - self.assertEqual(filetime_object._time_zone_offset, None) + filetime_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(filetime_object._timestamp, 0x1CB39B14E8C4000) + self.assertEqual(filetime_object._time_zone_offset, None) - filetime_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(filetime_object._timestamp, 0x1cb3a623cb6a580) - self.assertEqual(filetime_object._time_zone_offset, None) + filetime_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(filetime_object._timestamp, 0x1CB3A623CB6A580) + self.assertEqual(filetime_object._time_zone_offset, None) - filetime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(filetime_object._timestamp, 0x01cb3a623d0a17ce) - self.assertEqual(filetime_object._time_zone_offset, None) + filetime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(filetime_object._timestamp, 0x01CB3A623D0A17CE) + self.assertEqual(filetime_object._time_zone_offset, None) - filetime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(filetime_object._timestamp, 0x01cb3a623d0a17ce) - self.assertEqual(filetime_object._time_zone_offset, -60) + filetime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(filetime_object._timestamp, 0x01CB3A623D0A17CE) + self.assertEqual(filetime_object._time_zone_offset, -60) - filetime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(filetime_object._timestamp, 0x01cb3a623d0a17ce) - self.assertEqual(filetime_object._time_zone_offset, 60) + filetime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(filetime_object._timestamp, 0x01CB3A623D0A17CE) + self.assertEqual(filetime_object._time_zone_offset, 60) - filetime_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(filetime_object._timestamp, 86400 * 10000000) - self.assertEqual(filetime_object._time_zone_offset, None) + filetime_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(filetime_object._timestamp, 86400 * 10000000) + self.assertEqual(filetime_object._time_zone_offset, None) - with self.assertRaises(ValueError): - filetime_object.CopyFromDateTimeString('1500-01-02 00:00:00') + with self.assertRaises(ValueError): + filetime_object.CopyFromDateTimeString("1500-01-02 00:00:00") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - date_time_string = filetime_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 21:06:31.5468750') + date_time_string = filetime_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 21:06:31.5468750") - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - date_time_string = filetime_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = filetime_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - date_time_string = filetime_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T21:06:31.5468750+00:00') + date_time_string = filetime_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T21:06:31.5468750+00:00") - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - posix_timestamp, fraction_of_second = ( - filetime_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281647191) - self.assertEqual(fraction_of_second, 5468750) + posix_timestamp, fraction_of_second = ( + filetime_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281647191) + self.assertEqual(fraction_of_second, 5468750) - filetime_object = filetime.Filetime(timestamp=0x0000000000000000) + filetime_object = filetime.Filetime(timestamp=0x0000000000000000) - posix_timestamp, fraction_of_second = ( - filetime_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, -11644473600) - self.assertEqual(fraction_of_second, 0) + posix_timestamp, fraction_of_second = ( + filetime_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, -11644473600) + self.assertEqual(fraction_of_second, 0) - filetime_object = filetime.Filetime(timestamp=0x0000000000008000) + filetime_object = filetime.Filetime(timestamp=0x0000000000008000) - posix_timestamp, fraction_of_second = ( - filetime_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, -11644473599) - self.assertEqual(fraction_of_second, 9967232) + posix_timestamp, fraction_of_second = ( + filetime_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, -11644473599) + self.assertEqual(fraction_of_second, 9967232) - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - posix_timestamp, fraction_of_second = ( - filetime_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + filetime_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testGetDate(self): + """Tests the GetDate function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - date_tuple = filetime_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = filetime_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - date_tuple = filetime_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = filetime_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - date_with_time_of_day_tuple = filetime_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) + date_with_time_of_day_tuple = filetime_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - date_with_time_of_day_tuple = filetime_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = filetime_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + filetime_object = filetime.Filetime(timestamp=0x01CB3A623D0A17CE) - time_of_day_tuple = filetime_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (21, 6, 31)) + time_of_day_tuple = filetime_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (21, 6, 31)) - filetime_object = filetime.Filetime() + filetime_object = filetime.Filetime() - time_of_day_tuple = filetime_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = filetime_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/golang_time.py b/tests/golang_time.py index 086769e..a472157 100644 --- a/tests/golang_time.py +++ b/tests/golang_time.py @@ -8,208 +8,200 @@ class GolangEpochTest(unittest.TestCase): - """Test for the Golang time.Time epoch.""" + """Test for the Golang time.Time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - golang_epoch = golang_time.GolangTimeEpoch() - self.assertIsNotNone(golang_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + golang_epoch = golang_time.GolangTimeEpoch() + self.assertIsNotNone(golang_epoch) - def testEpochDate(self): - """Tests the Golang time.Time epoch properties.""" - golang_epoch = golang_time.GolangTimeEpoch() - self.assertEqual(golang_epoch.year, 1) - self.assertEqual(golang_epoch.month, 1) - self.assertEqual(golang_epoch.day_of_month, 1) + def testEpochDate(self): + """Tests the Golang time.Time epoch properties.""" + golang_epoch = golang_time.GolangTimeEpoch() + self.assertEqual(golang_epoch.year, 1) + self.assertEqual(golang_epoch.month, 1) + self.assertEqual(golang_epoch.day_of_month, 1) class GolangTest(unittest.TestCase): - """Tests for the Golang time.Time timestamp.""" - - # pylint: disable=protected-access - - def testProperties(self): - """Tests the Golang time.Time timestamp properties.""" - golang_timestamp = struct.pack('>Bqih', 1, 0, 0, -1) - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - self.assertEqual(golang_time_object._number_of_seconds, 0) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object.is_local_time, False) - self.assertEqual(golang_time_object._time_zone_offset, 0) - - golang_timestamp = struct.pack( - '>Bqih', 1, golang_time.GolangTime._GOLANG_TO_POSIX_BASE, 0, 60) - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - self.assertEqual(golang_time_object._number_of_seconds, - golang_time.GolangTime._GOLANG_TO_POSIX_BASE) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object.is_local_time, False) - self.assertEqual(golang_time_object._time_zone_offset, 60) - - golang_timestamp = bytes.fromhex('010000000e7791f70000000000ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - self.assertEqual(golang_time_object._number_of_seconds, - golang_time.GolangTime._GOLANG_TO_POSIX_BASE) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object.is_local_time, False) - self.assertEqual(golang_time_object._time_zone_offset, 0) - - def testGetNormalizedTimestamp(self): - """Test the _GetNormalizedTimestamp function.""" - golang_timestamp = bytes.fromhex('010000000000000000000000000000') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - golang_timestamp = struct.pack('>Bqih', 1, 63772480949, 711098348, 0) - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1636884149.711098348')) - - golang_timestamp = struct.pack('>Bqih', 1, 63772480949, 711098348, 60) - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1636880549.711098348')) - - golang_timestamp = struct.pack('>Bqih', 1, 63772480949, 711098348, 0) - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - golang_time_object.time_zone_offset = 60 - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1636880549.711098348')) - - golang_timestamp = bytes.fromhex('010000000e7791f70000000000ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('0')) - - golang_timestamp = bytes.fromhex('010000000e7791f60000000000ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - normalized_timestamp = golang_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - def testGetNumberOfSeconds(self): - """Test the _GetNumberOfSeconds function.""" - golang_time_object = golang_time.GolangTime() - - golang_timestamp = bytes.fromhex('010000000000000002000000030004') - number_of_seconds, nanoseconds, time_zone_offset = ( - golang_time_object._GetNumberOfSeconds(golang_timestamp)) - self.assertEqual(number_of_seconds, 2) - self.assertEqual(nanoseconds, 3) - self.assertEqual(time_zone_offset, 4) - - golang_timestamp = bytes.fromhex('02000000000000000500000006ffff08') - number_of_seconds, nanoseconds, time_zone_offset = ( - golang_time_object._GetNumberOfSeconds(golang_timestamp)) - self.assertEqual(number_of_seconds, 5) - self.assertEqual(nanoseconds, 6) - self.assertEqual(time_zone_offset, 0) - - with self.assertRaises(ValueError): - golang_timestamp = bytes.fromhex('0100') - golang_time_object._GetNumberOfSeconds(golang_timestamp) - - with self.assertRaises(ValueError): - golang_timestamp = bytes.fromhex('020000000000000000000000000000') - golang_time_object._GetNumberOfSeconds(golang_timestamp) - - with self.assertRaises(ValueError): - golang_timestamp = bytes.fromhex('ff0000000000000000000000000000') - golang_time_object._GetNumberOfSeconds(golang_timestamp) - - with self.assertRaises(ValueError): - golang_timestamp = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - golang_time_object._GetNumberOfSeconds(golang_timestamp) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - golang_time_object = golang_time.GolangTime() - - golang_time_object.CopyFromDateTimeString('0001-01-01') - self.assertEqual(golang_time_object._number_of_seconds, 0) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object._time_zone_offset, None) - - golang_time_object.CopyFromDateTimeString('0001-01-01 00:01:00') - self.assertEqual(golang_time_object._number_of_seconds, 60) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object._time_zone_offset, None) - - golang_time_object.CopyFromDateTimeString('0001-01-01 00:00:00.000001') - self.assertEqual(golang_time_object._number_of_seconds, 0) - self.assertEqual(golang_time_object._nanoseconds, 1000) - self.assertEqual(golang_time_object._time_zone_offset, None) - - golang_time_object.CopyFromDateTimeString('2000-01-01') - self.assertEqual(golang_time_object._number_of_seconds, 63082281600) - self.assertEqual(golang_time_object._nanoseconds, 0) - self.assertEqual(golang_time_object._time_zone_offset, None) - - golang_time_object.CopyFromDateTimeString('2000-01-01 12:23:45.567890') - self.assertEqual(golang_time_object._number_of_seconds, 63082326225) - self.assertEqual(golang_time_object._nanoseconds, 567890000) - self.assertEqual(golang_time_object._time_zone_offset, None) - - golang_time_object.CopyFromDateTimeString( - '2000-01-01 12:23:45.567890+01:00') - self.assertEqual(golang_time_object._number_of_seconds, 63082326225) - self.assertEqual(golang_time_object._nanoseconds, 567890000) - self.assertEqual(golang_time_object._time_zone_offset, 60) - - # Test with invalid date string. - with self.assertRaises(ValueError): - golang_time_object.CopyFromDateTimeString('0001:01-01 00:01:00') - - # Test with negative year. - with self.assertRaises(ValueError): - golang_time_object.CopyFromDateTimeString('-001-01-01 00:01:00') - - def testCopyToDateTimeString(self): - """Test the CopyToDateTimeString function.""" - golang_timestamp = bytes.fromhex('010000000eafffe8d121d95050ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - self.assertEqual(golang_time_object._number_of_seconds, 63082326225) - self.assertEqual(golang_time_object._nanoseconds, 567890000) - self.assertEqual(golang_time_object._time_zone_offset, 0) - - date_time_string = golang_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2000-01-01 12:23:45.567890000') - - golang_timestamp = bytes.fromhex('010000000eafffe8d10000ddd5ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - self.assertEqual(golang_time_object._number_of_seconds, 63082326225) - self.assertEqual(golang_time_object._nanoseconds, 56789) - self.assertEqual(golang_time_object._time_zone_offset, 0) - - date_time_string = golang_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2000-01-01 12:23:45.000056789') - - golang_time_object = golang_time.GolangTime() - date_time_string = golang_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - -if __name__ == '__main__': - unittest.main() + """Tests for the Golang time.Time timestamp.""" + + # pylint: disable=protected-access + + def testProperties(self): + """Tests the Golang time.Time timestamp properties.""" + golang_timestamp = struct.pack(">Bqih", 1, 0, 0, -1) + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + self.assertEqual(golang_time_object._number_of_seconds, 0) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object.is_local_time, False) + self.assertEqual(golang_time_object._time_zone_offset, 0) + + golang_timestamp = struct.pack( + ">Bqih", 1, golang_time.GolangTime._GOLANG_TO_POSIX_BASE, 0, 60 + ) + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + self.assertEqual( + golang_time_object._number_of_seconds, + golang_time.GolangTime._GOLANG_TO_POSIX_BASE, + ) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object.is_local_time, False) + self.assertEqual(golang_time_object._time_zone_offset, 60) + + golang_timestamp = bytes.fromhex("010000000e7791f70000000000ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + self.assertEqual( + golang_time_object._number_of_seconds, + golang_time.GolangTime._GOLANG_TO_POSIX_BASE, + ) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object.is_local_time, False) + self.assertEqual(golang_time_object._time_zone_offset, 0) + + def testGetNormalizedTimestamp(self): + """Test the _GetNormalizedTimestamp function.""" + golang_timestamp = bytes.fromhex("010000000000000000000000000000") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + golang_timestamp = struct.pack(">Bqih", 1, 63772480949, 711098348, 0) + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1636884149.711098348")) + + golang_timestamp = struct.pack(">Bqih", 1, 63772480949, 711098348, 60) + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1636880549.711098348")) + + golang_timestamp = struct.pack(">Bqih", 1, 63772480949, 711098348, 0) + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + golang_time_object.time_zone_offset = 60 + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1636880549.711098348")) + + golang_timestamp = bytes.fromhex("010000000e7791f70000000000ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("0")) + + golang_timestamp = bytes.fromhex("010000000e7791f60000000000ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + normalized_timestamp = golang_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + def testGetNumberOfSeconds(self): + """Test the _GetNumberOfSeconds function.""" + golang_time_object = golang_time.GolangTime() + + golang_timestamp = bytes.fromhex("010000000000000002000000030004") + number_of_seconds, nanoseconds, time_zone_offset = ( + golang_time_object._GetNumberOfSeconds(golang_timestamp) + ) + self.assertEqual(number_of_seconds, 2) + self.assertEqual(nanoseconds, 3) + self.assertEqual(time_zone_offset, 4) + + golang_timestamp = bytes.fromhex("02000000000000000500000006ffff08") + number_of_seconds, nanoseconds, time_zone_offset = ( + golang_time_object._GetNumberOfSeconds(golang_timestamp) + ) + self.assertEqual(number_of_seconds, 5) + self.assertEqual(nanoseconds, 6) + self.assertEqual(time_zone_offset, 0) + + with self.assertRaises(ValueError): + golang_timestamp = bytes.fromhex("0100") + golang_time_object._GetNumberOfSeconds(golang_timestamp) + + with self.assertRaises(ValueError): + golang_timestamp = bytes.fromhex("020000000000000000000000000000") + golang_time_object._GetNumberOfSeconds(golang_timestamp) + + with self.assertRaises(ValueError): + golang_timestamp = bytes.fromhex("ff0000000000000000000000000000") + golang_time_object._GetNumberOfSeconds(golang_timestamp) + + with self.assertRaises(ValueError): + golang_timestamp = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + golang_time_object._GetNumberOfSeconds(golang_timestamp) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + golang_time_object = golang_time.GolangTime() + + golang_time_object.CopyFromDateTimeString("0001-01-01") + self.assertEqual(golang_time_object._number_of_seconds, 0) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object._time_zone_offset, None) + + golang_time_object.CopyFromDateTimeString("0001-01-01 00:01:00") + self.assertEqual(golang_time_object._number_of_seconds, 60) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object._time_zone_offset, None) + + golang_time_object.CopyFromDateTimeString("0001-01-01 00:00:00.000001") + self.assertEqual(golang_time_object._number_of_seconds, 0) + self.assertEqual(golang_time_object._nanoseconds, 1000) + self.assertEqual(golang_time_object._time_zone_offset, None) + + golang_time_object.CopyFromDateTimeString("2000-01-01") + self.assertEqual(golang_time_object._number_of_seconds, 63082281600) + self.assertEqual(golang_time_object._nanoseconds, 0) + self.assertEqual(golang_time_object._time_zone_offset, None) + + golang_time_object.CopyFromDateTimeString("2000-01-01 12:23:45.567890") + self.assertEqual(golang_time_object._number_of_seconds, 63082326225) + self.assertEqual(golang_time_object._nanoseconds, 567890000) + self.assertEqual(golang_time_object._time_zone_offset, None) + + golang_time_object.CopyFromDateTimeString("2000-01-01 12:23:45.567890+01:00") + self.assertEqual(golang_time_object._number_of_seconds, 63082326225) + self.assertEqual(golang_time_object._nanoseconds, 567890000) + self.assertEqual(golang_time_object._time_zone_offset, 60) + + # Test with invalid date string. + with self.assertRaises(ValueError): + golang_time_object.CopyFromDateTimeString("0001:01-01 00:01:00") + + # Test with negative year. + with self.assertRaises(ValueError): + golang_time_object.CopyFromDateTimeString("-001-01-01 00:01:00") + + def testCopyToDateTimeString(self): + """Test the CopyToDateTimeString function.""" + golang_timestamp = bytes.fromhex("010000000eafffe8d121d95050ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + self.assertEqual(golang_time_object._number_of_seconds, 63082326225) + self.assertEqual(golang_time_object._nanoseconds, 567890000) + self.assertEqual(golang_time_object._time_zone_offset, 0) + + date_time_string = golang_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2000-01-01 12:23:45.567890000") + + golang_timestamp = bytes.fromhex("010000000eafffe8d10000ddd5ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + self.assertEqual(golang_time_object._number_of_seconds, 63082326225) + self.assertEqual(golang_time_object._nanoseconds, 56789) + self.assertEqual(golang_time_object._time_zone_offset, 0) + + date_time_string = golang_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2000-01-01 12:23:45.000056789") + + golang_time_object = golang_time.GolangTime() + date_time_string = golang_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/hfs_time.py b/tests/hfs_time.py index 6a8152a..f9e4d6a 100644 --- a/tests/hfs_time.py +++ b/tests/hfs_time.py @@ -8,148 +8,148 @@ class HFSTimeEpochTest(unittest.TestCase): - """Tests for the HFS time epoch.""" + """Tests for the HFS time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - hfs_time_epoch = hfs_time.HFSTimeEpoch() - self.assertIsNotNone(hfs_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + hfs_time_epoch = hfs_time.HFSTimeEpoch() + self.assertIsNotNone(hfs_time_epoch) class HFSTimeTest(unittest.TestCase): - """Tests for the HFS timestamp.""" + """Tests for the HFS timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - self.assertEqual(hfs_time_object.timestamp, 3458215528) + def testProperties(self): + """Tests the properties.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + self.assertEqual(hfs_time_object.timestamp, 3458215528) - hfs_time_object = hfs_time.HFSTime() - self.assertIsNone(hfs_time_object.timestamp) + hfs_time_object = hfs_time.HFSTime() + self.assertIsNone(hfs_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1375370728.0')) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1375370728.0")) - hfs_time_object = hfs_time.HFSTime( - time_zone_offset=60, timestamp=3458215528) + hfs_time_object = hfs_time.HFSTime(time_zone_offset=60, timestamp=3458215528) - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1375367128.0')) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1375367128.0")) - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - hfs_time_object.time_zone_offset = 60 + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + hfs_time_object.time_zone_offset = 60 - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1375367128.0')) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1375367128.0")) - hfs_time_object = hfs_time.HFSTime(timestamp=0x1ffffffff) + hfs_time_object = hfs_time.HFSTime(timestamp=0x1FFFFFFFF) - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - hfs_time_object = hfs_time.HFSTime(timestamp=-0x1ffffffff) + hfs_time_object = hfs_time.HFSTime(timestamp=-0x1FFFFFFFF) - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - hfs_time_object = hfs_time.HFSTime() + hfs_time_object = hfs_time.HFSTime() - normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = hfs_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - hfs_time_object = hfs_time.HFSTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + hfs_time_object = hfs_time.HFSTime() - hfs_time_object.CopyFromDateTimeString('2013-08-01') - self.assertEqual(hfs_time_object._timestamp, 3458160000) - self.assertEqual(hfs_time_object._time_zone_offset, None) + hfs_time_object.CopyFromDateTimeString("2013-08-01") + self.assertEqual(hfs_time_object._timestamp, 3458160000) + self.assertEqual(hfs_time_object._time_zone_offset, None) - hfs_time_object.CopyFromDateTimeString('2013-08-01 15:25:28') - self.assertEqual(hfs_time_object._timestamp, 3458215528) - self.assertEqual(hfs_time_object._time_zone_offset, None) + hfs_time_object.CopyFromDateTimeString("2013-08-01 15:25:28") + self.assertEqual(hfs_time_object._timestamp, 3458215528) + self.assertEqual(hfs_time_object._time_zone_offset, None) - hfs_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875') - self.assertEqual(hfs_time_object._timestamp, 3458215528) - self.assertEqual(hfs_time_object._time_zone_offset, None) + hfs_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875") + self.assertEqual(hfs_time_object._timestamp, 3458215528) + self.assertEqual(hfs_time_object._time_zone_offset, None) - hfs_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875-01:00') - self.assertEqual(hfs_time_object._timestamp, 3458215528) - self.assertEqual(hfs_time_object._time_zone_offset, -60) + hfs_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875-01:00") + self.assertEqual(hfs_time_object._timestamp, 3458215528) + self.assertEqual(hfs_time_object._time_zone_offset, -60) - hfs_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875+01:00') - self.assertEqual(hfs_time_object._timestamp, 3458215528) - self.assertEqual(hfs_time_object._time_zone_offset, 60) + hfs_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875+01:00") + self.assertEqual(hfs_time_object._timestamp, 3458215528) + self.assertEqual(hfs_time_object._time_zone_offset, 60) - hfs_time_object.CopyFromDateTimeString('1904-01-02 00:00:00') - self.assertEqual(hfs_time_object._timestamp, 86400) - self.assertEqual(hfs_time_object._time_zone_offset, None) + hfs_time_object.CopyFromDateTimeString("1904-01-02 00:00:00") + self.assertEqual(hfs_time_object._timestamp, 86400) + self.assertEqual(hfs_time_object._time_zone_offset, None) - with self.assertRaises(ValueError): - hfs_time_object.CopyFromDateTimeString('1600-01-02 00:00:00') + with self.assertRaises(ValueError): + hfs_time_object.CopyFromDateTimeString("1600-01-02 00:00:00") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - date_time_string = hfs_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2013-08-01 15:25:28') + date_time_string = hfs_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2013-08-01 15:25:28") - hfs_time_object = hfs_time.HFSTime() + hfs_time_object = hfs_time.HFSTime() - date_time_string = hfs_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = hfs_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - date_time_string = hfs_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2013-08-01T15:25:28+00:00') + date_time_string = hfs_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2013-08-01T15:25:28+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testGetDate(self): + """Tests the GetDate function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - date_tuple = hfs_time_object.GetDate() - self.assertEqual(date_tuple, (2013, 8, 1)) + date_tuple = hfs_time_object.GetDate() + self.assertEqual(date_tuple, (2013, 8, 1)) - hfs_time_object = hfs_time.HFSTime() + hfs_time_object = hfs_time.HFSTime() - date_tuple = hfs_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = hfs_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - date_with_time_of_day_tuple = hfs_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2013, 8, 1, 15, 25, 28)) + date_with_time_of_day_tuple = hfs_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2013, 8, 1, 15, 25, 28)) - hfs_time_object = hfs_time.HFSTime() + hfs_time_object = hfs_time.HFSTime() - date_with_time_of_day_tuple = hfs_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = hfs_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + hfs_time_object = hfs_time.HFSTime(timestamp=3458215528) - time_of_day_tuple = hfs_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (15, 25, 28)) + time_of_day_tuple = hfs_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (15, 25, 28)) - hfs_time_object = hfs_time.HFSTime() + hfs_time_object = hfs_time.HFSTime() - time_of_day_tuple = hfs_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = hfs_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/interface.py b/tests/interface.py index 9df76e7..ab1a679 100644 --- a/tests/interface.py +++ b/tests/interface.py @@ -8,678 +8,712 @@ class EmptyDateTimeValues(interface.DateTimeValues): - """Empty date time values for testing.""" + """Empty date time values for testing.""" - # pylint: disable=abstract-method,redundant-returns-doc + # pylint: disable=abstract-method,redundant-returns-doc - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. - Returns: - float: normalized timestamp, which is None for testing purposes. - """ - return None + Returns: + float: normalized timestamp, which is None for testing purposes. + """ + return None class TestDateTimeValues(interface.DateTimeValues): - """Date time values for testing.""" + """Date time values for testing.""" - # pylint: disable=abstract-method + # pylint: disable=abstract-method - def _GetNormalizedTimestamp(self): - """Retrieves the normalized timestamp. + def _GetNormalizedTimestamp(self): + """Retrieves the normalized timestamp. - Returns: - float: normalized timestamp, which is 0.0 for testing purposes. - """ - return 0.0 + Returns: + float: normalized timestamp, which is 0.0 for testing purposes. + """ + return 0.0 class DateTimeEpochTest(unittest.TestCase): - """Tests for the date and time epoch interface.""" + """Tests for the date and time epoch interface.""" - def testInitialize(self): - """Tests the __init__ function.""" - date_time_epoch = interface.DateTimeEpoch(1970, 1, 1) - self.assertIsNotNone(date_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + date_time_epoch = interface.DateTimeEpoch(1970, 1, 1) + self.assertIsNotNone(date_time_epoch) class DateTimeValuesTest(unittest.TestCase): - """Tests for the date and time values interface.""" + """Tests for the date and time values interface.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testIsDelta(self): - """Tests the is_delta property.""" - date_time_values = interface.DateTimeValues(is_delta=True) - self.assertTrue(date_time_values.is_delta) + def testIsDelta(self): + """Tests the is_delta property.""" + date_time_values = interface.DateTimeValues(is_delta=True) + self.assertTrue(date_time_values.is_delta) - def testPrecision(self): - """Tests the precision property.""" - date_time_values = interface.DateTimeValues( - precision=definitions.PRECISION_1_MILLISECOND) - self.assertEqual(date_time_values.precision, '1ms') + def testPrecision(self): + """Tests the precision property.""" + date_time_values = interface.DateTimeValues( + precision=definitions.PRECISION_1_MILLISECOND + ) + self.assertEqual(date_time_values.precision, "1ms") - def testTimeZoneOffset(self): - """Tests the time_zone_offset property.""" - date_time_values = interface.DateTimeValues(time_zone_offset=60) - self.assertEqual(date_time_values.time_zone_offset, 60) + def testTimeZoneOffset(self): + """Tests the time_zone_offset property.""" + date_time_values = interface.DateTimeValues(time_zone_offset=60) + self.assertEqual(date_time_values.time_zone_offset, 60) - def testComparison(self): - """Tests the comparison functions.""" - date_time_values1 = EmptyDateTimeValues() + def testComparison(self): + """Tests the comparison functions.""" + date_time_values1 = EmptyDateTimeValues() - date_time_values2 = EmptyDateTimeValues() + date_time_values2 = EmptyDateTimeValues() - self.assertTrue(date_time_values1 == date_time_values2) - self.assertTrue(date_time_values1 >= date_time_values2) - self.assertFalse(date_time_values1 > date_time_values2) - self.assertTrue(date_time_values1 <= date_time_values2) - self.assertFalse(date_time_values1 < date_time_values2) - self.assertFalse(date_time_values1 != date_time_values2) + self.assertTrue(date_time_values1 == date_time_values2) + self.assertTrue(date_time_values1 >= date_time_values2) + self.assertFalse(date_time_values1 > date_time_values2) + self.assertTrue(date_time_values1 <= date_time_values2) + self.assertFalse(date_time_values1 < date_time_values2) + self.assertFalse(date_time_values1 != date_time_values2) - date_time_values1 = EmptyDateTimeValues() + date_time_values1 = EmptyDateTimeValues() - date_time_values2 = TestDateTimeValues() + date_time_values2 = TestDateTimeValues() - self.assertFalse(date_time_values1 == date_time_values2) - self.assertFalse(date_time_values1 >= date_time_values2) - self.assertFalse(date_time_values1 > date_time_values2) - self.assertTrue(date_time_values1 <= date_time_values2) - self.assertTrue(date_time_values1 < date_time_values2) - self.assertTrue(date_time_values1 != date_time_values2) + self.assertFalse(date_time_values1 == date_time_values2) + self.assertFalse(date_time_values1 >= date_time_values2) + self.assertFalse(date_time_values1 > date_time_values2) + self.assertTrue(date_time_values1 <= date_time_values2) + self.assertTrue(date_time_values1 < date_time_values2) + self.assertTrue(date_time_values1 != date_time_values2) - date_time_values1 = TestDateTimeValues() + date_time_values1 = TestDateTimeValues() - date_time_values2 = EmptyDateTimeValues() + date_time_values2 = EmptyDateTimeValues() - self.assertFalse(date_time_values1 == date_time_values2) - self.assertTrue(date_time_values1 >= date_time_values2) - self.assertTrue(date_time_values1 > date_time_values2) - self.assertFalse(date_time_values1 <= date_time_values2) - self.assertFalse(date_time_values1 < date_time_values2) - self.assertTrue(date_time_values1 != date_time_values2) + self.assertFalse(date_time_values1 == date_time_values2) + self.assertTrue(date_time_values1 >= date_time_values2) + self.assertTrue(date_time_values1 > date_time_values2) + self.assertFalse(date_time_values1 <= date_time_values2) + self.assertFalse(date_time_values1 < date_time_values2) + self.assertTrue(date_time_values1 != date_time_values2) - date_time_values1 = TestDateTimeValues() + date_time_values1 = TestDateTimeValues() - date_time_values2 = TestDateTimeValues() + date_time_values2 = TestDateTimeValues() - self.assertTrue(date_time_values1 == date_time_values2) - self.assertTrue(date_time_values1 >= date_time_values2) - self.assertFalse(date_time_values1 > date_time_values2) - self.assertTrue(date_time_values1 <= date_time_values2) - self.assertFalse(date_time_values1 < date_time_values2) - self.assertFalse(date_time_values1 != date_time_values2) + self.assertTrue(date_time_values1 == date_time_values2) + self.assertTrue(date_time_values1 >= date_time_values2) + self.assertFalse(date_time_values1 > date_time_values2) + self.assertTrue(date_time_values1 <= date_time_values2) + self.assertFalse(date_time_values1 < date_time_values2) + self.assertFalse(date_time_values1 != date_time_values2) - self.assertFalse(date_time_values1 == 0.0) + self.assertFalse(date_time_values1 == 0.0) - with self.assertRaises(ValueError): - date_time_values1 >= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + date_time_values1 >= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - date_time_values1 > 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + date_time_values1 > 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - date_time_values1 <= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + date_time_values1 <= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - date_time_values1 < 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + date_time_values1 < 0.0 # pylint: disable=pointless-statement - self.assertTrue(date_time_values1 != 0.0) + self.assertTrue(date_time_values1 != 0.0) - def testCopyDateFromString(self): - """Tests the _CopyDateFromString function.""" - date_time_values = interface.DateTimeValues() + def testCopyDateFromString(self): + """Tests the _CopyDateFromString function.""" + date_time_values = interface.DateTimeValues() + + expected_date_tuple = (2010, 1, 1) + date_tuple = date_time_values._CopyDateFromString("2010-01-01") + self.assertEqual(date_tuple, expected_date_tuple) + + expected_date_tuple = (2010, 8, 1) + date_tuple = date_time_values._CopyDateFromString("2010-08-01") + self.assertEqual(date_tuple, expected_date_tuple) + + expected_date_tuple = (2010, 8, 12) + date_tuple = date_time_values._CopyDateFromString("2010-08-12") + self.assertEqual(date_tuple, expected_date_tuple) + + expected_date_tuple = (2010, 8, 31) + date_tuple = date_time_values._CopyDateFromString("2010-08-31") + self.assertEqual(date_tuple, expected_date_tuple) + + expected_date_tuple = (2010, 12, 31) + date_tuple = date_time_values._CopyDateFromString("2010-12-31") + self.assertEqual(date_tuple, expected_date_tuple) + + expected_date_tuple = (1601, 1, 2) + date_tuple = date_time_values._CopyDateFromString("1601-01-02") + self.assertEqual(date_tuple, expected_date_tuple) + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("195a-01-02") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("10000-01-02") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("2010-09-00") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("2010-09-31") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("1601-01-32") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("1601-01-b2") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("1601-13-02") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("1601-a1-02") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("2010-02-29") + + with self.assertRaises(ValueError): + date_time_values._CopyDateFromString("2010-04-31") + + def testCopyDateTimeFromString(self): + """Tests the _CopyDateTimeFromString function.""" + date_time_values = interface.DateTimeValues() + + expected_date_dict = {"year": 2010, "month": 8, "day_of_month": 12} + date_dict = date_time_values._CopyDateTimeFromString("2010-08-12") + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + } + date_dict = date_time_values._CopyDateTimeFromString("2010-08-12 21:06:31") + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + } + date_dict = date_time_values._CopyDateTimeFromString( + "2010-08-12 21:06:31.546875" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + "time_zone_offset": -60, + } + date_dict = date_time_values._CopyDateTimeFromString( + "2010-08-12 21:06:31.546875-01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + "time_zone_offset": 60, + } + date_dict = date_time_values._CopyDateTimeFromString( + "2010-08-12 21:06:31.546875+01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875333, + } + date_dict = date_time_values._CopyDateTimeFromString( + "2010-08-12 21:06:31.546875333" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875333, + "time_zone_offset": 60, + } + date_dict = date_time_values._CopyDateTimeFromString( + "2010-08-12 21:06:31.546875333+01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + with self.assertRaises(ValueError): + date_time_values._CopyDateTimeFromString("") + + with self.assertRaises(ValueError): + date_time_values._CopyDateTimeFromString("2010-08-12T21:06:31.546875+01:00") + + def testCopyTimeFromString(self): + """Tests the _CopyTimeFromString function.""" + date_time_values = interface.DateTimeValues() + + expected_time_tuple = (8, 4, 32, None, None) + time_tuple = date_time_values._CopyTimeFromString("08:04:32") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, None, None) + time_tuple = date_time_values._CopyTimeFromString("20:23:56") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, None, 330) + time_tuple = date_time_values._CopyTimeFromString("20:23:56+05:30") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327000000, None) + time_tuple = date_time_values._CopyTimeFromString("20:23:56.327") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327000000, 60) + time_tuple = date_time_values._CopyTimeFromString("20:23:56.327+01:00") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327124000, None) + time_tuple = date_time_values._CopyTimeFromString("20:23:56.327124") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327124000, -300) + time_tuple = date_time_values._CopyTimeFromString("20:23:56.327124-05:00") + self.assertEqual(time_tuple, expected_time_tuple) + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("14") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("14:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("24:00:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12b00:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00b00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("1s:00:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("00:60:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("00:e0:00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("00:00:60") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("00:00:w0") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00.00") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00.0000") + + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00.00w") - expected_date_tuple = (2010, 1, 1) - date_tuple = date_time_values._CopyDateFromString('2010-01-01') - self.assertEqual(date_tuple, expected_date_tuple) + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00+01b00") - expected_date_tuple = (2010, 8, 1) - date_tuple = date_time_values._CopyDateFromString('2010-08-01') - self.assertEqual(date_tuple, expected_date_tuple) + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00+0w:00") - expected_date_tuple = (2010, 8, 12) - date_tuple = date_time_values._CopyDateFromString('2010-08-12') - self.assertEqual(date_tuple, expected_date_tuple) + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00+20:00") - expected_date_tuple = (2010, 8, 31) - date_tuple = date_time_values._CopyDateFromString('2010-08-31') - self.assertEqual(date_tuple, expected_date_tuple) + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00+01:0w") - expected_date_tuple = (2010, 12, 31) - date_tuple = date_time_values._CopyDateFromString('2010-12-31') - self.assertEqual(date_tuple, expected_date_tuple) - - expected_date_tuple = (1601, 1, 2) - date_tuple = date_time_values._CopyDateFromString('1601-01-02') - self.assertEqual(date_tuple, expected_date_tuple) - - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('') + with self.assertRaises(ValueError): + date_time_values._CopyTimeFromString("12:00:00+01:60") - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('195a-01-02') + def testGetDateValues(self): + """Tests the _GetDateValues function.""" + date_time_values = interface.DateTimeValues() - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('10000-01-02') + year, month, day_of_month = date_time_values._GetDateValues(0, 2000, 1, 1) + self.assertEqual(year, 2000) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('2010-09-00') + year, month, day_of_month = date_time_values._GetDateValues(10, 2000, 1, 1) + self.assertEqual(year, 2000) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 11) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('2010-09-31') + year, month, day_of_month = date_time_values._GetDateValues(100, 2000, 1, 1) + self.assertEqual(year, 2000) + self.assertEqual(month, 4) + self.assertEqual(day_of_month, 10) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('1601-01-32') + year, month, day_of_month = date_time_values._GetDateValues(100, 1999, 1, 1) + self.assertEqual(year, 1999) + self.assertEqual(month, 4) + self.assertEqual(day_of_month, 11) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('1601-01-b2') + year, month, day_of_month = date_time_values._GetDateValues(0, 1999, 12, 30) + self.assertEqual(year, 1999) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 30) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('1601-13-02') + year, month, day_of_month = date_time_values._GetDateValues(5, 1999, 12, 30) + self.assertEqual(year, 2000) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 4) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('1601-a1-02') + year, month, day_of_month = date_time_values._GetDateValues(-10, 2000, 1, 1) + self.assertEqual(year, 1999) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 22) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('2010-02-29') + year, month, day_of_month = date_time_values._GetDateValues(-100, 2000, 1, 1) + self.assertEqual(year, 1999) + self.assertEqual(month, 9) + self.assertEqual(day_of_month, 23) - with self.assertRaises(ValueError): - date_time_values._CopyDateFromString('2010-04-31') + year, month, day_of_month = date_time_values._GetDateValues(-10, 2000, 1, 9) + self.assertEqual(year, 1999) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 30) - def testCopyDateTimeFromString(self): - """Tests the _CopyDateTimeFromString function.""" - date_time_values = interface.DateTimeValues() + with self.assertRaises(ValueError): + date_time_values._GetDateValues(10, -1, 1, 1) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12} - date_dict = date_time_values._CopyDateTimeFromString('2010-08-12') - self.assertEqual(date_dict, expected_date_dict) + with self.assertRaises(ValueError): + date_time_values._GetDateValues(10, 2000, 0, 1) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31') - self.assertEqual(date_dict, expected_date_dict) + with self.assertRaises(ValueError): + date_time_values._GetDateValues(10, 2000, 13, 1) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31.546875') - self.assertEqual(date_dict, expected_date_dict) + with self.assertRaises(ValueError): + date_time_values._GetDateValues(10, 2000, 1, 0) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000, - 'time_zone_offset': -60} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual(date_dict, expected_date_dict) + with self.assertRaises(ValueError): + date_time_values._GetDateValues(10, 2000, 1, 32) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000, - 'time_zone_offset': 60} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual(date_dict, expected_date_dict) + year, month, day_of_month = date_time_values._GetDateValues(0, 1899, 12, 30) + self.assertEqual(year, 1899) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 30) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875333} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31.546875333') - self.assertEqual(date_dict, expected_date_dict) + year, month, day_of_month = date_time_values._GetDateValues(25569, 1899, 12, 30) + self.assertEqual(year, 1970) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875333, - 'time_zone_offset': 60} - date_dict = date_time_values._CopyDateTimeFromString( - '2010-08-12 21:06:31.546875333+01:00') - self.assertEqual(date_dict, expected_date_dict) + year, month, day_of_month = date_time_values._GetDateValues(36526, 1899, 12, 30) + self.assertEqual(year, 2000) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - with self.assertRaises(ValueError): - date_time_values._CopyDateTimeFromString('') + year, month, day_of_month = date_time_values._GetDateValues(41275, 1899, 12, 30) + self.assertEqual(year, 2013) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - with self.assertRaises(ValueError): - date_time_values._CopyDateTimeFromString( - '2010-08-12T21:06:31.546875+01:00') + year, month, day_of_month = date_time_values._GetDateValues(41443, 1899, 12, 30) + self.assertEqual(year, 2013) + self.assertEqual(month, 6) + self.assertEqual(day_of_month, 18) - def testCopyTimeFromString(self): - """Tests the _CopyTimeFromString function.""" - date_time_values = interface.DateTimeValues() + year, month, day_of_month = date_time_values._GetDateValues( + -25569, 1899, 12, 30 + ) + self.assertEqual(year, 1829) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 28) - expected_time_tuple = (8, 4, 32, None, None) - time_tuple = date_time_values._CopyTimeFromString('08:04:32') - self.assertEqual(time_tuple, expected_time_tuple) + year, month, day_of_month = date_time_values._GetDateValues(0, 1970, 1, 1) + self.assertEqual(year, 1970) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - expected_time_tuple = (20, 23, 56, None, None) - time_tuple = date_time_values._CopyTimeFromString('20:23:56') - self.assertEqual(time_tuple, expected_time_tuple) + year, month, day_of_month = date_time_values._GetDateValues(-1, 1970, 1, 1) + self.assertEqual(year, 1969) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 31) - expected_time_tuple = (20, 23, 56, None, 330) - time_tuple = date_time_values._CopyTimeFromString('20:23:56+05:30') - self.assertEqual(time_tuple, expected_time_tuple) + year, month, day_of_month = date_time_values._GetDateValues(364, 1970, 1, 1) + self.assertEqual(year, 1970) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 31) - expected_time_tuple = (20, 23, 56, 327000000, None) - time_tuple = date_time_values._CopyTimeFromString('20:23:56.327') - self.assertEqual(time_tuple, expected_time_tuple) + year, month, day_of_month = date_time_values._GetDateValues(1460, 1970, 1, 1) + self.assertEqual(year, 1973) + self.assertEqual(month, 12) + self.assertEqual(day_of_month, 31) - expected_time_tuple = (20, 23, 56, 327000000, 60) - time_tuple = date_time_values._CopyTimeFromString('20:23:56.327+01:00') - self.assertEqual(time_tuple, expected_time_tuple) + def testGetDateValuesWithEpoch(self): + """Tests the _GetDateValuesWithEpoch function.""" + date_time_epoch = interface.DateTimeEpoch(2000, 1, 1) + date_time_values = interface.DateTimeValues() - expected_time_tuple = (20, 23, 56, 327124000, None) - time_tuple = date_time_values._CopyTimeFromString('20:23:56.327124') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 23, 56, 327124000, -300) - time_tuple = date_time_values._CopyTimeFromString('20:23:56.327124-05:00') - self.assertEqual(time_tuple, expected_time_tuple) - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('14') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('14:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('24:00:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12b00:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00b00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('1s:00:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('00:60:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('00:e0:00') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('00:00:60') + year, month, day_of_month = date_time_values._GetDateValuesWithEpoch( + 0, date_time_epoch + ) + self.assertEqual(year, 2000) + self.assertEqual(month, 1) + self.assertEqual(day_of_month, 1) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('00:00:w0') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00.00') + with self.assertRaises(ValueError): + date_time_values._GetDateValuesWithEpoch(-1000000000, date_time_epoch) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00.0000') - - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00.00w') + def testGetDayOfYear(self): + """Tests the _GetDayOfYear function.""" + date_time_values = interface.DateTimeValues() - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00+01b00') + day_of_year = date_time_values._GetDayOfYear(1999, 1, 1) + self.assertEqual(day_of_year, 1) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00+0w:00') + day_of_year = date_time_values._GetDayOfYear(1999, 4, 21) + self.assertEqual(day_of_year, 111) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00+20:00') + day_of_year = date_time_values._GetDayOfYear(1999, 12, 31) + self.assertEqual(day_of_year, 365) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00+01:0w') + day_of_year = date_time_values._GetDayOfYear(2000, 1, 1) + self.assertEqual(day_of_year, 1) - with self.assertRaises(ValueError): - date_time_values._CopyTimeFromString('12:00:00+01:60') + day_of_year = date_time_values._GetDayOfYear(2000, 4, 21) + self.assertEqual(day_of_year, 112) - def testGetDateValues(self): - """Tests the _GetDateValues function.""" - date_time_values = interface.DateTimeValues() + day_of_year = date_time_values._GetDayOfYear(2000, 12, 31) + self.assertEqual(day_of_year, 366) - year, month, day_of_month = date_time_values._GetDateValues(0, 2000, 1, 1) - self.assertEqual(year, 2000) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) + with self.assertRaises(ValueError): + date_time_values._GetDayOfYear(1999, 0, 1) + + with self.assertRaises(ValueError): + date_time_values._GetDayOfYear(1999, 13, 1) + + with self.assertRaises(ValueError): + date_time_values._GetDayOfYear(1999, 1, 0) + + with self.assertRaises(ValueError): + date_time_values._GetDayOfYear(1999, 1, 32) + + def testGetDaysPerMonth(self): + """Tests the _GetDaysPerMonth function.""" + date_time_values = interface.DateTimeValues() - year, month, day_of_month = date_time_values._GetDateValues(10, 2000, 1, 1) - self.assertEqual(year, 2000) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 11) + expected_days_per_month = list(definitions.DAYS_PER_MONTH) - year, month, day_of_month = date_time_values._GetDateValues(100, 2000, 1, 1) - self.assertEqual(year, 2000) - self.assertEqual(month, 4) - self.assertEqual(day_of_month, 10) + days_per_month = [] + for month in range(1, 13): + days_per_month.append(date_time_values._GetDaysPerMonth(1999, month)) - year, month, day_of_month = date_time_values._GetDateValues(100, 1999, 1, 1) - self.assertEqual(year, 1999) - self.assertEqual(month, 4) - self.assertEqual(day_of_month, 11) - - year, month, day_of_month = date_time_values._GetDateValues(0, 1999, 12, 30) - self.assertEqual(year, 1999) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 30) - - year, month, day_of_month = date_time_values._GetDateValues(5, 1999, 12, 30) - self.assertEqual(year, 2000) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 4) - - year, month, day_of_month = date_time_values._GetDateValues(-10, 2000, 1, 1) - self.assertEqual(year, 1999) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 22) - - year, month, day_of_month = date_time_values._GetDateValues( - -100, 2000, 1, 1) - self.assertEqual(year, 1999) - self.assertEqual(month, 9) - self.assertEqual(day_of_month, 23) - - year, month, day_of_month = date_time_values._GetDateValues(-10, 2000, 1, 9) - self.assertEqual(year, 1999) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 30) - - with self.assertRaises(ValueError): - date_time_values._GetDateValues(10, -1, 1, 1) - - with self.assertRaises(ValueError): - date_time_values._GetDateValues(10, 2000, 0, 1) - - with self.assertRaises(ValueError): - date_time_values._GetDateValues(10, 2000, 13, 1) - - with self.assertRaises(ValueError): - date_time_values._GetDateValues(10, 2000, 1, 0) - - with self.assertRaises(ValueError): - date_time_values._GetDateValues(10, 2000, 1, 32) - - year, month, day_of_month = date_time_values._GetDateValues( - 0, 1899, 12, 30) - self.assertEqual(year, 1899) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 30) - - year, month, day_of_month = date_time_values._GetDateValues( - 25569, 1899, 12, 30) - self.assertEqual(year, 1970) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) - - year, month, day_of_month = date_time_values._GetDateValues( - 36526, 1899, 12, 30) - self.assertEqual(year, 2000) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) - - year, month, day_of_month = date_time_values._GetDateValues( - 41275, 1899, 12, 30) - self.assertEqual(year, 2013) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) - - year, month, day_of_month = date_time_values._GetDateValues( - 41443, 1899, 12, 30) - self.assertEqual(year, 2013) - self.assertEqual(month, 6) - self.assertEqual(day_of_month, 18) - - year, month, day_of_month = date_time_values._GetDateValues( - -25569, 1899, 12, 30) - self.assertEqual(year, 1829) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 28) - - year, month, day_of_month = date_time_values._GetDateValues(0, 1970, 1, 1) - self.assertEqual(year, 1970) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) - - year, month, day_of_month = date_time_values._GetDateValues(-1, 1970, 1, 1) - self.assertEqual(year, 1969) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 31) - - year, month, day_of_month = date_time_values._GetDateValues(364, 1970, 1, 1) - self.assertEqual(year, 1970) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 31) - - year, month, day_of_month = date_time_values._GetDateValues( - 1460, 1970, 1, 1) - self.assertEqual(year, 1973) - self.assertEqual(month, 12) - self.assertEqual(day_of_month, 31) + self.assertEqual(days_per_month, expected_days_per_month) - def testGetDateValuesWithEpoch(self): - """Tests the _GetDateValuesWithEpoch function.""" - date_time_epoch = interface.DateTimeEpoch(2000, 1, 1) - date_time_values = interface.DateTimeValues() + expected_days_per_month[1] += 1 - year, month, day_of_month = date_time_values._GetDateValuesWithEpoch( - 0, date_time_epoch) - self.assertEqual(year, 2000) - self.assertEqual(month, 1) - self.assertEqual(day_of_month, 1) + days_per_month = [] + for month in range(1, 13): + days_per_month.append(date_time_values._GetDaysPerMonth(2000, month)) - with self.assertRaises(ValueError): - date_time_values._GetDateValuesWithEpoch(-1000000000, date_time_epoch) + self.assertEqual(days_per_month, expected_days_per_month) - def testGetDayOfYear(self): - """Tests the _GetDayOfYear function.""" - date_time_values = interface.DateTimeValues() + with self.assertRaises(ValueError): + date_time_values._GetDaysPerMonth(1999, 0) - day_of_year = date_time_values._GetDayOfYear(1999, 1, 1) - self.assertEqual(day_of_year, 1) + with self.assertRaises(ValueError): + date_time_values._GetDaysPerMonth(1999, 13) - day_of_year = date_time_values._GetDayOfYear(1999, 4, 21) - self.assertEqual(day_of_year, 111) + def testGetNumberOfDaysInCentury(self): + """Tests the _GetNumberOfDaysInCentury function.""" + date_time_values = interface.DateTimeValues() - day_of_year = date_time_values._GetDayOfYear(1999, 12, 31) - self.assertEqual(day_of_year, 365) + self.assertEqual(date_time_values._GetNumberOfDaysInCentury(1700), 36524) + self.assertEqual(date_time_values._GetNumberOfDaysInCentury(2000), 36525) + self.assertEqual(date_time_values._GetNumberOfDaysInCentury(10000), 36525) + self.assertEqual(date_time_values._GetNumberOfDaysInCentury(10100), 36524) - day_of_year = date_time_values._GetDayOfYear(2000, 1, 1) - self.assertEqual(day_of_year, 1) + with self.assertRaises(ValueError): + date_time_values._GetNumberOfDaysInCentury(-1) - day_of_year = date_time_values._GetDayOfYear(2000, 4, 21) - self.assertEqual(day_of_year, 112) + def testGetNumberOfDaysInYear(self): + """Tests the _GetNumberOfDaysInYear function.""" + date_time_values = interface.DateTimeValues() - day_of_year = date_time_values._GetDayOfYear(2000, 12, 31) - self.assertEqual(day_of_year, 366) + self.assertEqual(date_time_values._GetNumberOfDaysInYear(1999), 365) + self.assertEqual(date_time_values._GetNumberOfDaysInYear(2000), 366) + self.assertEqual(date_time_values._GetNumberOfDaysInYear(1996), 366) + self.assertEqual(date_time_values._GetNumberOfDaysInYear(10000), 366) + self.assertEqual(date_time_values._GetNumberOfDaysInYear(10100), 365) - with self.assertRaises(ValueError): - date_time_values._GetDayOfYear(1999, 0, 1) + def testGetNumberOfSecondsFromElements(self): + """Tests the _GetNumberOfSecondsFromElements function.""" + date_time_values = interface.DateTimeValues() - with self.assertRaises(ValueError): - date_time_values._GetDayOfYear(1999, 13, 1) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 1970, 1, 1, 0, 1, 0 + ) + self.assertEqual(number_of_seconds, 60) - with self.assertRaises(ValueError): - date_time_values._GetDayOfYear(1999, 1, 0) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 2010, 8, 12, 0, 0, 0 + ) + self.assertEqual(number_of_seconds, 1281571200) - with self.assertRaises(ValueError): - date_time_values._GetDayOfYear(1999, 1, 32) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 2010, 8, 12, None, None, None + ) + self.assertEqual(number_of_seconds, 1281571200) - def testGetDaysPerMonth(self): - """Tests the _GetDaysPerMonth function.""" - date_time_values = interface.DateTimeValues() + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 2010, 8, 12, 21, 6, 31 + ) + self.assertEqual(number_of_seconds, 1281647191) - expected_days_per_month = list(definitions.DAYS_PER_MONTH) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 2012, 3, 5, 20, 40, 0 + ) + self.assertEqual(number_of_seconds, 1330980000) - days_per_month = [] - for month in range(1, 13): - days_per_month.append(date_time_values._GetDaysPerMonth(1999, month)) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 1601, 1, 2, 0, 0, 0 + ) + self.assertEqual(number_of_seconds, -11644387200) - self.assertEqual(days_per_month, expected_days_per_month) + number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( + 0, 1, 2, 0, 0, 0 + ) + self.assertEqual(number_of_seconds, -62167132800) - expected_days_per_month[1] += 1 - - days_per_month = [] - for month in range(1, 13): - days_per_month.append(date_time_values._GetDaysPerMonth(2000, month)) - - self.assertEqual(days_per_month, expected_days_per_month) - - with self.assertRaises(ValueError): - date_time_values._GetDaysPerMonth(1999, 0) - - with self.assertRaises(ValueError): - date_time_values._GetDaysPerMonth(1999, 13) - - def testGetNumberOfDaysInCentury(self): - """Tests the _GetNumberOfDaysInCentury function.""" - date_time_values = interface.DateTimeValues() - - self.assertEqual(date_time_values._GetNumberOfDaysInCentury(1700), 36524) - self.assertEqual(date_time_values._GetNumberOfDaysInCentury(2000), 36525) - self.assertEqual(date_time_values._GetNumberOfDaysInCentury(10000), 36525) - self.assertEqual(date_time_values._GetNumberOfDaysInCentury(10100), 36524) - - with self.assertRaises(ValueError): - date_time_values._GetNumberOfDaysInCentury(-1) - - def testGetNumberOfDaysInYear(self): - """Tests the _GetNumberOfDaysInYear function.""" - date_time_values = interface.DateTimeValues() - - self.assertEqual(date_time_values._GetNumberOfDaysInYear(1999), 365) - self.assertEqual(date_time_values._GetNumberOfDaysInYear(2000), 366) - self.assertEqual(date_time_values._GetNumberOfDaysInYear(1996), 366) - self.assertEqual(date_time_values._GetNumberOfDaysInYear(10000), 366) - self.assertEqual(date_time_values._GetNumberOfDaysInYear(10100), 365) - - def testGetNumberOfSecondsFromElements(self): - """Tests the _GetNumberOfSecondsFromElements function.""" - date_time_values = interface.DateTimeValues() - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 1970, 1, 1, 0, 1, 0) - self.assertEqual(number_of_seconds, 60) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 2010, 8, 12, 0, 0, 0) - self.assertEqual(number_of_seconds, 1281571200) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 2010, 8, 12, None, None, None) - self.assertEqual(number_of_seconds, 1281571200) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 2010, 8, 12, 21, 6, 31) - self.assertEqual(number_of_seconds, 1281647191) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 2012, 3, 5, 20, 40, 0) - self.assertEqual(number_of_seconds, 1330980000) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 1601, 1, 2, 0, 0, 0) - self.assertEqual(number_of_seconds, -11644387200) - - number_of_seconds = date_time_values._GetNumberOfSecondsFromElements( - 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, 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, 8, 12, 21, 99, 31) - - with self.assertRaises(ValueError): - date_time_values._GetNumberOfSecondsFromElements( - 2010, 8, 12, 21, 6, 65) - - with self.assertRaises(ValueError): - date_time_values._GetNumberOfSecondsFromElements( - 2013, 2, 29, 1, 4, 25) - - with self.assertRaises(ValueError): - date_time_values._GetNumberOfSecondsFromElements( - 10000, 8, 12, 21, 6, 31) - - def testGetTimeValues(self): - """Tests the _GetTimeValues function.""" - date_time_values = interface.DateTimeValues() - - days, hours, minutes, seconds = date_time_values._GetTimeValues(10) - self.assertEqual(days, 0) - self.assertEqual(hours, 0) - self.assertEqual(minutes, 0) - self.assertEqual(seconds, 10) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(190) - self.assertEqual(days, 0) - self.assertEqual(hours, 0) - self.assertEqual(minutes, 3) - self.assertEqual(seconds, 10) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(18190) - self.assertEqual(days, 0) - self.assertEqual(hours, 5) - self.assertEqual(minutes, 3) - self.assertEqual(seconds, 10) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(190990) - self.assertEqual(days, 2) - self.assertEqual(hours, 5) - self.assertEqual(minutes, 3) - self.assertEqual(seconds, 10) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(-10) - self.assertEqual(days, -1) - self.assertEqual(hours, 23) - self.assertEqual(minutes, 59) - self.assertEqual(seconds, 50) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(-190) - self.assertEqual(days, -1) - self.assertEqual(hours, 23) - self.assertEqual(minutes, 56) - self.assertEqual(seconds, 50) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(-18190) - self.assertEqual(days, -1) - self.assertEqual(hours, 18) - self.assertEqual(minutes, 56) - self.assertEqual(seconds, 50) - - days, hours, minutes, seconds = date_time_values._GetTimeValues(-190990) - self.assertEqual(days, -3) - self.assertEqual(hours, 18) - self.assertEqual(minutes, 56) - self.assertEqual(seconds, 50) - - def testIsLeapYear(self): - """Tests the _IsLeapYear function.""" - date_time_values = interface.DateTimeValues() - - self.assertFalse(date_time_values._IsLeapYear(1999)) - self.assertTrue(date_time_values._IsLeapYear(2000)) - self.assertTrue(date_time_values._IsLeapYear(1996)) - - -if __name__ == '__main__': - unittest.main() + 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, 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, 8, 12, 21, 99, 31) + + with self.assertRaises(ValueError): + date_time_values._GetNumberOfSecondsFromElements(2010, 8, 12, 21, 6, 65) + + with self.assertRaises(ValueError): + date_time_values._GetNumberOfSecondsFromElements(2013, 2, 29, 1, 4, 25) + + with self.assertRaises(ValueError): + date_time_values._GetNumberOfSecondsFromElements(10000, 8, 12, 21, 6, 31) + + def testGetTimeValues(self): + """Tests the _GetTimeValues function.""" + date_time_values = interface.DateTimeValues() + + days, hours, minutes, seconds = date_time_values._GetTimeValues(10) + self.assertEqual(days, 0) + self.assertEqual(hours, 0) + self.assertEqual(minutes, 0) + self.assertEqual(seconds, 10) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(190) + self.assertEqual(days, 0) + self.assertEqual(hours, 0) + self.assertEqual(minutes, 3) + self.assertEqual(seconds, 10) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(18190) + self.assertEqual(days, 0) + self.assertEqual(hours, 5) + self.assertEqual(minutes, 3) + self.assertEqual(seconds, 10) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(190990) + self.assertEqual(days, 2) + self.assertEqual(hours, 5) + self.assertEqual(minutes, 3) + self.assertEqual(seconds, 10) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(-10) + self.assertEqual(days, -1) + self.assertEqual(hours, 23) + self.assertEqual(minutes, 59) + self.assertEqual(seconds, 50) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(-190) + self.assertEqual(days, -1) + self.assertEqual(hours, 23) + self.assertEqual(minutes, 56) + self.assertEqual(seconds, 50) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(-18190) + self.assertEqual(days, -1) + self.assertEqual(hours, 18) + self.assertEqual(minutes, 56) + self.assertEqual(seconds, 50) + + days, hours, minutes, seconds = date_time_values._GetTimeValues(-190990) + self.assertEqual(days, -3) + self.assertEqual(hours, 18) + self.assertEqual(minutes, 56) + self.assertEqual(seconds, 50) + + def testIsLeapYear(self): + """Tests the _IsLeapYear function.""" + date_time_values = interface.DateTimeValues() + + self.assertFalse(date_time_values._IsLeapYear(1999)) + self.assertTrue(date_time_values._IsLeapYear(2000)) + self.assertTrue(date_time_values._IsLeapYear(1996)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/java_time.py b/tests/java_time.py index f3e36db..b6e81d3 100644 --- a/tests/java_time.py +++ b/tests/java_time.py @@ -8,126 +8,128 @@ class JavaTimeTest(unittest.TestCase): - """Tests for the Java java.util.Date timestamp.""" + """Tests for the Java java.util.Date timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) - self.assertEqual(java_time_object.timestamp, 1281643591546) + def testProperties(self): + """Tests the properties.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) + self.assertEqual(java_time_object.timestamp, 1281643591546) - java_time_object = java_time.JavaTime() - self.assertIsNone(java_time_object.timestamp) + java_time_object = java_time.JavaTime() + self.assertIsNone(java_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - normalized_timestamp = java_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546')) + normalized_timestamp = java_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546")) - java_time_object = java_time.JavaTime( - time_zone_offset=60, timestamp=1281643591546) + java_time_object = java_time.JavaTime( + time_zone_offset=60, timestamp=1281643591546 + ) - normalized_timestamp = java_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546')) + normalized_timestamp = java_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546")) - java_time_object = java_time.JavaTime(timestamp=1281643591546) - java_time_object.time_zone_offset = 60 + java_time_object = java_time.JavaTime(timestamp=1281643591546) + java_time_object.time_zone_offset = 60 - normalized_timestamp = java_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546')) + normalized_timestamp = java_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546")) - java_time_object = java_time.JavaTime() + java_time_object = java_time.JavaTime() - normalized_timestamp = java_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = java_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - java_time_object = java_time.JavaTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + java_time_object = java_time.JavaTime() - java_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(java_time_object._timestamp, 1281571200000) - self.assertEqual(java_time_object._time_zone_offset, None) + java_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(java_time_object._timestamp, 1281571200000) + self.assertEqual(java_time_object._time_zone_offset, None) - java_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(java_time_object._timestamp, 1281647191000) - self.assertEqual(java_time_object._time_zone_offset, None) + java_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(java_time_object._timestamp, 1281647191000) + self.assertEqual(java_time_object._time_zone_offset, None) - java_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(java_time_object._timestamp, 1281647191546) - self.assertEqual(java_time_object._time_zone_offset, None) + java_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(java_time_object._timestamp, 1281647191546) + self.assertEqual(java_time_object._time_zone_offset, None) - java_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(java_time_object._timestamp, 1281647191546) - self.assertEqual(java_time_object._time_zone_offset, -60) + java_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(java_time_object._timestamp, 1281647191546) + self.assertEqual(java_time_object._time_zone_offset, -60) - java_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(java_time_object._timestamp, 1281647191546) - self.assertEqual(java_time_object._time_zone_offset, 60) + java_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(java_time_object._timestamp, 1281647191546) + self.assertEqual(java_time_object._time_zone_offset, 60) - java_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(java_time_object._timestamp, -11644387200000) - self.assertEqual(java_time_object._time_zone_offset, None) + java_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(java_time_object._timestamp, -11644387200000) + self.assertEqual(java_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - date_time_string = java_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.546') + date_time_string = java_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.546") - java_time_object = java_time.JavaTime() + java_time_object = java_time.JavaTime() - date_time_string = java_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = java_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - date_time_string = java_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.546+00:00') + date_time_string = java_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.546+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testGetDate(self): + """Tests the GetDate function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - date_tuple = java_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = java_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - java_time_object = java_time.JavaTime() + java_time_object = java_time.JavaTime() - date_tuple = java_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = java_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - date_with_time_of_day_tuple = java_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = java_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - java_time_object = java_time.JavaTime() + java_time_object = java_time.JavaTime() - date_with_time_of_day_tuple = java_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = java_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - java_time_object = java_time.JavaTime(timestamp=1281643591546) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + java_time_object = java_time.JavaTime(timestamp=1281643591546) - time_of_day_tuple = java_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = java_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - java_time_object = java_time.JavaTime() + java_time_object = java_time.JavaTime() - time_of_day_tuple = java_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = java_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/ole_automation_date.py b/tests/ole_automation_date.py index ed40560..bbc1d35 100644 --- a/tests/ole_automation_date.py +++ b/tests/ole_automation_date.py @@ -8,154 +8,160 @@ class OLEAutomationDateEpochTest(unittest.TestCase): - """Tests for the OLE Automation date epoch.""" + """Tests for the OLE Automation date epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - ole_automation_date_epoch = ole_automation_date.OLEAutomationDateEpoch() - self.assertIsNotNone(ole_automation_date_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + ole_automation_date_epoch = ole_automation_date.OLEAutomationDateEpoch() + self.assertIsNotNone(ole_automation_date_epoch) class OLEAutomationDateTest(unittest.TestCase): - """Tests for the OLE Automation date.""" + """Tests for the OLE Automation date.""" - # pylint: disable=protected-access + # pylint: disable=protected-access + + def testProperties(self): + """Tests the properties.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) + self.assertEqual(ole_automation_date_object.timestamp, 43044.480556) - def testProperties(self): - """Tests the properties.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) - self.assertEqual(ole_automation_date_object.timestamp, 43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate() + self.assertIsNone(ole_automation_date_object.timestamp) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() - self.assertIsNone(ole_automation_date_object.timestamp) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) + + expected_normalized_timestamp = decimal.Decimal("1509881520.038400194607675076") + normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + time_zone_offset=60, timestamp=43044.480556 + ) - expected_normalized_timestamp = decimal.Decimal( - '1509881520.038400194607675076') - normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + expected_normalized_timestamp = decimal.Decimal("1509877920.038400194607675076") + normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - time_zone_offset=60, timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) + ole_automation_date_object.time_zone_offset = 60 - expected_normalized_timestamp = decimal.Decimal( - '1509877920.038400194607675076') - normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + expected_normalized_timestamp = decimal.Decimal("1509877920.038400194607675076") + normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, expected_normalized_timestamp) - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) - ole_automation_date_object.time_zone_offset = 60 + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - expected_normalized_timestamp = decimal.Decimal( - '1509877920.038400194607675076') - normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, expected_normalized_timestamp) + normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - normalized_timestamp = ole_automation_date_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + ole_automation_date_object.CopyFromDateTimeString("2017-11-05") + self.assertEqual(ole_automation_date_object._timestamp, 43044.0) + self.assertEqual(ole_automation_date_object._time_zone_offset, None) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate() + ole_automation_date_object.CopyFromDateTimeString("2017-11-05 11:32:00") + self.assertEqual(ole_automation_date_object._timestamp, 43044.48055555555) + self.assertEqual(ole_automation_date_object._time_zone_offset, None) - ole_automation_date_object.CopyFromDateTimeString('2017-11-05') - self.assertEqual(ole_automation_date_object._timestamp, 43044.0) - self.assertEqual(ole_automation_date_object._time_zone_offset, None) + ole_automation_date_object.CopyFromDateTimeString("2017-11-05 11:32:00.546875") + self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) + self.assertEqual(ole_automation_date_object._time_zone_offset, None) - ole_automation_date_object.CopyFromDateTimeString('2017-11-05 11:32:00') - self.assertEqual(ole_automation_date_object._timestamp, 43044.48055555555) - self.assertEqual(ole_automation_date_object._time_zone_offset, None) + ole_automation_date_object.CopyFromDateTimeString( + "2017-11-05 11:32:00.546875-01:00" + ) + self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) + self.assertEqual(ole_automation_date_object._time_zone_offset, -60) - ole_automation_date_object.CopyFromDateTimeString( - '2017-11-05 11:32:00.546875') - self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) - self.assertEqual(ole_automation_date_object._time_zone_offset, None) + ole_automation_date_object.CopyFromDateTimeString( + "2017-11-05 11:32:00.546875+01:00" + ) + self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) + self.assertEqual(ole_automation_date_object._time_zone_offset, 60) - ole_automation_date_object.CopyFromDateTimeString( - '2017-11-05 11:32:00.546875-01:00') - self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) - self.assertEqual(ole_automation_date_object._time_zone_offset, -60) + ole_automation_date_object.CopyFromDateTimeString("1900-01-01 00:00:00") + self.assertEqual(ole_automation_date_object._timestamp, 2.0) + self.assertEqual(ole_automation_date_object._time_zone_offset, None) - ole_automation_date_object.CopyFromDateTimeString( - '2017-11-05 11:32:00.546875+01:00') - self.assertEqual(ole_automation_date_object._timestamp, 43044.480561885124) - self.assertEqual(ole_automation_date_object._time_zone_offset, 60) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) - ole_automation_date_object.CopyFromDateTimeString('1900-01-01 00:00:00') - self.assertEqual(ole_automation_date_object._timestamp, 2.0) - self.assertEqual(ole_automation_date_object._time_zone_offset, None) + date_time_string = ole_automation_date_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2017-11-05 11:32:00.038400") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - date_time_string = ole_automation_date_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2017-11-05 11:32:00.038400') + date_time_string = ole_automation_date_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) - date_time_string = ole_automation_date_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = ole_automation_date_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2017-11-05T11:32:00.038400+00:00") - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + def testGetDate(self): + """Tests the GetDate function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) - date_time_string = ole_automation_date_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2017-11-05T11:32:00.038400+00:00') + date_tuple = ole_automation_date_object.GetDate() + self.assertEqual(date_tuple, (2017, 11, 5)) - def testGetDate(self): - """Tests the GetDate function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - date_tuple = ole_automation_date_object.GetDate() - self.assertEqual(date_tuple, (2017, 11, 5)) + date_tuple = ole_automation_date_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) - date_tuple = ole_automation_date_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_with_time_of_day_tuple = ole_automation_date_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2017, 11, 5, 11, 32, 0)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - date_with_time_of_day_tuple = ( - ole_automation_date_object.GetDateWithTimeOfDay()) - self.assertEqual(date_with_time_of_day_tuple, (2017, 11, 5, 11, 32, 0)) + date_with_time_of_day_tuple = ole_automation_date_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + ole_automation_date_object = ole_automation_date.OLEAutomationDate( + timestamp=43044.480556 + ) - date_with_time_of_day_tuple = ( - ole_automation_date_object.GetDateWithTimeOfDay()) - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + time_of_day_tuple = ole_automation_date_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (11, 32, 0)) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - ole_automation_date_object = ole_automation_date.OLEAutomationDate( - timestamp=43044.480556) + ole_automation_date_object = ole_automation_date.OLEAutomationDate() - time_of_day_tuple = ole_automation_date_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (11, 32, 0)) + time_of_day_tuple = ole_automation_date_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) - ole_automation_date_object = ole_automation_date.OLEAutomationDate() - time_of_day_tuple = ole_automation_date_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) - - -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/posix_time.py b/tests/posix_time.py index 074b74b..8da7f25 100644 --- a/tests/posix_time.py +++ b/tests/posix_time.py @@ -8,624 +8,648 @@ class PosixTimeEpochTest(unittest.TestCase): - """Tests for the POSIX time epoch.""" + """Tests for the POSIX time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - posix_epoch = posix_time.PosixTimeEpoch() - self.assertIsNotNone(posix_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + posix_epoch = posix_time.PosixTimeEpoch() + self.assertIsNotNone(posix_epoch) class PosixTimeTest(unittest.TestCase): - """Tests for the POSIX timestamp.""" + """Tests for the POSIX timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) - self.assertEqual(posix_time_object.timestamp, 1281643591) + def testProperties(self): + """Tests the properties.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) + self.assertEqual(posix_time_object.timestamp, 1281643591) - posix_time_object = posix_time.PosixTime() - self.assertIsNone(posix_time_object.timestamp) + posix_time_object = posix_time.PosixTime() + self.assertIsNone(posix_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.0')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.0")) - posix_time_object = posix_time.PosixTime( - time_zone_offset=60, timestamp=1281643591) + posix_time_object = posix_time.PosixTime( + time_zone_offset=60, timestamp=1281643591 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.0')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.0")) - posix_time_object = posix_time.PosixTime(timestamp=1281643591) - posix_time_object.time_zone_offset = 60 + posix_time_object = posix_time.PosixTime(timestamp=1281643591) + posix_time_object.time_zone_offset = 60 - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.0')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.0")) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - posix_time_object = posix_time.PosixTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + posix_time_object = posix_time.PosixTime() - posix_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(posix_time_object._timestamp, 1281571200) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(posix_time_object._timestamp, 1281571200) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(posix_time_object._timestamp, 1281647191) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(posix_time_object._timestamp, 1281647191) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(posix_time_object._timestamp, 1281647191) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(posix_time_object._timestamp, 1281647191) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191) - self.assertEqual(posix_time_object._time_zone_offset, -60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191) + self.assertEqual(posix_time_object._time_zone_offset, -60) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191) - self.assertEqual(posix_time_object._time_zone_offset, 60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191) + self.assertEqual(posix_time_object._time_zone_offset, 60) - posix_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(posix_time_object._timestamp, -11644387200) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(posix_time_object._timestamp, -11644387200) + self.assertEqual(posix_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31') + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31") - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31+00:00") - posix_time_object = posix_time.PosixTime(timestamp=-11644468446) + posix_time_object = posix_time.PosixTime(timestamp=-11644468446) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '1601-01-01T01:25:54+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "1601-01-01T01:25:54+00:00") - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertIsNone(fraction_of_second) - posix_time_object = posix_time.PosixTime(timestamp=-11644468446) + posix_time_object = posix_time.PosixTime(timestamp=-11644468446) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, -11644468446) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, -11644468446) + self.assertIsNone(fraction_of_second) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testGetDate(self): + """Tests the GetDate function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) class PosixTimeInMillisecondsTest(unittest.TestCase): - """Tests for the POSIX timestamp in milliseconds.""" + """Tests for the POSIX timestamp in milliseconds.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) - self.assertEqual(posix_time_object.timestamp, 1281643591546) + def testProperties(self): + """Tests the properties.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) + self.assertEqual(posix_time_object.timestamp, 1281643591546) - posix_time_object = posix_time.PosixTimeInMilliseconds() - self.assertIsNone(posix_time_object.timestamp) + posix_time_object = posix_time.PosixTimeInMilliseconds() + self.assertIsNone(posix_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546")) - posix_time_object = posix_time.PosixTimeInMilliseconds( - time_zone_offset=60, timestamp=1281643591546) + posix_time_object = posix_time.PosixTimeInMilliseconds( + time_zone_offset=60, timestamp=1281643591546 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546")) - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) - posix_time_object.time_zone_offset = 60 + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) + posix_time_object.time_zone_offset = 60 - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546")) - posix_time_object = posix_time.PosixTimeInMilliseconds() + posix_time_object = posix_time.PosixTimeInMilliseconds() - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - # pylint: disable=protected-access + # pylint: disable=protected-access - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds() - posix_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(posix_time_object._timestamp, 1281571200000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(posix_time_object._timestamp, 1281571200000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(posix_time_object._timestamp, 1281647191000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(posix_time_object._timestamp, 1281647191000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546') - self.assertEqual(posix_time_object._timestamp, 1281647191546) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546") + self.assertEqual(posix_time_object._timestamp, 1281647191546) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546-01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191546) - self.assertEqual(posix_time_object._time_zone_offset, -60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546-01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191546) + self.assertEqual(posix_time_object._time_zone_offset, -60) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546+01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191546) - self.assertEqual(posix_time_object._time_zone_offset, 60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546+01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191546) + self.assertEqual(posix_time_object._time_zone_offset, 60) - posix_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(posix_time_object._timestamp, -11644387200000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(posix_time_object._timestamp, -11644387200000) + self.assertEqual(posix_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.546') + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.546") - posix_time_object = posix_time.PosixTimeInMilliseconds() + posix_time_object = posix_time.PosixTimeInMilliseconds() - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.546+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.546+00:00") - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=-11644468446327) + posix_time_object = posix_time.PosixTimeInMilliseconds( + timestamp=-11644468446327 + ) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '1601-01-01T01:25:53.673+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "1601-01-01T01:25:53.673+00:00") - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertEqual(fraction_of_second, 546) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertEqual(fraction_of_second, 546) - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=-11644468446327) + posix_time_object = posix_time.PosixTimeInMilliseconds( + timestamp=-11644468446327 + ) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, -11644468446) - self.assertEqual(fraction_of_second, 327) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, -11644468446) + self.assertEqual(fraction_of_second, 327) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testGetDate(self): + """Tests the GetDate function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - posix_time_object = posix_time.PosixTimeInMilliseconds() + posix_time_object = posix_time.PosixTimeInMilliseconds() - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - posix_time_object = posix_time.PosixTimeInMilliseconds() + posix_time_object = posix_time.PosixTimeInMilliseconds() - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInMilliseconds( - timestamp=1281643591546) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInMilliseconds(timestamp=1281643591546) - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - posix_time_object = posix_time.PosixTimeInMilliseconds() + posix_time_object = posix_time.PosixTimeInMilliseconds() - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) class PosixTimeInMicrosecondsTest(unittest.TestCase): - """Tests for the POSIX timestamp in microseconds.""" + """Tests for the POSIX timestamp in microseconds.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) - self.assertEqual(posix_time_object.timestamp, 1281643591546875) + def testProperties(self): + """Tests the properties.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) + self.assertEqual(posix_time_object.timestamp, 1281643591546875) - posix_time_object = posix_time.PosixTimeInMicroseconds() - self.assertIsNone(posix_time_object.timestamp) + posix_time_object = posix_time.PosixTimeInMicroseconds() + self.assertIsNone(posix_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - posix_time_object = posix_time.PosixTimeInMicroseconds( - time_zone_offset=60, timestamp=1281643591546875) + posix_time_object = posix_time.PosixTimeInMicroseconds( + time_zone_offset=60, timestamp=1281643591546875 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546875')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546875")) - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) - posix_time_object.time_zone_offset = 60 + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) + posix_time_object.time_zone_offset = 60 - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.546875')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.546875")) - posix_time_object = posix_time.PosixTimeInMicroseconds() + posix_time_object = posix_time.PosixTimeInMicroseconds() - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - # pylint: disable=protected-access + # pylint: disable=protected-access - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds() - posix_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(posix_time_object._timestamp, 1281571200000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(posix_time_object._timestamp, 1281571200000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(posix_time_object._timestamp, 1281647191000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(posix_time_object._timestamp, 1281647191000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(posix_time_object._timestamp, 1281647191546875) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(posix_time_object._timestamp, 1281647191546875) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191546875) - self.assertEqual(posix_time_object._time_zone_offset, -60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191546875) + self.assertEqual(posix_time_object._time_zone_offset, -60) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(posix_time_object._timestamp, 1281647191546875) - self.assertEqual(posix_time_object._time_zone_offset, 60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(posix_time_object._timestamp, 1281647191546875) + self.assertEqual(posix_time_object._time_zone_offset, 60) - posix_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(posix_time_object._timestamp, -11644387200000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(posix_time_object._timestamp, -11644387200000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.546875') + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.546875") - posix_time_object = posix_time.PosixTimeInMicroseconds() + posix_time_object = posix_time.PosixTimeInMicroseconds() - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.546875+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.546875+00:00") - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=-11644468446327447) + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=-11644468446327447 + ) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '1601-01-01T01:25:53.672553+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "1601-01-01T01:25:53.672553+00:00") - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertEqual(fraction_of_second, 546875) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertEqual(fraction_of_second, 546875) - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=-11644468446327447) + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=-11644468446327447 + ) - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, -11644468446) - self.assertEqual(fraction_of_second, 327447) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, -11644468446) + self.assertEqual(fraction_of_second, 327447) - posix_time_object = posix_time.PosixTime() + posix_time_object = posix_time.PosixTime() - posix_timestamp, fraction_of_second = ( - posix_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + posix_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testGetDate(self): + """Tests the GetDate function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - posix_time_object = posix_time.PosixTimeInMicroseconds() + posix_time_object = posix_time.PosixTimeInMicroseconds() - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - posix_time_object = posix_time.PosixTimeInMicroseconds() + posix_time_object = posix_time.PosixTimeInMicroseconds() - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInMicroseconds( - timestamp=1281643591546875) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInMicroseconds( + timestamp=1281643591546875 + ) - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - posix_time_object = posix_time.PosixTimeInMicroseconds() + posix_time_object = posix_time.PosixTimeInMicroseconds() - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) class PosixTimeInNanoSecondsTest(unittest.TestCase): - """Tests for the POSIX timestamp in nanoseconds.""" + """Tests for the POSIX timestamp in nanoseconds.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) - self.assertEqual(posix_time_object.timestamp, 1281643591987654321) + def testProperties(self): + """Tests the properties.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) + self.assertEqual(posix_time_object.timestamp, 1281643591987654321) - posix_time_object = posix_time.PosixTimeInNanoseconds() - self.assertIsNone(posix_time_object.timestamp) + posix_time_object = posix_time.PosixTimeInNanoseconds() + self.assertIsNone(posix_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281643591.987654321')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.987654321")) - posix_time_object = posix_time.PosixTimeInNanoseconds( - time_zone_offset=60, timestamp=1281643591987654321) + posix_time_object = posix_time.PosixTimeInNanoseconds( + time_zone_offset=60, timestamp=1281643591987654321 + ) - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.987654321')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.987654321")) - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) - posix_time_object.time_zone_offset = 60 + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) + posix_time_object.time_zone_offset = 60 - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.987654321')) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.987654321")) - posix_time_object = posix_time.PosixTimeInNanoseconds() + posix_time_object = posix_time.PosixTimeInNanoseconds() - normalized_timestamp = posix_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = posix_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds() - posix_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(posix_time_object.timestamp, 1281571200000000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(posix_time_object.timestamp, 1281571200000000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(posix_time_object.timestamp, 1281647191000000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(posix_time_object.timestamp, 1281647191000000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.654321') - self.assertEqual(posix_time_object.timestamp, 1281647191654321000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.654321") + self.assertEqual(posix_time_object.timestamp, 1281647191654321000) + self.assertEqual(posix_time_object._time_zone_offset, None) - posix_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.654321-01:00') - self.assertEqual(posix_time_object.timestamp, 1281647191654321000) - self.assertEqual(posix_time_object._time_zone_offset, -60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.654321-01:00") + self.assertEqual(posix_time_object.timestamp, 1281647191654321000) + self.assertEqual(posix_time_object._time_zone_offset, -60) - posix_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.654321+01:00') - self.assertEqual(posix_time_object.timestamp, 1281647191654321000) - self.assertEqual(posix_time_object._time_zone_offset, 60) + posix_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.654321+01:00") + self.assertEqual(posix_time_object.timestamp, 1281647191654321000) + self.assertEqual(posix_time_object._time_zone_offset, 60) - posix_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(posix_time_object.timestamp, -11644387200000000000) - self.assertEqual(posix_time_object._time_zone_offset, None) + posix_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(posix_time_object.timestamp, -11644387200000000000) + self.assertEqual(posix_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.987654321') + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.987654321") - posix_time_object = posix_time.PosixTimeInNanoseconds() + posix_time_object = posix_time.PosixTimeInNanoseconds() - date_time_string = posix_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = posix_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - date_time_string = posix_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.987654321+00:00') + date_time_string = posix_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.987654321+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testGetDate(self): + """Tests the GetDate function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - posix_time_object = posix_time.PosixTimeInNanoseconds() + posix_time_object = posix_time.PosixTimeInNanoseconds() - date_tuple = posix_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = posix_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - posix_time_object = posix_time.PosixTimeInNanoseconds() + posix_time_object = posix_time.PosixTimeInNanoseconds() - date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = posix_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - posix_time_object = posix_time.PosixTimeInNanoseconds( - timestamp=1281643591987654321) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + posix_time_object = posix_time.PosixTimeInNanoseconds( + timestamp=1281643591987654321 + ) - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - posix_time_object = posix_time.PosixTimeInNanoseconds() + posix_time_object = posix_time.PosixTimeInNanoseconds() - time_of_day_tuple = posix_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = posix_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/precisions.py b/tests/precisions.py index c3d9320..5a79696 100644 --- a/tests/precisions.py +++ b/tests/precisions.py @@ -9,210 +9,221 @@ class DateTimePrecisionHelperTest(unittest.TestCase): - """Tests for the date time precision helper interface.""" + """Tests for the date time precision helper interface.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.DateTimePrecisionHelper + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.DateTimePrecisionHelper - with self.assertRaises(NotImplementedError): - precision_helper.CopyNanosecondsToFractionOfSecond(0) + with self.assertRaises(NotImplementedError): + precision_helper.CopyNanosecondsToFractionOfSecond(0) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.DateTimePrecisionHelper + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.DateTimePrecisionHelper - with self.assertRaises(NotImplementedError): - precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 0.5) + with self.assertRaises(NotImplementedError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 0.5) class SecondsPrecisionHelperTest(unittest.TestCase): - """Tests for the seconds precision helper.""" + """Tests for the seconds precision helper.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.SecondsPrecisionHelper + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.SecondsPrecisionHelper - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - 123456) - self.assertEqual(fraction_of_second, 0.0) + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond(123456) + self.assertEqual(fraction_of_second, 0.0) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(-1) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.SecondsPrecisionHelper + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.SecondsPrecisionHelper - 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') + 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") - with self.assertRaises(ValueError): - precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + with self.assertRaises(ValueError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) class CentisecondsPrevisionHelperTest(unittest.TestCase): - """Tests for the centiseconds prevision helper.""" + """Tests for the centiseconds prevision helper.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.CentisecondsPrecisionHelper + 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')) + 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(-1) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.CentisecondsPrecisionHelper + 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') + 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) + 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.""" + """Tests for the milliseconds precision helper.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.MillisecondsPrecisionHelper + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.MillisecondsPrecisionHelper - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - 123456789) - self.assertEqual(fraction_of_second, decimal.Decimal('0.123')) + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789 + ) + self.assertEqual(fraction_of_second, decimal.Decimal("0.123")) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(-1) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.MillisecondsPrecisionHelper + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.MillisecondsPrecisionHelper - 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.123') + 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.123") - with self.assertRaises(ValueError): - precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + with self.assertRaises(ValueError): + 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 + """Tests for the decimilliseconds precision helper.""" - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - 123456789) - self.assertEqual(fraction_of_second, decimal.Decimal('0.1234')) + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.DecimillisecondsPrecisionHelper - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(-1) + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789 + ) + self.assertEqual(fraction_of_second, decimal.Decimal("0.1234")) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.DecimillisecondsPrecisionHelper + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - 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') + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.DecimillisecondsPrecisionHelper - with self.assertRaises(ValueError): - precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + 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.""" + """Tests for the microseconds precision helper.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.MicrosecondsPrecisionHelper + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.MicrosecondsPrecisionHelper - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - 123456789) - self.assertEqual(fraction_of_second, decimal.Decimal('0.123456')) + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789 + ) + self.assertEqual(fraction_of_second, decimal.Decimal("0.123456")) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(-1) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.MicrosecondsPrecisionHelper + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.MicrosecondsPrecisionHelper - 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.123456') + 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.123456") - with self.assertRaises(ValueError): - precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) + with self.assertRaises(ValueError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456) class NanosecondsPrecisionHelperTest(unittest.TestCase): - """Tests for the nanoseconds precision helper.""" + """Tests for the nanoseconds precision helper.""" - def testCopyNanosecondsToFractionOfSecond(self): - """Tests the CopyNanosecondsToFractionOfSecond function.""" - precision_helper = precisions.NanosecondsPrecisionHelper + def testCopyNanosecondsToFractionOfSecond(self): + """Tests the CopyNanosecondsToFractionOfSecond function.""" + precision_helper = precisions.NanosecondsPrecisionHelper - fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( - 123456789) - self.assertEqual(fraction_of_second, decimal.Decimal('0.123456789')) + fraction_of_second = precision_helper.CopyNanosecondsToFractionOfSecond( + 123456789 + ) + self.assertEqual(fraction_of_second, decimal.Decimal("0.123456789")) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(-1) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(-1) - with self.assertRaises(ValueError): - precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) + with self.assertRaises(ValueError): + precision_helper.CopyNanosecondsToFractionOfSecond(1000000000) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - precision_helper = precisions.NanosecondsPrecisionHelper + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + precision_helper = precisions.NanosecondsPrecisionHelper - date_time_string = precision_helper.CopyToDateTimeString( - (2018, 1, 2, 19, 45, 12), 0.123456789) - self.assertEqual(date_time_string, '2018-01-02 19:45:12.123456789') + date_time_string = precision_helper.CopyToDateTimeString( + (2018, 1, 2, 19, 45, 12), 0.123456789 + ) + self.assertEqual(date_time_string, "2018-01-02 19:45:12.123456789") - with self.assertRaises(ValueError): - precision_helper.CopyToDateTimeString( - (2018, 1, 2, 19, 45, 12), 4.123456789) + with self.assertRaises(ValueError): + precision_helper.CopyToDateTimeString((2018, 1, 2, 19, 45, 12), 4.123456789) class PrecisionHelperFactoryTest(unittest.TestCase): - """Tests for the date time precision helper factory.""" + """Tests for the date time precision helper factory.""" - def testCreatePrecisionHelper(self): - """Tests the CreatePrecisionHelper function.""" - precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( - definitions.PRECISION_1_MICROSECOND) + def testCreatePrecisionHelper(self): + """Tests the CreatePrecisionHelper function.""" + precision_helper = precisions.PrecisionHelperFactory.CreatePrecisionHelper( + definitions.PRECISION_1_MICROSECOND + ) - self.assertIsNotNone(precision_helper) + self.assertIsNotNone(precision_helper) - with self.assertRaises(ValueError): - precisions.PrecisionHelperFactory.CreatePrecisionHelper('bogus') + with self.assertRaises(ValueError): + precisions.PrecisionHelperFactory.CreatePrecisionHelper("bogus") -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/rfc2579_date_time.py b/tests/rfc2579_date_time.py index f8382b1..f48c963 100644 --- a/tests/rfc2579_date_time.py +++ b/tests/rfc2579_date_time.py @@ -8,275 +8,297 @@ class RFC2579DateTimeInvalidYear(rfc2579_date_time.RFC2579DateTime): - """RFC2579 date-time for testing invalid year.""" + """RFC2579 date-time for testing invalid year.""" - def _CopyDateTimeFromString(self, time_string): - """Copies a date and time from a string. + def _CopyDateTimeFromString(self, time_string): + """Copies a date and time from a string. - Args: - time_string (str): date and time value formatted as: - YYYY-MM-DD hh:mm:ss.######[+-]##:## + Args: + time_string (str): date and time value formatted as: + YYYY-MM-DD hh:mm:ss.######[+-]##:## - Where # are numeric digits ranging from 0 to 9 and the seconds - fraction can be either 3 or 6 digits. The time of day, seconds - fraction and time zone offset are optional. The default time zone - is UTC. + Where # are numeric digits ranging from 0 to 9 and the seconds + fraction can be either 3 or 6 digits. The time of day, seconds + fraction and time zone offset are optional. The default time zone + is UTC. - Returns: - dict[str, int]: date and time values, such as year, month, day of month, - hours, minutes, seconds, microseconds. + Returns: + dict[str, int]: date and time values, such as year, month, day of month, + hours, minutes, seconds, microseconds. - Raises: - ValueError: if the time string is invalid or not supported. - """ - return { - 'year': 70000, - 'month': 1, - 'day_of_month': 2, - 'hours': 0, - 'minutes': 0, - 'seconds': 0} + Raises: + ValueError: if the time string is invalid or not supported. + """ + return { + "year": 70000, + "month": 1, + "day_of_month": 2, + "hours": 0, + "minutes": 0, + "seconds": 0, + } class RFC2579DateTimeTest(unittest.TestCase): - """Tests for the RFC2579 date-time.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - self.assertIsNotNone(rfc2579_date_time_object) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)) - self.assertIsNotNone(rfc2579_date_time_object) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 20) - self.assertEqual(rfc2579_date_time_object.minutes, 6) - self.assertEqual(rfc2579_date_time_object.seconds, 31) - self.assertEqual(rfc2579_date_time_object.deciseconds, 6) - self.assertEqual(rfc2579_date_time_object.time_zone_offset, 120) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '-', 2, 0)) - self.assertEqual(rfc2579_date_time_object.time_zone_offset, -120) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(65537, 8, 12, 20, 6, 31, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 13, 12, 20, 6, 31, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 32, 20, 6, 31, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 24, 6, 31, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 61, 31, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 61, 6, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 11, '+', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '#', 2, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 14, 0)) - - with self.assertRaises(ValueError): - rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 60)) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.6')) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 1, 0)) - - normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.6')) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - rfc2579_date_time_object.time_zone_offset = 60 - - normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.6')) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - rfc2579_date_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281571200) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 0) - self.assertEqual(rfc2579_date_time_object.minutes, 0) - self.assertEqual(rfc2579_date_time_object.seconds, 0) - self.assertEqual(rfc2579_date_time_object.deciseconds, 0) - - rfc2579_date_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 21) - self.assertEqual(rfc2579_date_time_object.minutes, 6) - self.assertEqual(rfc2579_date_time_object.seconds, 31) - self.assertEqual(rfc2579_date_time_object.deciseconds, 0) - - rfc2579_date_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 21) - self.assertEqual(rfc2579_date_time_object.minutes, 6) - self.assertEqual(rfc2579_date_time_object.seconds, 31) - self.assertEqual(rfc2579_date_time_object.deciseconds, 5) - - rfc2579_date_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, -60) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 21) - self.assertEqual(rfc2579_date_time_object.minutes, 6) - self.assertEqual(rfc2579_date_time_object.seconds, 31) - self.assertEqual(rfc2579_date_time_object.deciseconds, 5) - self.assertEqual(rfc2579_date_time_object.time_zone_offset, -60) - - rfc2579_date_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, 60) - self.assertEqual(rfc2579_date_time_object.year, 2010) - self.assertEqual(rfc2579_date_time_object.month, 8) - self.assertEqual(rfc2579_date_time_object.day_of_month, 12) - self.assertEqual(rfc2579_date_time_object.hours, 21) - self.assertEqual(rfc2579_date_time_object.minutes, 6) - self.assertEqual(rfc2579_date_time_object.seconds, 31) - self.assertEqual(rfc2579_date_time_object.deciseconds, 5) - self.assertEqual(rfc2579_date_time_object.time_zone_offset, 60) - - rfc2579_date_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(rfc2579_date_time_object._number_of_seconds, -11644387200) - self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) - self.assertEqual(rfc2579_date_time_object.year, 1601) - self.assertEqual(rfc2579_date_time_object.month, 1) - self.assertEqual(rfc2579_date_time_object.day_of_month, 2) - self.assertEqual(rfc2579_date_time_object.hours, 0) - self.assertEqual(rfc2579_date_time_object.minutes, 0) - self.assertEqual(rfc2579_date_time_object.seconds, 0) - self.assertEqual(rfc2579_date_time_object.deciseconds, 0) - - rfc2579_date_time_object = RFC2579DateTimeInvalidYear() - - with self.assertRaises(ValueError): - rfc2579_date_time_object.CopyFromDateTimeString('9999-01-02 00:00:00') - - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - date_time_string = rfc2579_date_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.6') - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - date_time_string = rfc2579_date_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - date_time_string = rfc2579_date_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.6+00:00') - - def testGetDate(self): - """Tests the GetDate function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - date_tuple = rfc2579_date_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - date_tuple = rfc2579_date_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) - - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - date_with_time_of_day_tuple = ( - rfc2579_date_time_object.GetDateWithTimeOfDay()) - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - date_with_time_of_day_tuple = ( - rfc2579_date_time_object.GetDateWithTimeOfDay()) - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) - - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0)) - - time_of_day_tuple = rfc2579_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() - - time_of_day_tuple = rfc2579_date_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) - - -if __name__ == '__main__': - unittest.main() + """Tests for the RFC2579 date-time.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + self.assertIsNotNone(rfc2579_date_time_object) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 2, 0) + ) + self.assertIsNotNone(rfc2579_date_time_object) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 20) + self.assertEqual(rfc2579_date_time_object.minutes, 6) + self.assertEqual(rfc2579_date_time_object.seconds, 31) + self.assertEqual(rfc2579_date_time_object.deciseconds, 6) + self.assertEqual(rfc2579_date_time_object.time_zone_offset, 120) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "-", 2, 0) + ) + self.assertEqual(rfc2579_date_time_object.time_zone_offset, -120) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(65537, 8, 12, 20, 6, 31, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 13, 12, 20, 6, 31, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 32, 20, 6, 31, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 24, 6, 31, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 61, 31, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 61, 6, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 11, "+", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "#", 2, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 14, 0) + ) + + with self.assertRaises(ValueError): + rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 2, 60) + ) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.6")) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 1, 0) + ) + + normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.6")) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + rfc2579_date_time_object.time_zone_offset = 60 + + normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.6")) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + normalized_timestamp = rfc2579_date_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + rfc2579_date_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281571200) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 0) + self.assertEqual(rfc2579_date_time_object.minutes, 0) + self.assertEqual(rfc2579_date_time_object.seconds, 0) + self.assertEqual(rfc2579_date_time_object.deciseconds, 0) + + rfc2579_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 21) + self.assertEqual(rfc2579_date_time_object.minutes, 6) + self.assertEqual(rfc2579_date_time_object.seconds, 31) + self.assertEqual(rfc2579_date_time_object.deciseconds, 0) + + rfc2579_date_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 21) + self.assertEqual(rfc2579_date_time_object.minutes, 6) + self.assertEqual(rfc2579_date_time_object.seconds, 31) + self.assertEqual(rfc2579_date_time_object.deciseconds, 5) + + rfc2579_date_time_object.CopyFromDateTimeString( + "2010-08-12 21:06:31.546875-01:00" + ) + self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, -60) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 21) + self.assertEqual(rfc2579_date_time_object.minutes, 6) + self.assertEqual(rfc2579_date_time_object.seconds, 31) + self.assertEqual(rfc2579_date_time_object.deciseconds, 5) + self.assertEqual(rfc2579_date_time_object.time_zone_offset, -60) + + rfc2579_date_time_object.CopyFromDateTimeString( + "2010-08-12 21:06:31.546875+01:00" + ) + self.assertEqual(rfc2579_date_time_object._number_of_seconds, 1281647191) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, 60) + self.assertEqual(rfc2579_date_time_object.year, 2010) + self.assertEqual(rfc2579_date_time_object.month, 8) + self.assertEqual(rfc2579_date_time_object.day_of_month, 12) + self.assertEqual(rfc2579_date_time_object.hours, 21) + self.assertEqual(rfc2579_date_time_object.minutes, 6) + self.assertEqual(rfc2579_date_time_object.seconds, 31) + self.assertEqual(rfc2579_date_time_object.deciseconds, 5) + self.assertEqual(rfc2579_date_time_object.time_zone_offset, 60) + + rfc2579_date_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(rfc2579_date_time_object._number_of_seconds, -11644387200) + self.assertEqual(rfc2579_date_time_object._time_zone_offset, None) + self.assertEqual(rfc2579_date_time_object.year, 1601) + self.assertEqual(rfc2579_date_time_object.month, 1) + self.assertEqual(rfc2579_date_time_object.day_of_month, 2) + self.assertEqual(rfc2579_date_time_object.hours, 0) + self.assertEqual(rfc2579_date_time_object.minutes, 0) + self.assertEqual(rfc2579_date_time_object.seconds, 0) + self.assertEqual(rfc2579_date_time_object.deciseconds, 0) + + rfc2579_date_time_object = RFC2579DateTimeInvalidYear() + + with self.assertRaises(ValueError): + rfc2579_date_time_object.CopyFromDateTimeString("9999-01-02 00:00:00") + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + date_time_string = rfc2579_date_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.6") + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + date_time_string = rfc2579_date_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + date_time_string = rfc2579_date_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.6+00:00") + + def testGetDate(self): + """Tests the GetDate function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + date_tuple = rfc2579_date_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + date_tuple = rfc2579_date_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) + + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + date_with_time_of_day_tuple = rfc2579_date_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + date_with_time_of_day_tuple = rfc2579_date_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) + + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 0, 0) + ) + + time_of_day_tuple = rfc2579_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime() + + time_of_day_tuple = rfc2579_date_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/semantic_time.py b/tests/semantic_time.py index ed5e5b4..5d098e1 100644 --- a/tests/semantic_time.py +++ b/tests/semantic_time.py @@ -9,203 +9,205 @@ class SemanticTimeTest(unittest.TestCase): - """Tests for semantic time.""" + """Tests for semantic time.""" - # pylint: disable=assignment-from-none,protected-access + # pylint: disable=assignment-from-none,protected-access - def testComparison(self): - """Tests the comparison functions.""" - semantic_time_object1 = semantic_time.SemanticTime() - setattr(semantic_time_object1, '_SORT_ORDER', 1) + def testComparison(self): + """Tests the comparison functions.""" + semantic_time_object1 = semantic_time.SemanticTime() + setattr(semantic_time_object1, "_SORT_ORDER", 1) - semantic_time_object2 = semantic_time.SemanticTime() - setattr(semantic_time_object2, '_SORT_ORDER', 1) + semantic_time_object2 = semantic_time.SemanticTime() + setattr(semantic_time_object2, "_SORT_ORDER", 1) - self.assertTrue(semantic_time_object1 == semantic_time_object2) - self.assertTrue(semantic_time_object1 >= semantic_time_object2) - self.assertFalse(semantic_time_object1 > semantic_time_object2) - self.assertTrue(semantic_time_object1 <= semantic_time_object2) - self.assertFalse(semantic_time_object1 < semantic_time_object2) - self.assertFalse(semantic_time_object1 != semantic_time_object2) + self.assertTrue(semantic_time_object1 == semantic_time_object2) + self.assertTrue(semantic_time_object1 >= semantic_time_object2) + self.assertFalse(semantic_time_object1 > semantic_time_object2) + self.assertTrue(semantic_time_object1 <= semantic_time_object2) + self.assertFalse(semantic_time_object1 < semantic_time_object2) + self.assertFalse(semantic_time_object1 != semantic_time_object2) - semantic_time_object2 = semantic_time.SemanticTime() - setattr(semantic_time_object2, '_SORT_ORDER', 2) + semantic_time_object2 = semantic_time.SemanticTime() + setattr(semantic_time_object2, "_SORT_ORDER", 2) - self.assertFalse(semantic_time_object1 == semantic_time_object2) - self.assertFalse(semantic_time_object1 >= semantic_time_object2) - self.assertFalse(semantic_time_object1 > semantic_time_object2) - self.assertTrue(semantic_time_object1 <= semantic_time_object2) - self.assertTrue(semantic_time_object1 < semantic_time_object2) - self.assertTrue(semantic_time_object1 != semantic_time_object2) + self.assertFalse(semantic_time_object1 == semantic_time_object2) + self.assertFalse(semantic_time_object1 >= semantic_time_object2) + self.assertFalse(semantic_time_object1 > semantic_time_object2) + self.assertTrue(semantic_time_object1 <= semantic_time_object2) + self.assertTrue(semantic_time_object1 < semantic_time_object2) + self.assertTrue(semantic_time_object1 != semantic_time_object2) - date_time_values1 = interface.TestDateTimeValues() + date_time_values1 = interface.TestDateTimeValues() - self.assertFalse(semantic_time_object1 == date_time_values1) - self.assertFalse(semantic_time_object1 >= date_time_values1) - self.assertFalse(semantic_time_object1 > date_time_values1) - self.assertTrue(semantic_time_object1 <= date_time_values1) - self.assertTrue(semantic_time_object1 < date_time_values1) - self.assertTrue(semantic_time_object1 != date_time_values1) + self.assertFalse(semantic_time_object1 == date_time_values1) + self.assertFalse(semantic_time_object1 >= date_time_values1) + self.assertFalse(semantic_time_object1 > date_time_values1) + self.assertTrue(semantic_time_object1 <= date_time_values1) + self.assertTrue(semantic_time_object1 < date_time_values1) + self.assertTrue(semantic_time_object1 != date_time_values1) - self.assertFalse(semantic_time_object1 == 0.0) + self.assertFalse(semantic_time_object1 == 0.0) - with self.assertRaises(ValueError): - semantic_time_object1 >= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + semantic_time_object1 >= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - semantic_time_object1 > 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + semantic_time_object1 > 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - semantic_time_object1 <= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + semantic_time_object1 <= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - semantic_time_object1 < 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + semantic_time_object1 < 0.0 # pylint: disable=pointless-statement - self.assertTrue(semantic_time_object1 != 0.0) + self.assertTrue(semantic_time_object1 != 0.0) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - semantic_time_object = semantic_time.SemanticTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + semantic_time_object = semantic_time.SemanticTime() - semantic_time_object.CopyFromDateTimeString('Never') - self.assertEqual(semantic_time_object.string, 'Never') + semantic_time_object.CopyFromDateTimeString("Never") + self.assertEqual(semantic_time_object.string, "Never") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - semantic_time_object = semantic_time.SemanticTime(string='Never') + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + semantic_time_object = semantic_time.SemanticTime(string="Never") - date_time_string = semantic_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, 'Never') + date_time_string = semantic_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "Never") - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - semantic_time_object = semantic_time.SemanticTime(string='Never') + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + semantic_time_object = semantic_time.SemanticTime(string="Never") - date_time_string = semantic_time_object.CopyToDateTimeStringISO8601() - self.assertIsNone(date_time_string) + date_time_string = semantic_time_object.CopyToDateTimeStringISO8601() + self.assertIsNone(date_time_string) - def testCopyToPosixTimestamp(self): - """Tests the CopyToPosixTimestamp function.""" - semantic_time_object = semantic_time.SemanticTime() + def testCopyToPosixTimestamp(self): + """Tests the CopyToPosixTimestamp function.""" + semantic_time_object = semantic_time.SemanticTime() - posix_timestamp = semantic_time_object.CopyToPosixTimestamp() - self.assertIsNone(posix_timestamp) + posix_timestamp = semantic_time_object.CopyToPosixTimestamp() + self.assertIsNone(posix_timestamp) - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - semantic_time_object = semantic_time.SemanticTime() + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + semantic_time_object = semantic_time.SemanticTime() - posix_timestamp, fraction_of_second = ( - semantic_time_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + semantic_time_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - semantic_time_object = semantic_time.SemanticTime() + def testGetDate(self): + """Tests the GetDate function.""" + semantic_time_object = semantic_time.SemanticTime() - date_tuple = semantic_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = semantic_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - semantic_time_object = semantic_time.SemanticTime() + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + semantic_time_object = semantic_time.SemanticTime() - date_with_time_of_day_tuple = semantic_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = semantic_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - semantic_time_object = semantic_time.SemanticTime() + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + semantic_time_object = semantic_time.SemanticTime() - time_of_day_tuple = semantic_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = semantic_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) - def testGetPlasoTimestamp(self): - """Tests the GetPlasoTimestamp function.""" - semantic_time_object = semantic_time.SemanticTime() + def testGetPlasoTimestamp(self): + """Tests the GetPlasoTimestamp function.""" + semantic_time_object = semantic_time.SemanticTime() - micro_posix_timestamp = semantic_time_object.GetPlasoTimestamp() - self.assertEqual(micro_posix_timestamp, 0) + micro_posix_timestamp = semantic_time_object.GetPlasoTimestamp() + self.assertEqual(micro_posix_timestamp, 0) class InvalidTimeTest(unittest.TestCase): - """Tests for semantic time that represents invalid..""" + """Tests for semantic time that represents invalid..""" - def testInitialize(self): - """Tests the __init__ function.""" - invalid_time_object = semantic_time.InvalidTime() - self.assertEqual(invalid_time_object.string, 'Invalid') + def testInitialize(self): + """Tests the __init__ function.""" + invalid_time_object = semantic_time.InvalidTime() + self.assertEqual(invalid_time_object.string, "Invalid") class NeverTest(unittest.TestCase): - """Tests for semantic time that represents never.""" + """Tests for semantic time that represents never.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testInitialize(self): - """Tests the __init__ function.""" - never_time_object = semantic_time.Never() - self.assertEqual(never_time_object.string, 'Never') + def testInitialize(self): + """Tests the __init__ function.""" + never_time_object = semantic_time.Never() + self.assertEqual(never_time_object.string, "Never") - def testComparison(self): - """Tests the comparison functions.""" - never_time_object1 = semantic_time.Never() + def testComparison(self): + """Tests the comparison functions.""" + never_time_object1 = semantic_time.Never() - never_time_object2 = semantic_time.Never() + never_time_object2 = semantic_time.Never() - self.assertTrue(never_time_object1 == never_time_object2) - self.assertTrue(never_time_object1 >= never_time_object2) - self.assertFalse(never_time_object1 > never_time_object2) - self.assertTrue(never_time_object1 <= never_time_object2) - self.assertFalse(never_time_object1 < never_time_object2) - self.assertFalse(never_time_object1 != never_time_object2) + self.assertTrue(never_time_object1 == never_time_object2) + self.assertTrue(never_time_object1 >= never_time_object2) + self.assertFalse(never_time_object1 > never_time_object2) + self.assertTrue(never_time_object1 <= never_time_object2) + self.assertFalse(never_time_object1 < never_time_object2) + self.assertFalse(never_time_object1 != never_time_object2) - semantic_time_object2 = semantic_time.SemanticTime() - setattr(semantic_time_object2, '_SORT_ORDER', 1) + semantic_time_object2 = semantic_time.SemanticTime() + setattr(semantic_time_object2, "_SORT_ORDER", 1) - self.assertFalse(never_time_object1 == semantic_time_object2) - self.assertTrue(never_time_object1 >= semantic_time_object2) - self.assertTrue(never_time_object1 > semantic_time_object2) - self.assertFalse(never_time_object1 <= semantic_time_object2) - self.assertFalse(never_time_object1 < semantic_time_object2) - self.assertTrue(never_time_object1 != semantic_time_object2) + self.assertFalse(never_time_object1 == semantic_time_object2) + self.assertTrue(never_time_object1 >= semantic_time_object2) + self.assertTrue(never_time_object1 > semantic_time_object2) + self.assertFalse(never_time_object1 <= semantic_time_object2) + self.assertFalse(never_time_object1 < semantic_time_object2) + self.assertTrue(never_time_object1 != semantic_time_object2) - date_time_values1 = interface.TestDateTimeValues() + date_time_values1 = interface.TestDateTimeValues() - self.assertFalse(never_time_object1 == date_time_values1) - self.assertTrue(never_time_object1 >= date_time_values1) - self.assertTrue(never_time_object1 > date_time_values1) - self.assertFalse(never_time_object1 <= date_time_values1) - self.assertFalse(never_time_object1 < date_time_values1) - self.assertTrue(never_time_object1 != date_time_values1) + self.assertFalse(never_time_object1 == date_time_values1) + self.assertTrue(never_time_object1 >= date_time_values1) + self.assertTrue(never_time_object1 > date_time_values1) + self.assertFalse(never_time_object1 <= date_time_values1) + self.assertFalse(never_time_object1 < date_time_values1) + self.assertTrue(never_time_object1 != date_time_values1) - self.assertFalse(never_time_object1 == 0.0) + self.assertFalse(never_time_object1 == 0.0) - with self.assertRaises(ValueError): - never_time_object1 >= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + never_time_object1 >= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - never_time_object1 > 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + never_time_object1 > 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - never_time_object1 <= 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + never_time_object1 <= 0.0 # pylint: disable=pointless-statement - with self.assertRaises(ValueError): - never_time_object1 < 0.0 # pylint: disable=pointless-statement + with self.assertRaises(ValueError): + never_time_object1 < 0.0 # pylint: disable=pointless-statement - self.assertTrue(never_time_object1 != 0.0) + self.assertTrue(never_time_object1 != 0.0) class NotSetTest(unittest.TestCase): - """Tests for semantic time that represents not set.""" + """Tests for semantic time that represents not set.""" - def testInitialize(self): - """Tests the __init__ function.""" - not_set_time_object = semantic_time.NotSet() - self.assertEqual(not_set_time_object.string, 'Not set') + def testInitialize(self): + """Tests the __init__ function.""" + not_set_time_object = semantic_time.NotSet() + self.assertEqual(not_set_time_object.string, "Not set") -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/serializer.py b/tests/serializer.py index 34cf623..5025cd4 100644 --- a/tests/serializer.py +++ b/tests/serializer.py @@ -15,358 +15,388 @@ class SerializerTest(unittest.TestCase): - """Tests for the date and time values serializer.""" - - def testConvertDictToDateTimeValues(self): - """Test ConvertDictToDateTimeValues function.""" - json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591} - - date_time_object = serializer.Serializer.ConvertDictToDateTimeValues( - json_dict) - self.assertIsNotNone(date_time_object) - - def testConvertDateTimeValuesToDict(self): - """Test ConvertDateTimeValuesToDict function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) - json_dict = serializer.Serializer.ConvertDateTimeValuesToDict( - posix_time_object) - self.assertIsNotNone(json_dict) - - with self.assertRaises(TypeError): - serializer.Serializer.ConvertDateTimeValuesToDict('not a datetime') - - def testConvertDateTimeValuesToJSON(self): - """Test ConvertDateTimeValuesToJSON function.""" - posix_time_object = posix_time.PosixTime(timestamp=1281643591) - - expected_json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - posix_time_object) - self.assertEqual(json_dict, expected_json_dict) - - posix_time_object.is_local_time = True - posix_time_object.time_zone_hint = 'Europe/Amsterdam' - - expected_json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'is_local_time': True, - 'time_zone_hint': 'Europe/Amsterdam', - 'timestamp': 1281643591} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - posix_time_object) - self.assertEqual(json_dict, expected_json_dict) - - posix_time_object = posix_time.PosixTime( - timestamp=1281643591, time_zone_offset=60) - - expected_json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591, - 'time_zone_offset': 60} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - posix_time_object) - self.assertEqual(json_dict, expected_json_dict) - - never_time_object = semantic_time.Never() - - expected_json_dict = { - '__class_name__': 'Never', - '__type__': 'DateTimeValues', - 'string': 'Never'} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - never_time_object) - self.assertEqual(json_dict, expected_json_dict) - - dotnet_datetime_object = dotnet_datetime.DotNetDateTime( - timestamp=637433719321230000) - - expected_json_dict = { - '__class_name__': 'DotNetDateTime', - '__type__': 'DateTimeValues', - 'timestamp': 637433719321230000} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - dotnet_datetime_object) - self.assertEqual(json_dict, expected_json_dict) - - fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c) - - expected_json_dict = { - '__class_name__': 'FATDateTime', - '__type__': 'DateTimeValues', - 'fat_date_time': 2832219404} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - fat_date_time_object) - self.assertEqual(json_dict, expected_json_dict) - - golang_timestamp = bytes.fromhex('01000000000000000200000003ffff') - golang_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - expected_json_dict = { - '__class_name__': 'GolangTime', - '__type__': 'DateTimeValues', - 'golang_timestamp': ( - b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff')} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - golang_time_object) - self.assertEqual(json_dict, expected_json_dict) - - rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)) - - expected_json_dict = { - '__class_name__': 'RFC2579DateTime', - '__type__': 'DateTimeValues', - 'rfc2579_date_time_tuple': (2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - rfc2579_date_time_object) - self.assertEqual(json_dict, expected_json_dict) - - negative_timezone_rfc2579_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '-', 2, 0)) - - expected_json_dict = { - '__class_name__': 'RFC2579DateTime', - '__type__': 'DateTimeValues', - 'rfc2579_date_time_tuple': (2010, 8, 12, 20, 6, 31, 6, '-', 2, 0)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - negative_timezone_rfc2579_object) - self.assertEqual(json_dict, expected_json_dict) - - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - expected_json_dict = { - '__class_name__': 'Systemtime', - '__type__': 'DateTimeValues', - 'system_time_tuple': (2010, 8, 4, 12, 20, 6, 31, 142)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - systemtime_object) - self.assertEqual(json_dict, expected_json_dict) - - time_elements_object = time_elements.TimeElements( - is_delta=True, time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - expected_json_dict = { - '__class_name__': 'TimeElements', - '__type__': 'DateTimeValues', - 'is_delta': True, - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - time_elements_object) - self.assertEqual(json_dict, expected_json_dict) - - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546)) - - expected_json_dict = { - '__class_name__': 'TimeElementsInMilliseconds', - '__type__': 'DateTimeValues', - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 546)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - time_elements_object) - self.assertEqual(json_dict, expected_json_dict) - - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - expected_json_dict = { - '__class_name__': 'TimeElementsInMicroseconds', - '__type__': 'DateTimeValues', - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 429876)} - - json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( - time_elements_object) - self.assertEqual(json_dict, expected_json_dict) - - def testConvertJSONToDateTimeValues(self): - """Test ConvertJSONToDateTimeValues function.""" - json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591} - - expected_date_time_object = posix_time.PosixTime(timestamp=1281643591) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'is_local_time': True, - 'time_zone_hint': 'Europe/Amsterdam', - 'timestamp': 1281643591} - - expected_date_time_object.is_local_time = True - expected_date_time_object.time_zone_hint = 'Europe/Amsterdam' - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591, - 'time_zone_offset': 60} - - expected_date_time_object = posix_time.PosixTime( - timestamp=1281643591, time_zone_offset=60) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'Never', - '__type__': 'DateTimeValues', - 'string': 'Never'} - - expected_date_time_object = semantic_time.Never() - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'DotNetDateTime', - '__type__': 'DateTimeValues', - 'timestamp': 637433719321230000} - - expected_date_time_object = dotnet_datetime.DotNetDateTime( - timestamp=637433719321230000) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'FATDateTime', - '__type__': 'DateTimeValues', - 'fat_date_time': 2832219404} - - expected_date_time_object = fat_date_time.FATDateTime( - fat_date_time=0xa8d03d0c) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'GolangTime', - '__type__': 'DateTimeValues', - 'golang_timestamp': ( - b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff'), - 'time_zone_offset': 60} - - golang_timestamp = bytes.fromhex('01000000000000000200000003ffff') - expected_date_time_object = golang_time.GolangTime( - golang_timestamp=golang_timestamp) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'RFC2579DateTime', - '__type__': 'DateTimeValues', - 'rfc2579_date_time_tuple': (2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)} - - expected_date_time_object = rfc2579_date_time.RFC2579DateTime( - rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'Systemtime', - '__type__': 'DateTimeValues', - 'system_time_tuple': (2010, 8, 4, 12, 20, 6, 31, 142)} - - expected_date_time_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'TimeElements', - '__type__': 'DateTimeValues', - 'is_delta': True, - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31)} - - expected_date_time_object = time_elements.TimeElements( - is_delta=True, time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - self.assertTrue(date_time_object.is_delta) - - json_dict = { - '__class_name__': 'TimeElementsInMilliseconds', - '__type__': 'DateTimeValues', - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 546)} - - expected_date_time_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546)) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - json_dict = { - '__class_name__': 'TimeElementsInMicroseconds', - '__type__': 'DateTimeValues', - 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 429876)} - - expected_date_time_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertEqual(date_time_object, expected_date_time_object) - - # Test if is_delta is removed. - json_dict = { - '__class_name__': 'PosixTime', - '__type__': 'DateTimeValues', - 'timestamp': 1281643591, - 'is_delta': True} - - date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues( - json_dict) - self.assertFalse(date_time_object.is_delta) - - with self.assertRaises(KeyError): - json_dict = { - '__class_name__': 'UnknownType', '__type__': 'DateTimeValues'} - serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) - - -if __name__ == '__main__': - unittest.main() + """Tests for the date and time values serializer.""" + + def testConvertDictToDateTimeValues(self): + """Test ConvertDictToDateTimeValues function.""" + json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + } + + date_time_object = serializer.Serializer.ConvertDictToDateTimeValues(json_dict) + self.assertIsNotNone(date_time_object) + + def testConvertDateTimeValuesToDict(self): + """Test ConvertDateTimeValuesToDict function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) + json_dict = serializer.Serializer.ConvertDateTimeValuesToDict(posix_time_object) + self.assertIsNotNone(json_dict) + + with self.assertRaises(TypeError): + serializer.Serializer.ConvertDateTimeValuesToDict("not a datetime") + + def testConvertDateTimeValuesToJSON(self): + """Test ConvertDateTimeValuesToJSON function.""" + posix_time_object = posix_time.PosixTime(timestamp=1281643591) + + expected_json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(posix_time_object) + self.assertEqual(json_dict, expected_json_dict) + + posix_time_object.is_local_time = True + posix_time_object.time_zone_hint = "Europe/Amsterdam" + + expected_json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "is_local_time": True, + "time_zone_hint": "Europe/Amsterdam", + "timestamp": 1281643591, + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(posix_time_object) + self.assertEqual(json_dict, expected_json_dict) + + posix_time_object = posix_time.PosixTime( + timestamp=1281643591, time_zone_offset=60 + ) + + expected_json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + "time_zone_offset": 60, + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(posix_time_object) + self.assertEqual(json_dict, expected_json_dict) + + never_time_object = semantic_time.Never() + + expected_json_dict = { + "__class_name__": "Never", + "__type__": "DateTimeValues", + "string": "Never", + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(never_time_object) + self.assertEqual(json_dict, expected_json_dict) + + dotnet_datetime_object = dotnet_datetime.DotNetDateTime( + timestamp=637433719321230000 + ) + + expected_json_dict = { + "__class_name__": "DotNetDateTime", + "__type__": "DateTimeValues", + "timestamp": 637433719321230000, + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + dotnet_datetime_object + ) + self.assertEqual(json_dict, expected_json_dict) + + fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) + + expected_json_dict = { + "__class_name__": "FATDateTime", + "__type__": "DateTimeValues", + "fat_date_time": 2832219404, + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + fat_date_time_object + ) + self.assertEqual(json_dict, expected_json_dict) + + golang_timestamp = bytes.fromhex("01000000000000000200000003ffff") + golang_time_object = golang_time.GolangTime(golang_timestamp=golang_timestamp) + + expected_json_dict = { + "__class_name__": "GolangTime", + "__type__": "DateTimeValues", + "golang_timestamp": ( + b"\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff" + ), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + golang_time_object + ) + self.assertEqual(json_dict, expected_json_dict) + + rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 2, 0) + ) + + expected_json_dict = { + "__class_name__": "RFC2579DateTime", + "__type__": "DateTimeValues", + "rfc2579_date_time_tuple": (2010, 8, 12, 20, 6, 31, 6, "+", 2, 0), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + rfc2579_date_time_object + ) + self.assertEqual(json_dict, expected_json_dict) + + negative_timezone_rfc2579_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "-", 2, 0) + ) + + expected_json_dict = { + "__class_name__": "RFC2579DateTime", + "__type__": "DateTimeValues", + "rfc2579_date_time_tuple": (2010, 8, 12, 20, 6, 31, 6, "-", 2, 0), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + negative_timezone_rfc2579_object + ) + self.assertEqual(json_dict, expected_json_dict) + + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + expected_json_dict = { + "__class_name__": "Systemtime", + "__type__": "DateTimeValues", + "system_time_tuple": (2010, 8, 4, 12, 20, 6, 31, 142), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(systemtime_object) + self.assertEqual(json_dict, expected_json_dict) + + time_elements_object = time_elements.TimeElements( + is_delta=True, time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) + + expected_json_dict = { + "__class_name__": "TimeElements", + "__type__": "DateTimeValues", + "is_delta": True, + "time_elements_tuple": (2010, 8, 12, 20, 6, 31), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + time_elements_object + ) + self.assertEqual(json_dict, expected_json_dict) + + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546) + ) + + expected_json_dict = { + "__class_name__": "TimeElementsInMilliseconds", + "__type__": "DateTimeValues", + "time_elements_tuple": (2010, 8, 12, 20, 6, 31, 546), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + time_elements_object + ) + self.assertEqual(json_dict, expected_json_dict) + + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + expected_json_dict = { + "__class_name__": "TimeElementsInMicroseconds", + "__type__": "DateTimeValues", + "time_elements_tuple": (2010, 8, 12, 20, 6, 31, 429876), + } + + json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( + time_elements_object + ) + self.assertEqual(json_dict, expected_json_dict) + + def testConvertJSONToDateTimeValues(self): + """Test ConvertJSONToDateTimeValues function.""" + json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + } + + expected_date_time_object = posix_time.PosixTime(timestamp=1281643591) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "is_local_time": True, + "time_zone_hint": "Europe/Amsterdam", + "timestamp": 1281643591, + } + + expected_date_time_object.is_local_time = True + expected_date_time_object.time_zone_hint = "Europe/Amsterdam" + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + "time_zone_offset": 60, + } + + expected_date_time_object = posix_time.PosixTime( + timestamp=1281643591, time_zone_offset=60 + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "Never", + "__type__": "DateTimeValues", + "string": "Never", + } + + expected_date_time_object = semantic_time.Never() + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "DotNetDateTime", + "__type__": "DateTimeValues", + "timestamp": 637433719321230000, + } + + expected_date_time_object = dotnet_datetime.DotNetDateTime( + timestamp=637433719321230000 + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "FATDateTime", + "__type__": "DateTimeValues", + "fat_date_time": 2832219404, + } + + expected_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xA8D03D0C) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "GolangTime", + "__type__": "DateTimeValues", + "golang_timestamp": ( + b"\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff" + ), + "time_zone_offset": 60, + } + + golang_timestamp = bytes.fromhex("01000000000000000200000003ffff") + expected_date_time_object = golang_time.GolangTime( + golang_timestamp=golang_timestamp + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "RFC2579DateTime", + "__type__": "DateTimeValues", + "rfc2579_date_time_tuple": (2010, 8, 12, 20, 6, 31, 6, "+", 2, 0), + } + + expected_date_time_object = rfc2579_date_time.RFC2579DateTime( + rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, "+", 2, 0) + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "Systemtime", + "__type__": "DateTimeValues", + "system_time_tuple": (2010, 8, 4, 12, 20, 6, 31, 142), + } + + expected_date_time_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "TimeElements", + "__type__": "DateTimeValues", + "is_delta": True, + "time_elements_tuple": (2010, 8, 12, 20, 6, 31), + } + + expected_date_time_object = time_elements.TimeElements( + is_delta=True, time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + self.assertTrue(date_time_object.is_delta) + + json_dict = { + "__class_name__": "TimeElementsInMilliseconds", + "__type__": "DateTimeValues", + "time_elements_tuple": (2010, 8, 12, 20, 6, 31, 546), + } + + expected_date_time_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546) + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + json_dict = { + "__class_name__": "TimeElementsInMicroseconds", + "__type__": "DateTimeValues", + "time_elements_tuple": (2010, 8, 12, 20, 6, 31, 429876), + } + + expected_date_time_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertEqual(date_time_object, expected_date_time_object) + + # Test if is_delta is removed. + json_dict = { + "__class_name__": "PosixTime", + "__type__": "DateTimeValues", + "timestamp": 1281643591, + "is_delta": True, + } + + date_time_object = serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + self.assertFalse(date_time_object.is_delta) + + with self.assertRaises(KeyError): + json_dict = {"__class_name__": "UnknownType", "__type__": "DateTimeValues"} + serializer.Serializer.ConvertJSONToDateTimeValues(json_dict) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/systemtime.py b/tests/systemtime.py index 3d0acf1..ff059a6 100644 --- a/tests/systemtime.py +++ b/tests/systemtime.py @@ -8,225 +8,225 @@ class SystemtimeTest(unittest.TestCase): - """Tests for the SYSTEMTIME structure.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - systemtime_object = systemtime.Systemtime() - self.assertIsNotNone(systemtime_object) - - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - self.assertIsNotNone(systemtime_object) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 20) - self.assertEqual(systemtime_object.minutes, 6) - self.assertEqual(systemtime_object.seconds, 31) - self.assertEqual(systemtime_object.milliseconds, 142) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(1500, 8, 4, 12, 20, 6, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 13, 4, 12, 20, 6, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 7, 12, 20, 6, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 32, 20, 6, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 24, 6, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 61, 31, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 61, 142)) - - with self.assertRaises(ValueError): - systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 1001)) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - normalized_timestamp = systemtime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.142')) - - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142), - time_zone_offset=60) - - normalized_timestamp = systemtime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.142')) - - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - systemtime_object.time_zone_offset = 60 - - normalized_timestamp = systemtime_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.142')) - - systemtime_object = systemtime.Systemtime() - - normalized_timestamp = systemtime_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - systemtime_object = systemtime.Systemtime() - - systemtime_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(systemtime_object._number_of_seconds, 1281571200) - self.assertEqual(systemtime_object._time_zone_offset, None) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 0) - self.assertEqual(systemtime_object.minutes, 0) - self.assertEqual(systemtime_object.seconds, 0) - self.assertEqual(systemtime_object.milliseconds, 0) - - systemtime_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(systemtime_object._number_of_seconds, 1281647191) - self.assertEqual(systemtime_object._time_zone_offset, None) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 21) - self.assertEqual(systemtime_object.minutes, 6) - self.assertEqual(systemtime_object.seconds, 31) - self.assertEqual(systemtime_object.milliseconds, 0) - - systemtime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(systemtime_object._number_of_seconds, 1281647191) - self.assertEqual(systemtime_object._time_zone_offset, None) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 21) - self.assertEqual(systemtime_object.minutes, 6) - self.assertEqual(systemtime_object.seconds, 31) - self.assertEqual(systemtime_object.milliseconds, 546) - - systemtime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875-01:00') - self.assertEqual(systemtime_object._number_of_seconds, 1281647191) - self.assertEqual(systemtime_object._time_zone_offset, -60) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 21) - self.assertEqual(systemtime_object.minutes, 6) - self.assertEqual(systemtime_object.seconds, 31) - self.assertEqual(systemtime_object.milliseconds, 546) - self.assertEqual(systemtime_object.time_zone_offset, -60) - - systemtime_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875+01:00') - self.assertEqual(systemtime_object._number_of_seconds, 1281647191) - self.assertEqual(systemtime_object._time_zone_offset, 60) - self.assertEqual(systemtime_object.year, 2010) - self.assertEqual(systemtime_object.month, 8) - self.assertEqual(systemtime_object.day_of_month, 12) - self.assertEqual(systemtime_object.hours, 21) - self.assertEqual(systemtime_object.minutes, 6) - self.assertEqual(systemtime_object.seconds, 31) - self.assertEqual(systemtime_object.milliseconds, 546) - self.assertEqual(systemtime_object.time_zone_offset, 60) - - systemtime_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(systemtime_object._number_of_seconds, -11644387200) - self.assertEqual(systemtime_object._time_zone_offset, None) - self.assertEqual(systemtime_object.year, 1601) - self.assertEqual(systemtime_object.month, 1) - self.assertEqual(systemtime_object.day_of_month, 2) - self.assertEqual(systemtime_object.hours, 0) - self.assertEqual(systemtime_object.minutes, 0) - self.assertEqual(systemtime_object.seconds, 0) - self.assertEqual(systemtime_object.milliseconds, 0) - - with self.assertRaises(ValueError): - systemtime_object.CopyFromDateTimeString('1600-01-02 00:00:00') - - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - date_time_string = systemtime_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.142') - - systemtime_object = systemtime.Systemtime() - - date_time_string = systemtime_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - date_time_string = systemtime_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.142+00:00') - - def testGetDate(self): - """Tests the GetDate function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - date_tuple = systemtime_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) - - systemtime_object = systemtime.Systemtime() - - date_tuple = systemtime_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) - - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - date_with_time_of_day_tuple = systemtime_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - - systemtime_object = systemtime.Systemtime() - - date_with_time_of_day_tuple = systemtime_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) - - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - systemtime_object = systemtime.Systemtime( - system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142)) - - time_of_day_tuple = systemtime_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) - - systemtime_object = systemtime.Systemtime() - - time_of_day_tuple = systemtime_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) - - -if __name__ == '__main__': - unittest.main() + """Tests for the SYSTEMTIME structure.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + systemtime_object = systemtime.Systemtime() + self.assertIsNotNone(systemtime_object) + + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + self.assertIsNotNone(systemtime_object) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 20) + self.assertEqual(systemtime_object.minutes, 6) + self.assertEqual(systemtime_object.seconds, 31) + self.assertEqual(systemtime_object.milliseconds, 142) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 12, 20, 6, 31)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(1500, 8, 4, 12, 20, 6, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 13, 4, 12, 20, 6, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 7, 12, 20, 6, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 32, 20, 6, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 12, 24, 6, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 12, 20, 61, 31, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 12, 20, 6, 61, 142)) + + with self.assertRaises(ValueError): + systemtime.Systemtime(system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 1001)) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + normalized_timestamp = systemtime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.142")) + + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142), time_zone_offset=60 + ) + + normalized_timestamp = systemtime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.142")) + + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + systemtime_object.time_zone_offset = 60 + + normalized_timestamp = systemtime_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.142")) + + systemtime_object = systemtime.Systemtime() + + normalized_timestamp = systemtime_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + systemtime_object = systemtime.Systemtime() + + systemtime_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(systemtime_object._number_of_seconds, 1281571200) + self.assertEqual(systemtime_object._time_zone_offset, None) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 0) + self.assertEqual(systemtime_object.minutes, 0) + self.assertEqual(systemtime_object.seconds, 0) + self.assertEqual(systemtime_object.milliseconds, 0) + + systemtime_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(systemtime_object._number_of_seconds, 1281647191) + self.assertEqual(systemtime_object._time_zone_offset, None) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 21) + self.assertEqual(systemtime_object.minutes, 6) + self.assertEqual(systemtime_object.seconds, 31) + self.assertEqual(systemtime_object.milliseconds, 0) + + systemtime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(systemtime_object._number_of_seconds, 1281647191) + self.assertEqual(systemtime_object._time_zone_offset, None) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 21) + self.assertEqual(systemtime_object.minutes, 6) + self.assertEqual(systemtime_object.seconds, 31) + self.assertEqual(systemtime_object.milliseconds, 546) + + systemtime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(systemtime_object._number_of_seconds, 1281647191) + self.assertEqual(systemtime_object._time_zone_offset, -60) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 21) + self.assertEqual(systemtime_object.minutes, 6) + self.assertEqual(systemtime_object.seconds, 31) + self.assertEqual(systemtime_object.milliseconds, 546) + self.assertEqual(systemtime_object.time_zone_offset, -60) + + systemtime_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(systemtime_object._number_of_seconds, 1281647191) + self.assertEqual(systemtime_object._time_zone_offset, 60) + self.assertEqual(systemtime_object.year, 2010) + self.assertEqual(systemtime_object.month, 8) + self.assertEqual(systemtime_object.day_of_month, 12) + self.assertEqual(systemtime_object.hours, 21) + self.assertEqual(systemtime_object.minutes, 6) + self.assertEqual(systemtime_object.seconds, 31) + self.assertEqual(systemtime_object.milliseconds, 546) + self.assertEqual(systemtime_object.time_zone_offset, 60) + + systemtime_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(systemtime_object._number_of_seconds, -11644387200) + self.assertEqual(systemtime_object._time_zone_offset, None) + self.assertEqual(systemtime_object.year, 1601) + self.assertEqual(systemtime_object.month, 1) + self.assertEqual(systemtime_object.day_of_month, 2) + self.assertEqual(systemtime_object.hours, 0) + self.assertEqual(systemtime_object.minutes, 0) + self.assertEqual(systemtime_object.seconds, 0) + self.assertEqual(systemtime_object.milliseconds, 0) + + with self.assertRaises(ValueError): + systemtime_object.CopyFromDateTimeString("1600-01-02 00:00:00") + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + date_time_string = systemtime_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.142") + + systemtime_object = systemtime.Systemtime() + + date_time_string = systemtime_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + date_time_string = systemtime_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.142+00:00") + + def testGetDate(self): + """Tests the GetDate function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + date_tuple = systemtime_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) + + systemtime_object = systemtime.Systemtime() + + date_tuple = systemtime_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) + + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + date_with_time_of_day_tuple = systemtime_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + + systemtime_object = systemtime.Systemtime() + + date_with_time_of_day_tuple = systemtime_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) + + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + systemtime_object = systemtime.Systemtime( + system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142) + ) + + time_of_day_tuple = systemtime_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) + + systemtime_object = systemtime.Systemtime() + + time_of_day_tuple = systemtime_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/time_elements.py b/tests/time_elements.py index 67e95fd..f9b5f2d 100644 --- a/tests/time_elements.py +++ b/tests/time_elements.py @@ -10,2343 +10,2644 @@ class TimeElementsTest(unittest.TestCase): - """Tests for the time elements.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNotNone(time_elements_object) - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object = time_elements.TimeElements( - 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.year, 2010) - self.assertEqual(time_elements_object.month, 8) - self.assertEqual(time_elements_object.day_of_month, 12) - self.assertEqual(time_elements_object.hours, 20) - self.assertEqual(time_elements_object.minutes, 6) - self.assertEqual(time_elements_object.seconds, 31) - - expected_time_elements_tuple = (2010, 2, 29, 20, 6, 31) - time_elements_object = time_elements.TimeElements( - is_delta=True, time_elements_tuple=(2010, 2, 29, 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.year, 2010) - self.assertEqual(time_elements_object.month, 2) - self.assertEqual(time_elements_object.day_of_month, 29) - self.assertEqual(time_elements_object.hours, 20) - self.assertEqual(time_elements_object.minutes, 6) - self.assertEqual(time_elements_object.seconds, 31) - self.assertTrue(time_elements_object.is_delta) - - with self.assertRaises(ValueError): - time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6)) - - with self.assertRaises(ValueError): - time_elements.TimeElements( - time_elements_tuple=(2010, 2, 29, 20, 6)) - - with self.assertRaises(ValueError): - time_elements.TimeElements( - time_elements_tuple=(2010, 13, 12, 20, 6, 31)) - - def testDayOfMonth(self): - """Tests the day_of_month property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.day_of_month) - - def testHours(self): - """Tests the hours property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.hours) - - def testMinutes(self): - """Tests the minutes property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.minutes) - - def testMonth(self): - """Tests the month property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.month) - - def testSeconds(self): - """Tests the seconds property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.seconds) - - def testYear(self): - """Tests the year property.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNone(time_elements_object.year) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591')) - - time_elements_object = time_elements.TimeElements( - 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')) - - time_elements_object = time_elements.TimeElements( - 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')) - - time_elements_object = time_elements.TimeElements() - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - def testCopyDateTimeFromStringISO8601(self): - """Tests the _CopyDateTimeFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElements() - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12T21:06:31') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12T21:06:31.546875') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000, - 'time_zone_offset': -60} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12T21:06:31.546875-01:00') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875000, - 'time_zone_offset': 60} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12T21:06:31.546875+01:00') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 2010, 'month': 8, 'day_of_month': 12, - 'hours': 21, 'minutes': 6, 'seconds': 31, 'nanoseconds': 546875333, - 'time_zone_offset': 60} - date_dict = time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12T21:06:31.546875333+01:00') - self.assertEqual(date_dict, expected_date_dict) - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringISO8601('') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringISO8601('2010-08-12T1') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringISO8601( - '2010-08-12 21:06:31.546875+01:00') - - def testCopyDateTimeFromStringRFC822(self): - """Tests the _CopyDateTimeFromStringRFC822 function.""" - time_elements_object = time_elements.TimeElements() - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 Jun 82 11:57:09 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC822( - '20 Jun 82 11:57:09 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC822( - '20 Jun 82 11:57 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': -300} - date_dict = time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 Jun 82 11:57:09 EST') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': -300} - date_dict = time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 Jun 82 11:57:09 -0500') - self.assertEqual(date_dict, expected_date_dict) - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822(None) - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'XXX, 20 Jun 82 11:57:09 GMT BOGUS') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'XXX, 20 Jun 82 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, XX Jun 82 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 XXX 82 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 Jun XX 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC822( - 'Sun, 20 Jun 82 XX:XX:XX XXX') - - def testCopyDateTimeFromStringRFC1123(self): - """Tests the _CopyDateTimeFromStringRFC1123 function.""" - time_elements_object = time_elements.TimeElements() - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 Jun 1982 11:57:09 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( - '20 Jun 1982 11:57:09 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, - 'time_zone_offset': 0} - date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( - '20 Jun 1982 11:57 GMT') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': -300} - date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 Jun 1982 11:57:09 EST') - self.assertEqual(date_dict, expected_date_dict) - - expected_date_dict = { - 'year': 1982, 'month': 6, 'day_of_month': 20, - 'hours': 11, 'minutes': 57, 'seconds': 9, - 'time_zone_offset': -300} - date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 Jun 1982 11:57:09 -0500') - self.assertEqual(date_dict, expected_date_dict) - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123(None) - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'XXX, 20 Jun 1982 11:57:09 GMT BOGUS') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'XXX, 20 Jun 1982 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, XX Jun 1982 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 XXX 1982 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 Jun XXXX 11:57:09 GMT') - - with self.assertRaises(ValueError): - time_elements_object._CopyDateTimeFromStringRFC1123( - 'Sun, 20 Jun 1982 XX:XX:XX XXX') - - # TODO: add tests for _CopyFromDateTimeValues - - def testCopyTimeFromStringISO8601(self): - """Tests the _CopyTimeFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_tuple = (8, None, None, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('08') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (8, 4, None, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('08:04') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (8, 4, None, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('0804') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 30, 0, 0, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('20.5') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (8, 4, 32, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('08:04:32') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (8, 4, 32, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('080432') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 23, 30, 0, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('20:23.5') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 23, 30, 0, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('2023.5') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 23, 56, None, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('20:23:56') - self.assertEqual(time_tuple, expected_time_tuple) - - expected_time_tuple = (20, 23, 56, None, 330) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56+05:30') - self.assertEqual(time_tuple, expected_time_tuple) + """Tests for the time elements.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNotNone(time_elements_object) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElements( + 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.year, 2010) + self.assertEqual(time_elements_object.month, 8) + self.assertEqual(time_elements_object.day_of_month, 12) + self.assertEqual(time_elements_object.hours, 20) + self.assertEqual(time_elements_object.minutes, 6) + self.assertEqual(time_elements_object.seconds, 31) + + expected_time_elements_tuple = (2010, 2, 29, 20, 6, 31) + time_elements_object = time_elements.TimeElements( + is_delta=True, time_elements_tuple=(2010, 2, 29, 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.year, 2010) + self.assertEqual(time_elements_object.month, 2) + self.assertEqual(time_elements_object.day_of_month, 29) + self.assertEqual(time_elements_object.hours, 20) + self.assertEqual(time_elements_object.minutes, 6) + self.assertEqual(time_elements_object.seconds, 31) + self.assertTrue(time_elements_object.is_delta) + + with self.assertRaises(ValueError): + time_elements.TimeElements(time_elements_tuple=(2010, 8, 12, 20, 6)) + + with self.assertRaises(ValueError): + time_elements.TimeElements(time_elements_tuple=(2010, 2, 29, 20, 6)) + + with self.assertRaises(ValueError): + time_elements.TimeElements(time_elements_tuple=(2010, 13, 12, 20, 6, 31)) + + def testDayOfMonth(self): + """Tests the day_of_month property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.day_of_month) + + def testHours(self): + """Tests the hours property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.hours) + + def testMinutes(self): + """Tests the minutes property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.minutes) + + def testMonth(self): + """Tests the month property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.month) + + def testSeconds(self): + """Tests the seconds property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.seconds) + + def testYear(self): + """Tests the year property.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNone(time_elements_object.year) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591")) + + time_elements_object = time_elements.TimeElements( + 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")) + + time_elements_object = time_elements.TimeElements( + 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")) + + time_elements_object = time_elements.TimeElements() + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + def testCopyDateTimeFromStringISO8601(self): + """Tests the _CopyDateTimeFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElements() + + expected_date_dict = {"year": 2010, "month": 8, "day_of_month": 12} + date_dict = time_elements_object._CopyDateTimeFromStringISO8601("2010-08-12") + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + } + date_dict = time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12T21:06:31" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + } + date_dict = time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12T21:06:31.546875" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + "time_zone_offset": -60, + } + date_dict = time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12T21:06:31.546875-01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875000, + "time_zone_offset": 60, + } + date_dict = time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12T21:06:31.546875+01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 2010, + "month": 8, + "day_of_month": 12, + "hours": 21, + "minutes": 6, + "seconds": 31, + "nanoseconds": 546875333, + "time_zone_offset": 60, + } + date_dict = time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12T21:06:31.546875333+01:00" + ) + self.assertEqual(date_dict, expected_date_dict) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringISO8601("") + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringISO8601("2010-08-12T1") + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringISO8601( + "2010-08-12 21:06:31.546875+01:00" + ) + + def testCopyDateTimeFromStringRFC822(self): + """Tests the _CopyDateTimeFromStringRFC822 function.""" + time_elements_object = time_elements.TimeElements() + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 Jun 82 11:57:09 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC822( + "20 Jun 82 11:57:09 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC822( + "20 Jun 82 11:57 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": -300, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 Jun 82 11:57:09 EST" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": -300, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 Jun 82 11:57:09 -0500" + ) + self.assertEqual(date_dict, expected_date_dict) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822(None) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "XXX, 20 Jun 82 11:57:09 GMT BOGUS" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "XXX, 20 Jun 82 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, XX Jun 82 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 XXX 82 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 Jun XX 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC822( + "Sun, 20 Jun 82 XX:XX:XX XXX" + ) + + def testCopyDateTimeFromStringRFC1123(self): + """Tests the _CopyDateTimeFromStringRFC1123 function.""" + time_elements_object = time_elements.TimeElements() + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 Jun 1982 11:57:09 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( + "20 Jun 1982 11:57:09 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "time_zone_offset": 0, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( + "20 Jun 1982 11:57 GMT" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": -300, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 Jun 1982 11:57:09 EST" + ) + self.assertEqual(date_dict, expected_date_dict) + + expected_date_dict = { + "year": 1982, + "month": 6, + "day_of_month": 20, + "hours": 11, + "minutes": 57, + "seconds": 9, + "time_zone_offset": -300, + } + date_dict = time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 Jun 1982 11:57:09 -0500" + ) + self.assertEqual(date_dict, expected_date_dict) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123(None) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "XXX, 20 Jun 1982 11:57:09 GMT BOGUS" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "XXX, 20 Jun 1982 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, XX Jun 1982 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 XXX 1982 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 Jun XXXX 11:57:09 GMT" + ) + + with self.assertRaises(ValueError): + time_elements_object._CopyDateTimeFromStringRFC1123( + "Sun, 20 Jun 1982 XX:XX:XX XXX" + ) + + # TODO: add tests for _CopyFromDateTimeValues + + def testCopyTimeFromStringISO8601(self): + """Tests the _CopyTimeFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_tuple = (8, None, None, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("08") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (8, 4, None, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("08:04") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (8, 4, None, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("0804") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 30, 0, 0, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20.5") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (8, 4, 32, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("08:04:32") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (8, 4, 32, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("080432") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 30, 0, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20:23.5") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 30, 0, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("2023.5") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, None, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20:23:56") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, None, 330) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20:23:56+05:30") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327000000, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20:23:56.327") + self.assertEqual(time_tuple, expected_time_tuple) + + expected_time_tuple = (20, 23, 56, 327000000, 60) + time_tuple = time_elements_object._CopyTimeFromStringISO8601( + "20:23:56.327+01:00" + ) + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (20, 23, 56, 327000000, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('20:23:56.327') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (20, 23, 56, 327124000, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("20:23:56.327124") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (20, 23, 56, 327000000, 60) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56.327+01:00') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (8, 4, 32, None, 0) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("08:04:32Z") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (20, 23, 56, 327124000, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56.327124') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (8, 4, 32, None, 0) + time_tuple = time_elements_object._CopyTimeFromStringISO8601("08:04:32+00:00") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (8, 4, 32, None, 0) - time_tuple = time_elements_object._CopyTimeFromStringISO8601('08:04:32Z') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (20, 23, 56, 327124000, -300) + time_tuple = time_elements_object._CopyTimeFromStringISO8601( + "20:23:56.327124-05:00" + ) + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (8, 4, 32, None, 0) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '08:04:32+00:00') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (20, 23, 56, 327124519, None) + time_tuple = time_elements_object._CopyTimeFromStringISO8601( + "20:23:56.327124519" + ) + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (20, 23, 56, 327124000, -300) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56.327124-05:00') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (20, 23, 56, 327124519, -300) + time_tuple = time_elements_object._CopyTimeFromStringISO8601( + "20:23:56.327124519-05:00" + ) + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (20, 23, 56, 327124519, None) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56.327124519') - self.assertEqual(time_tuple, expected_time_tuple) + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("") - expected_time_tuple = (20, 23, 56, 327124519, -300) - time_tuple = time_elements_object._CopyTimeFromStringISO8601( - '20:23:56.327124519-05:00') - self.assertEqual(time_tuple, expected_time_tuple) + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("1") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("14:1") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('1') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("14:15:1") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('14:1') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("24:00:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('14:15:1') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12b00:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('24:00:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00b00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12b00:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("1s:00:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00b00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("00:60:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('1s:00:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("00:e0:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('00:60:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("00:00:60") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('00:e0:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("00:00:w0") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('00:00:60') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00.00w") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('00:00:w0') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00+01b00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00.00w') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00+0w:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00+01b00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00+20:00") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00+0w:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00+01:0w") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00+20:00') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringISO8601("12:00:00+01:60") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00+01:0w') + def testCopyTimeFromStringRFC(self): + """Tests the _CopyTimeFromStringRFC function.""" + time_elements_object = time_elements.TimeElements() - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringISO8601('12:00:00+01:60') + expected_time_tuple = (11, 57, 9, 0) + time_tuple = time_elements_object._CopyTimeFromStringRFC("11:57:09", "GMT") + self.assertEqual(time_tuple, expected_time_tuple) - def testCopyTimeFromStringRFC(self): - """Tests the _CopyTimeFromStringRFC function.""" - time_elements_object = time_elements.TimeElements() + expected_time_tuple = (11, 57, None, 0) + time_tuple = time_elements_object._CopyTimeFromStringRFC("11:57", "GMT") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (11, 57, 9, 0) - time_tuple = time_elements_object._CopyTimeFromStringRFC('11:57:09', 'GMT') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (11, 57, None, -300) + time_tuple = time_elements_object._CopyTimeFromStringRFC("11:57", "EST") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (11, 57, None, 0) - time_tuple = time_elements_object._CopyTimeFromStringRFC('11:57', 'GMT') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (11, 57, None, -300) + time_tuple = time_elements_object._CopyTimeFromStringRFC("11:57", "-0500") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (11, 57, None, -300) - time_tuple = time_elements_object._CopyTimeFromStringRFC('11:57', 'EST') - self.assertEqual(time_tuple, expected_time_tuple) + expected_time_tuple = (11, 57, None, 60) + time_tuple = time_elements_object._CopyTimeFromStringRFC("11:57", "+0100") + self.assertEqual(time_tuple, expected_time_tuple) - expected_time_tuple = (11, 57, None, -300) - time_tuple = time_elements_object._CopyTimeFromStringRFC('11:57', '-0500') - self.assertEqual(time_tuple, expected_time_tuple) + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:", "GMT") - expected_time_tuple = (11, 57, None, 60) - time_tuple = time_elements_object._CopyTimeFromStringRFC('11:57', '+0100') - self.assertEqual(time_tuple, expected_time_tuple) + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57:", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("XX:57:09", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57:', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("24:57:09", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('XX:57:09', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:XX:09", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('24:57:09', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:60:09", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:XX:09', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57:XX", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:60:09', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57:60", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57:XX', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57:09", "XXX") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57:60', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("12:34:56:78", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57:09', 'XXX') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("12X34:56", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('12:34:56:78', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("12:34X56", "GMT") - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('12X34:56', 'GMT') + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "+01000") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "ZZZ") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "A0160") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "+A500") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "+1600") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "+01A0") + + with self.assertRaises(ValueError): + time_elements_object._CopyTimeFromStringRFC("11:57", "+0160") + + def testCopyFromDatetime(self): + """Tests the CopyFromDatetime function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) + 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.assertTrue(time_elements_object.is_local_time) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + 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.assertFalse(time_elements_object.is_local_time) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, -11644387200) + self.assertEqual(time_elements_object._time_zone_offset, None) + + def testCopyFromStringISO8601(self): + """Tests the CopyFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromStringISO8601("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.5") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31,546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) + time_elements_object.CopyFromStringISO8601("2012-03-05T20:40:00.0000000+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1330980000) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601(None) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601( + "2010-08-12 21:06:31.546875+01:00" + ) + + # Valid ISO 8601 notations currently not supported. + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33-3") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("--08-17") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-230") + + def testCopyFromStringRFC822(self): + """Tests the CopyFromStringRFC822 function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (1982, 6, 20, 11, 57, 9) + time_elements_object.CopyFromStringRFC822("Sun, 20 Jun 82 11:57:09 GMT") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 393422229) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + def testCopyFromStringRFC1123(self): + """Tests the CopyFromStringRFC1123 function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (1982, 6, 20, 11, 57, 9) + time_elements_object.CopyFromStringRFC1123("Sun, 20 Jun 1982 11:57:09 GMT") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 393422229) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + def testCopyFromStringTuple(self): + """Tests the CopyFromStringTuple function.""" + time_elements_object = time_elements.TimeElements() + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object.CopyFromStringTuple( + 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 + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "6") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("20A0", "B", "12", "20", "6", "31") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "B", "12", "20", "6", "31") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "1C", "20", "6", "31") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "D0", "6", "31") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "E", "31") + ) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "6", "F1") + ) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + time_elements_object = time_elements.TimeElements( + 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") + + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(0, 8, 12, 20, 6, 31) + ) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "0000-08-12 20:06:31") + + time_elements_object = time_elements.TimeElements() + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31+00:00") + + time_elements_object.is_local_time = True + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31") + + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31), time_zone_offset=120 + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31+02:00") + + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31), time_zone_offset=-300 + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31-05:00") + + def testCopyToPosixTimestamp(self): + """Tests the CopyToPosixTimestamp function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertEqual(posix_timestamp, 1281643591) + + time_elements_object = time_elements.TimeElements() + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertIsNone(posix_timestamp) - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('12:34X56', 'GMT') + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', '+01000') + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertIsNone(fraction_of_second) - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', 'ZZZ') + time_elements_object = time_elements.TimeElements() - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', 'A0160') + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', '+A500') - - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', '+1600') - - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', '+01A0') - - with self.assertRaises(ValueError): - time_elements_object._CopyTimeFromStringRFC('11:57', '+0160') - - def testCopyFromDatetime(self): - """Tests the CopyFromDatetime function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) - 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.assertTrue(time_elements_object.is_local_time) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - 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.assertFalse(time_elements_object.is_local_time) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, -11644387200) - self.assertEqual(time_elements_object._time_zone_offset, None) - - def testCopyFromStringISO8601(self): - """Tests the CopyFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromStringISO8601('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.5') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31,546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) - time_elements_object.CopyFromStringISO8601( - '2012-03-05T20:40:00.0000000+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1330980000) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601(None) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601( - '2010-08-12 21:06:31.546875+01:00') - - # Valid ISO 8601 notations currently not supported. - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33-3') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('--08-17') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-230') - - def testCopyFromStringRFC822(self): - """Tests the CopyFromStringRFC822 function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (1982, 6, 20, 11, 57, 9) - time_elements_object.CopyFromStringRFC822('Sun, 20 Jun 82 11:57:09 GMT') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 393422229) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - def testCopyFromStringRFC1123(self): - """Tests the CopyFromStringRFC1123 function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (1982, 6, 20, 11, 57, 9) - time_elements_object.CopyFromStringRFC1123('Sun, 20 Jun 1982 11:57:09 GMT') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 393422229) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - def testCopyFromStringTuple(self): - """Tests the CopyFromStringTuple function.""" - time_elements_object = time_elements.TimeElements() - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object.CopyFromStringTuple( - 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) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', '6')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('20A0', 'B', '12', '20', '6', '31')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', 'B', '12', '20', '6', '31')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '1C', '20', '6', '31')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', 'D0', '6', '31')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', 'E', '31')) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', '6', 'F1')) + def testGetDate(self): + """Tests the GetDate function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31') + time_elements_object = time_elements.TimeElements() - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(0, 8, 12, 20, 6, 31)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '0000-08-12 20:06:31') + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) - time_elements_object = time_elements.TimeElements() + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + time_elements_object = time_elements.TimeElements() - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31+00:00') + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + time_elements_object = time_elements.TimeElements( + time_elements_tuple=(2010, 8, 12, 20, 6, 31) + ) - time_elements_object.is_local_time = True + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31') + time_elements_object = time_elements.TimeElements() - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31), - time_zone_offset=120) + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31+02:00') + 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) + ) - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31), - time_zone_offset=-300) + 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) - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31-05:00') + time_elements_object = time_elements.TimeElements(is_delta=True) - def testCopyToPosixTimestamp(self): - """Tests the CopyToPosixTimestamp function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + new_time_elements_object = time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + self.assertIsNone(new_time_elements_object) - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertEqual(posix_timestamp, 1281643591) + time_elements_object = time_elements.TimeElements(is_delta=False) - time_elements_object = time_elements.TimeElements() + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertIsNone(posix_timestamp) + def testNewFromDeltaAndYear(self): + """Tests the NewFromDeltaAndYear function.""" + time_elements_object = time_elements.TimeElements( + is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31) + ) - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertIsNotNone(new_time_elements_object) + self.assertFalse(new_time_elements_object.is_delta) + self.assertEqual(new_time_elements_object.year, 2010) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertIsNone(fraction_of_second) + time_elements_object = time_elements.TimeElements(is_delta=True) - time_elements_object = time_elements.TimeElements() + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertIsNone(new_time_elements_object) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + time_elements_object = time_elements.TimeElements(is_delta=False) - def testGetDate(self): - """Tests the GetDate function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) - - time_elements_object = time_elements.TimeElements() - - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) - - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - - time_elements_object = time_elements.TimeElements() - - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) - - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - time_elements_object = time_elements.TimeElements( - time_elements_tuple=(2010, 8, 12, 20, 6, 31)) - - time_of_day_tuple = time_elements_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) - - time_elements_object = time_elements.TimeElements() - - 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( - is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31)) - - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - self.assertIsNotNone(new_time_elements_object) - self.assertFalse(new_time_elements_object.is_delta) - self.assertEqual(new_time_elements_object.year, 2010) - - time_elements_object = time_elements.TimeElements(is_delta=True) - - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - self.assertIsNone(new_time_elements_object) - - time_elements_object = time_elements.TimeElements(is_delta=False) - - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndYear(2009) + with self.assertRaises(ValueError): + 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) - - 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'), - 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( - 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) - - 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')) - - 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) - 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) - - 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')) - - 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') - - 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( - 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) + """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) + + 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"), + 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( + 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) + + 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") + ) + + 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) + 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 + ) + + 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") + ) + + 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") + + 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( + 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) class TimeElementsInMillisecondsTest(unittest.TestCase): - """Tests for the time elements in milliseconds.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNotNone(time_elements_object) - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546)) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.milliseconds, 546) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31)) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001)) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.429')) - - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429), time_zone_offset=60) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.429')) - - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) - time_elements_object.time_zone_offset = 60 - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.429')) - - time_elements_object = time_elements.TimeElementsInMilliseconds() - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - # TODO: add tests for _CopyFromDateTimeValues - - def testCopyFromDatetime(self): - """Tests the CopyFromDatetime function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds() - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) - 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.milliseconds, 546) - self.assertTrue(time_elements_object.is_local_time) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - 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.milliseconds, 546) - self.assertFalse(time_elements_object.is_local_time) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, -11644387200) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - def testCopyFromStringISO8601(self): - """Tests the CopyFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromStringISO8601('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.5') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 500) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31,546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.milliseconds, 546) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) - time_elements_object.CopyFromStringISO8601( - '2012-03-05T20:40:00.0000000+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1330980000) - self.assertEqual(time_elements_object.milliseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601(None) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601( - '2010-08-12 21:06:31.546875+01:00') - - # Valid ISO 8601 notations currently not supported. - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33-3') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('--08-17') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-230') - - def testCopyFromStringTuple(self): - """Tests the CopyFromStringTuple function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds() - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', '6', '31', '546')) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.milliseconds, 546) - - 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', '9S')) - - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.429') - - time_elements_object = time_elements.TimeElementsInMilliseconds() - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) - - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.429+00:00') - - def testCopyToPosixTimestamp(self): - """Tests the CopyToPosixTimestamp function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertEqual(posix_timestamp, 1281643591) - - time_elements_object = time_elements.TimeElements() - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertIsNone(posix_timestamp) - - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) + """Tests for the time elements in milliseconds.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNotNone(time_elements_object) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546) + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.milliseconds, 546) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31) + ) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001) + ) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.429")) + + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429), time_zone_offset=60 + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429")) + + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + time_elements_object.time_zone_offset = 60 + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429")) + + time_elements_object = time_elements.TimeElementsInMilliseconds() + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + # TODO: add tests for _CopyFromDateTimeValues + + def testCopyFromDatetime(self): + """Tests the CopyFromDatetime function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds() + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) + 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.milliseconds, 546) + self.assertTrue(time_elements_object.is_local_time) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + 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.milliseconds, 546) + self.assertFalse(time_elements_object.is_local_time) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, -11644387200) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + def testCopyFromStringISO8601(self): + """Tests the CopyFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromStringISO8601("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.5") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 500) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31,546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.milliseconds, 546) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) + time_elements_object.CopyFromStringISO8601("2012-03-05T20:40:00.0000000+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1330980000) + self.assertEqual(time_elements_object.milliseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601(None) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601( + "2010-08-12 21:06:31.546875+01:00" + ) + + # Valid ISO 8601 notations currently not supported. + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33-3") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("--08-17") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-230") + + def testCopyFromStringTuple(self): + """Tests the CopyFromStringTuple function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds() + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "6", "31", "546") + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.milliseconds, 546) + + 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", "9S") + ) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.429") + + time_elements_object = time_elements.TimeElementsInMilliseconds() + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.429+00:00") + + def testCopyToPosixTimestamp(self): + """Tests the CopyToPosixTimestamp function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertEqual(posix_timestamp, 1281643591) + + time_elements_object = time_elements.TimeElements() + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertIsNone(posix_timestamp) + + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) + + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertEqual(fraction_of_second, 429) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertEqual(fraction_of_second, 429) + time_elements_object = time_elements.TimeElements() - time_elements_object = time_elements.TimeElements() + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + def testGetDate(self): + """Tests the GetDate function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) - def testGetDate(self): - """Tests the GetDate function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + time_elements_object = time_elements.TimeElementsInMilliseconds() - time_elements_object = time_elements.TimeElementsInMilliseconds() + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + time_elements_object = time_elements.TimeElementsInMilliseconds() - time_elements_object = time_elements.TimeElementsInMilliseconds() + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429)) + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - time_of_day_tuple = time_elements_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_elements_object = time_elements.TimeElementsInMilliseconds() - time_elements_object = time_elements.TimeElementsInMilliseconds() + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) - 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) + ) - 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) - 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) - 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) - 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) - time_elements_object = time_elements.TimeElements(is_delta=False) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + def testNewFromDeltaAndYear(self): + """Tests the NewFromDeltaAndYear function.""" + time_elements_object = time_elements.TimeElementsInMilliseconds( + is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429) + ) - def testNewFromDeltaAndYear(self): - """Tests the NewFromDeltaAndYear function.""" - time_elements_object = time_elements.TimeElementsInMilliseconds( - is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429)) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + 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.milliseconds, 429) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - 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.milliseconds, 429) + time_elements_object = time_elements.TimeElements(is_delta=True) - time_elements_object = time_elements.TimeElements(is_delta=True) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertIsNone(new_time_elements_object) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - self.assertIsNone(new_time_elements_object) + time_elements_object = time_elements.TimeElements(is_delta=False) - time_elements_object = time_elements.TimeElements(is_delta=False) - - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndYear(2009) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndYear(2009) class TimeElementsInMicrosecondsTest(unittest.TestCase): - """Tests for the time elements in microseconds.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNotNone(time_elements_object) - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546875)) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.microseconds, 546875) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31)) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001)) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.429876')) - - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876), - time_zone_offset=60) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.429876')) - - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - time_elements_object.time_zone_offset = 60 - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281639991.429876')) - - time_elements_object = time_elements.TimeElementsInMicroseconds() - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - # TODO: add tests for _CopyFromDateTimeValues - - def testCopyFromDatetime(self): - """Tests the CopyFromDatetime function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds() - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) - 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.microseconds, 546875) - self.assertTrue(time_elements_object.is_local_time) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - 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.microseconds, 546875) - self.assertFalse(time_elements_object.is_local_time) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, -11644387200) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - def testCopyFromStringISO8601(self): - """Tests the CopyFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromStringISO8601('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.5') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 500000) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31,546875') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.microseconds, 546875) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) - time_elements_object.CopyFromStringISO8601( - '2012-03-05T20:40:00.0000000+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1330980000) - self.assertEqual(time_elements_object.microseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601(None) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601( - '2010-08-12 21:06:31.546875+01:00') - - # Valid ISO 8601 notations currently not supported. - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33-3') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('--08-17') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-230') - - def testCopyFromStringTuple(self): - """Tests the CopyFromStringTuple function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds() - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', '6', '31', '546')) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.microseconds, 546) - - 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', '9S')) - - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.429876') - - time_elements_object = time_elements.TimeElementsInMicroseconds() - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.429876+00:00') - - def testCopyToPosixTimestamp(self): - """Tests the CopyToPosixTimestamp function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertEqual(posix_timestamp, 1281643591) - - time_elements_object = time_elements.TimeElements() - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertIsNone(posix_timestamp) - - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) + """Tests for the time elements in microseconds.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNotNone(time_elements_object) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546875) + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.microseconds, 546875) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31) + ) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001) + ) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.429876")) + + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876), time_zone_offset=60 + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429876")) + + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + time_elements_object.time_zone_offset = 60 + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429876")) + + time_elements_object = time_elements.TimeElementsInMicroseconds() + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + # TODO: add tests for _CopyFromDateTimeValues + + def testCopyFromDatetime(self): + """Tests the CopyFromDatetime function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds() + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) + 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.microseconds, 546875) + self.assertTrue(time_elements_object.is_local_time) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + 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.microseconds, 546875) + self.assertFalse(time_elements_object.is_local_time) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, -11644387200) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + def testCopyFromStringISO8601(self): + """Tests the CopyFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromStringISO8601("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.5") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 500000) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31,546875") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875-01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875+01:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.microseconds, 546875) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) + time_elements_object.CopyFromStringISO8601("2012-03-05T20:40:00.0000000+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1330980000) + self.assertEqual(time_elements_object.microseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601(None) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601( + "2010-08-12 21:06:31.546875+01:00" + ) + + # Valid ISO 8601 notations currently not supported. + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33-3") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("--08-17") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-230") + + def testCopyFromStringTuple(self): + """Tests the CopyFromStringTuple function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds() + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "6", "31", "546") + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.microseconds, 546) + + 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", "9S") + ) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.429876") + + time_elements_object = time_elements.TimeElementsInMicroseconds() + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.429876+00:00") + + def testCopyToPosixTimestamp(self): + """Tests the CopyToPosixTimestamp function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertEqual(posix_timestamp, 1281643591) + + time_elements_object = time_elements.TimeElements() + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertIsNone(posix_timestamp) + + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) + + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertEqual(fraction_of_second, 429876) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertEqual(fraction_of_second, 429876) + time_elements_object = time_elements.TimeElements() - time_elements_object = time_elements.TimeElements() + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + def testGetDate(self): + """Tests the GetDate function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) - def testGetDate(self): - """Tests the GetDate function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + time_elements_object = time_elements.TimeElementsInMicroseconds() - time_elements_object = time_elements.TimeElementsInMicroseconds() + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + time_elements_object = time_elements.TimeElementsInMicroseconds() - time_elements_object = time_elements.TimeElementsInMicroseconds() + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - time_of_day_tuple = time_elements_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_elements_object = time_elements.TimeElementsInMicroseconds() - time_elements_object = time_elements.TimeElementsInMicroseconds() + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) - 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) + ) - 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) - 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) - 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) - 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) - time_elements_object = time_elements.TimeElements(is_delta=False) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + def testNewFromDeltaAndYear(self): + """Tests the NewFromDeltaAndYear function.""" + time_elements_object = time_elements.TimeElementsInMicroseconds( + is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429876) + ) - def testNewFromDeltaAndYear(self): - """Tests the NewFromDeltaAndYear function.""" - time_elements_object = time_elements.TimeElementsInMicroseconds( - is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429876)) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + 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.microseconds, 429876) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - 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.microseconds, 429876) + time_elements_object = time_elements.TimeElements(is_delta=True) - time_elements_object = time_elements.TimeElements(is_delta=True) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertIsNone(new_time_elements_object) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - self.assertIsNone(new_time_elements_object) + time_elements_object = time_elements.TimeElements(is_delta=False) - time_elements_object = time_elements.TimeElements(is_delta=False) - - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndYear(2009) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndYear(2009) class TimeElementsInNanosecondsTest(unittest.TestCase): - """Tests for the time elements in nanoseconds.""" - - # pylint: disable=protected-access - - def testInitialize(self): - """Tests the initialization function.""" - time_elements_object = time_elements.TimeElements() - self.assertIsNotNone(time_elements_object) - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546875218)) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31)) - - with self.assertRaises(ValueError): - time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001)) - - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281643591.429876301')) - - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301), - time_zone_offset=60) - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.429876301')) - - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - time_elements_object.time_zone_offset = 60 - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1281639991.429876301')) - - time_elements_object = time_elements.TimeElementsInNanoseconds() - - normalized_timestamp = time_elements_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) - - # TODO: add tests for _CopyFromDateTimeValues - - def testCopyFromDatetime(self): - """Tests the CopyFromDatetime function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds() - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - # Note that datetime has microsecond precision. - datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) - 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.nanoseconds, 546875000) - self.assertTrue(time_elements_object.is_local_time) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - expected_number_of_seconds = 1281647191 - - # Note that datetime has microsecond precision. - 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.nanoseconds, 546875000) - self.assertFalse(time_elements_object.is_local_time) - - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875218') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875218-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875218+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) - time_elements_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, -11644387200) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - def testCopyFromStringISO8601(self): - """Tests the CopyFromStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds() - - expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) - time_elements_object.CopyFromStringISO8601('2010-08-12') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281571200) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.5') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 500000000) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.546875218') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31,546875218') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, None) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875218-01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, -60) - - expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) - time_elements_object.CopyFromStringISO8601( - '2010-08-12T21:06:31.546875218+01:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1281647191) - self.assertEqual(time_elements_object.nanoseconds, 546875218) - self.assertEqual(time_elements_object._time_zone_offset, 60) - - expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) - time_elements_object.CopyFromStringISO8601( - '2012-03-05T20:40:00.0000000+00:00') - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object._number_of_seconds, 1330980000) - self.assertEqual(time_elements_object.nanoseconds, 0) - self.assertEqual(time_elements_object._time_zone_offset, 0) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601(None) - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601( - '2010-08-12 21:06:31.546875218+01:00') - - # Valid ISO 8601 notations currently not supported. - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-W33-3') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('--08-17') - - with self.assertRaises(ValueError): - time_elements_object.CopyFromStringISO8601('2016-230') - - def testCopyFromStringTuple(self): - """Tests the CopyFromStringTuple function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds() - - expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) - time_elements_object.CopyFromStringTuple( - time_elements_tuple=('2010', '8', '12', '20', '6', '31', '546')) - self.assertIsNotNone(time_elements_object) - self.assertEqual( - time_elements_object._time_elements_tuple, expected_time_elements_tuple) - self.assertEqual(time_elements_object.nanoseconds, 546) - - 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', '9S')) - - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 20:06:31.429876301') - - time_elements_object = time_elements.TimeElementsInNanoseconds() - - date_time_string = time_elements_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) - - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - - date_time_string = time_elements_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T20:06:31.429876301+00:00') - - def testCopyToPosixTimestamp(self): - """Tests the CopyToPosixTimestamp function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertEqual(posix_timestamp, 1281643591) - - time_elements_object = time_elements.TimeElements() - - posix_timestamp = time_elements_object.CopyToPosixTimestamp() - self.assertIsNone(posix_timestamp) - - def testCopyToPosixTimestampWithFractionOfSecond(self): - """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) - - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertEqual(posix_timestamp, 1281643591) - self.assertEqual(fraction_of_second, 429876301) + """Tests for the time elements in nanoseconds.""" + + # pylint: disable=protected-access + + def testInitialize(self): + """Tests the initialization function.""" + time_elements_object = time_elements.TimeElements() + self.assertIsNotNone(time_elements_object) + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546875218) + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31) + ) + + with self.assertRaises(ValueError): + time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 13, 12, 20, 6, 31, 1001) + ) + + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.429876301")) + + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301), time_zone_offset=60 + ) + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429876301")) + + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + time_elements_object.time_zone_offset = 60 + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281639991.429876301")) + + time_elements_object = time_elements.TimeElementsInNanoseconds() + + normalized_timestamp = time_elements_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) + + # TODO: add tests for _CopyFromDateTimeValues + + def testCopyFromDatetime(self): + """Tests the CopyFromDatetime function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds() + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + # Note that datetime has microsecond precision. + datetime_object = datetime.datetime(2010, 8, 12, 21, 6, 31, 546875) + 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.nanoseconds, 546875000) + self.assertTrue(time_elements_object.is_local_time) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + expected_number_of_seconds = 1281647191 + + # Note that datetime has microsecond precision. + 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.nanoseconds, 546875000) + self.assertFalse(time_elements_object.is_local_time) + + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875218") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString( + "2010-08-12 21:06:31.546875218-01:00" + ) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromDateTimeString( + "2010-08-12 21:06:31.546875218+01:00" + ) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) + time_elements_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, -11644387200) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + def testCopyFromStringISO8601(self): + """Tests the CopyFromStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds() + + expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) + time_elements_object.CopyFromStringISO8601("2010-08-12") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281571200) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.5") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 500000000) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31.546875218") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601("2010-08-12T21:06:31,546875218") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, None) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601( + "2010-08-12T21:06:31.546875218-01:00" + ) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, -60) + + expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) + time_elements_object.CopyFromStringISO8601( + "2010-08-12T21:06:31.546875218+01:00" + ) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1281647191) + self.assertEqual(time_elements_object.nanoseconds, 546875218) + self.assertEqual(time_elements_object._time_zone_offset, 60) + + expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) + time_elements_object.CopyFromStringISO8601("2012-03-05T20:40:00.0000000+00:00") + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object._number_of_seconds, 1330980000) + self.assertEqual(time_elements_object.nanoseconds, 0) + self.assertEqual(time_elements_object._time_zone_offset, 0) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601(None) + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601( + "2010-08-12 21:06:31.546875218+01:00" + ) + + # Valid ISO 8601 notations currently not supported. + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-W33-3") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("--08-17") + + with self.assertRaises(ValueError): + time_elements_object.CopyFromStringISO8601("2016-230") + + def testCopyFromStringTuple(self): + """Tests the CopyFromStringTuple function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds() + + expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) + time_elements_object.CopyFromStringTuple( + time_elements_tuple=("2010", "8", "12", "20", "6", "31", "546") + ) + self.assertIsNotNone(time_elements_object) + self.assertEqual( + time_elements_object._time_elements_tuple, expected_time_elements_tuple + ) + self.assertEqual(time_elements_object.nanoseconds, 546) + + 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", "9S") + ) + + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 20:06:31.429876301") + + time_elements_object = time_elements.TimeElementsInNanoseconds() + + date_time_string = time_elements_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) + + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + + date_time_string = time_elements_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T20:06:31.429876301+00:00") + + def testCopyToPosixTimestamp(self): + """Tests the CopyToPosixTimestamp function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertEqual(posix_timestamp, 1281643591) + + time_elements_object = time_elements.TimeElements() + + posix_timestamp = time_elements_object.CopyToPosixTimestamp() + self.assertIsNone(posix_timestamp) + + def testCopyToPosixTimestampWithFractionOfSecond(self): + """Tests the CopyToPosixTimestampWithFractionOfSecond function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) + + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertEqual(posix_timestamp, 1281643591) + self.assertEqual(fraction_of_second, 429876301) - time_elements_object = time_elements.TimeElements() + time_elements_object = time_elements.TimeElements() - posix_timestamp, fraction_of_second = ( - time_elements_object.CopyToPosixTimestampWithFractionOfSecond()) - self.assertIsNone(posix_timestamp) - self.assertIsNone(fraction_of_second) + posix_timestamp, fraction_of_second = ( + time_elements_object.CopyToPosixTimestampWithFractionOfSecond() + ) + self.assertIsNone(posix_timestamp) + self.assertIsNone(fraction_of_second) - def testGetDate(self): - """Tests the GetDate function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) + def testGetDate(self): + """Tests the GetDate function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - time_elements_object = time_elements.TimeElementsInNanoseconds() + time_elements_object = time_elements.TimeElementsInNanoseconds() - date_tuple = time_elements_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = time_elements_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 20, 6, 31)) - time_elements_object = time_elements.TimeElementsInNanoseconds() + time_elements_object = time_elements.TimeElementsInNanoseconds() - date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = time_elements_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301)) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876301) + ) - time_of_day_tuple = time_elements_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (20, 6, 31)) + time_of_day_tuple = time_elements_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (20, 6, 31)) - time_elements_object = time_elements.TimeElementsInNanoseconds() + time_elements_object = time_elements.TimeElementsInNanoseconds() - time_of_day_tuple = time_elements_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + 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.TimeElementsInNanoseconds( - is_delta=True, time_elements_tuple=(1, 0, 0, 20, 6, 31, 429876301)) + def testNewFromDeltaAndDate(self): + """Tests the NewFromDeltaAndDate function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + is_delta=True, time_elements_tuple=(1, 0, 0, 20, 6, 31, 429876301) + ) - 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.nanoseconds, 429876301) + 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.nanoseconds, 429876301) - time_elements_object = time_elements.TimeElements(is_delta=True) + 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) + 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) + time_elements_object = time_elements.TimeElements(is_delta=False) - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndDate(2009, 1, 12) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndDate(2009, 1, 12) - def testNewFromDeltaAndYear(self): - """Tests the NewFromDeltaAndYear function.""" - time_elements_object = time_elements.TimeElementsInNanoseconds( - is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429876301)) + def testNewFromDeltaAndYear(self): + """Tests the NewFromDeltaAndYear function.""" + time_elements_object = time_elements.TimeElementsInNanoseconds( + is_delta=True, time_elements_tuple=(1, 8, 12, 20, 6, 31, 429876301) + ) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - 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.nanoseconds, 429876301) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + 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.nanoseconds, 429876301) - time_elements_object = time_elements.TimeElements(is_delta=True) + time_elements_object = time_elements.TimeElements(is_delta=True) - new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) - self.assertIsNone(new_time_elements_object) + new_time_elements_object = time_elements_object.NewFromDeltaAndYear(2009) + self.assertIsNone(new_time_elements_object) - time_elements_object = time_elements.TimeElements(is_delta=False) + time_elements_object = time_elements.TimeElements(is_delta=False) - with self.assertRaises(ValueError): - time_elements_object.NewFromDeltaAndYear(2009) + with self.assertRaises(ValueError): + time_elements_object.NewFromDeltaAndYear(2009) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/uuid_time.py b/tests/uuid_time.py index 03d57cf..48a46db 100644 --- a/tests/uuid_time.py +++ b/tests/uuid_time.py @@ -9,179 +9,178 @@ class UUIDTimeEpochTEst(unittest.TestCase): - """Tests for the UUID version 1 time time epoch.""" + """Tests for the UUID version 1 time time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - uuid_time_epoch = uuid_time.UUIDTimeEpoch() - self.assertIsNotNone(uuid_time_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + uuid_time_epoch = uuid_time.UUIDTimeEpoch() + self.assertIsNotNone(uuid_time_epoch) class UUIDTimeTest(unittest.TestCase): - """Tests for the UUID version 1 timestamp.""" + """Tests for the UUID version 1 timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testInitialize(self): - """Tests the initialization function.""" - uuid_time_object = uuid_time.UUIDTime() - self.assertIsNotNone(uuid_time_object) + def testInitialize(self): + """Tests the initialization function.""" + uuid_time_object = uuid_time.UUIDTime() + self.assertIsNotNone(uuid_time_object) - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - self.assertIsNotNone(uuid_time_object) - expected_timestamp = 135564234616544084 - self.assertEqual(uuid_time_object.timestamp, expected_timestamp) + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + self.assertIsNotNone(uuid_time_object) + expected_timestamp = 135564234616544084 + self.assertEqual(uuid_time_object.timestamp, expected_timestamp) - with self.assertRaises(ValueError): - uuid_time.UUIDTime(timestamp=0x1fffffffffffffff) + with self.assertRaises(ValueError): + uuid_time.UUIDTime(timestamp=0x1FFFFFFFFFFFFFFF) - with self.assertRaises(ValueError): - uuid_time.UUIDTime(timestamp=-1) + with self.assertRaises(ValueError): + uuid_time.UUIDTime(timestamp=-1) - def testProperties(self): - """Tests the properties.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - self.assertEqual(uuid_time_object.timestamp, 0x1e19ef400911b54) + def testProperties(self): + """Tests the properties.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + self.assertEqual(uuid_time_object.timestamp, 0x1E19EF400911B54) - uuid_time_object = uuid_time.UUIDTime() - self.assertIsNone(uuid_time_object.timestamp) + uuid_time_object = uuid_time.UUIDTime() + self.assertIsNone(uuid_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1337130661.6544084')) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1337130661.6544084")) - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime( - time_zone_offset=60, timestamp=uuid_object.time) + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime( + time_zone_offset=60, timestamp=uuid_object.time + ) - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1337127061.6544084')) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1337127061.6544084")) - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - uuid_time_object.time_zone_offset = 60 + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + uuid_time_object.time_zone_offset = 60 - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertEqual( - normalized_timestamp, decimal.Decimal('1337127061.6544084')) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1337127061.6544084")) - uuid_time_object = uuid_time.UUIDTime() - uuid_time_object._timestamp = 0x1fffffffffffffff + uuid_time_object = uuid_time.UUIDTime() + uuid_time_object._timestamp = 0x1FFFFFFFFFFFFFFF - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - uuid_time_object = uuid_time.UUIDTime() - uuid_time_object._timestamp = -1 + uuid_time_object = uuid_time.UUIDTime() + uuid_time_object._timestamp = -1 - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - uuid_time_object = uuid_time.UUIDTime() + uuid_time_object = uuid_time.UUIDTime() - normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = uuid_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - uuid_time_object = uuid_time.UUIDTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + uuid_time_object = uuid_time.UUIDTime() - uuid_time_object.CopyFromDateTimeString('2013-08-01') - self.assertEqual(uuid_time_object._timestamp, 135946080000000000) - self.assertEqual(uuid_time_object._time_zone_offset, None) + uuid_time_object.CopyFromDateTimeString("2013-08-01") + self.assertEqual(uuid_time_object._timestamp, 135946080000000000) + self.assertEqual(uuid_time_object._time_zone_offset, None) - uuid_time_object.CopyFromDateTimeString('2013-08-01 15:25:28') - self.assertEqual(uuid_time_object._timestamp, 135946635280000000) - self.assertEqual(uuid_time_object._time_zone_offset, None) + uuid_time_object.CopyFromDateTimeString("2013-08-01 15:25:28") + self.assertEqual(uuid_time_object._timestamp, 135946635280000000) + self.assertEqual(uuid_time_object._time_zone_offset, None) - uuid_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875') - self.assertEqual(uuid_time_object._timestamp, 135946635285468750) - self.assertEqual(uuid_time_object._time_zone_offset, None) + uuid_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875") + self.assertEqual(uuid_time_object._timestamp, 135946635285468750) + self.assertEqual(uuid_time_object._time_zone_offset, None) - uuid_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875-01:00') - self.assertEqual(uuid_time_object._timestamp, 135946635285468750) - self.assertEqual(uuid_time_object._time_zone_offset, -60) + uuid_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875-01:00") + self.assertEqual(uuid_time_object._timestamp, 135946635285468750) + self.assertEqual(uuid_time_object._time_zone_offset, -60) - uuid_time_object.CopyFromDateTimeString('2013-08-01 15:25:28.546875+01:00') - self.assertEqual(uuid_time_object._timestamp, 135946635285468750) - self.assertEqual(uuid_time_object._time_zone_offset, 60) + uuid_time_object.CopyFromDateTimeString("2013-08-01 15:25:28.546875+01:00") + self.assertEqual(uuid_time_object._timestamp, 135946635285468750) + self.assertEqual(uuid_time_object._time_zone_offset, 60) - uuid_time_object.CopyFromDateTimeString('1582-10-16 00:00:00') - self.assertEqual(uuid_time_object._timestamp, 864000000000) - self.assertEqual(uuid_time_object._time_zone_offset, None) + uuid_time_object.CopyFromDateTimeString("1582-10-16 00:00:00") + self.assertEqual(uuid_time_object._timestamp, 864000000000) + self.assertEqual(uuid_time_object._time_zone_offset, None) - with self.assertRaises(ValueError): - uuid_time_object.CopyFromDateTimeString('1570-01-02 00:00:00') + with self.assertRaises(ValueError): + uuid_time_object.CopyFromDateTimeString("1570-01-02 00:00:00") - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - date_time_string = uuid_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2012-05-16 01:11:01.6544084') + date_time_string = uuid_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2012-05-16 01:11:01.6544084") - uuid_time_object = uuid_time.UUIDTime() + uuid_time_object = uuid_time.UUIDTime() - date_time_string = uuid_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = uuid_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - date_time_string = uuid_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2012-05-16T01:11:01.6544084+00:00') + date_time_string = uuid_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2012-05-16T01:11:01.6544084+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testGetDate(self): + """Tests the GetDate function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - date_tuple = uuid_time_object.GetDate() - self.assertEqual(date_tuple, (2012, 5, 16)) + date_tuple = uuid_time_object.GetDate() + self.assertEqual(date_tuple, (2012, 5, 16)) - uuid_time_object = uuid_time.UUIDTime() + uuid_time_object = uuid_time.UUIDTime() - date_tuple = uuid_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = uuid_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - date_with_time_of_day_tuple = uuid_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2012, 5, 16, 1, 11, 1)) + date_with_time_of_day_tuple = uuid_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2012, 5, 16, 1, 11, 1)) - uuid_time_object = uuid_time.UUIDTime() + uuid_time_object = uuid_time.UUIDTime() - date_with_time_of_day_tuple = uuid_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = uuid_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - uuid_object = uuid.UUID('00911b54-9ef4-11e1-be53-525400123456') - uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + uuid_object = uuid.UUID("00911b54-9ef4-11e1-be53-525400123456") + uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time) - time_of_day_tuple = uuid_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (1, 11, 1)) + time_of_day_tuple = uuid_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (1, 11, 1)) - uuid_time_object = uuid_time.UUIDTime() + uuid_time_object = uuid_time.UUIDTime() - time_of_day_tuple = uuid_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = uuid_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tests/webkit_time.py b/tests/webkit_time.py index 49338d3..f4272f7 100644 --- a/tests/webkit_time.py +++ b/tests/webkit_time.py @@ -8,142 +8,142 @@ class WebKitTimeEpochTest(unittest.TestCase): - """Tests for the WebKit time epoch.""" + """Tests for the WebKit time epoch.""" - def testInitialize(self): - """Tests the __init__ function.""" - webkit_epoch = webkit_time.WebKitTimeEpoch() - self.assertIsNotNone(webkit_epoch) + def testInitialize(self): + """Tests the __init__ function.""" + webkit_epoch = webkit_time.WebKitTimeEpoch() + self.assertIsNotNone(webkit_epoch) class WebKitTimeTest(unittest.TestCase): - """Tests for the WebKit timestamp.""" + """Tests for the WebKit timestamp.""" - # pylint: disable=protected-access + # pylint: disable=protected-access - def testProperties(self): - """Tests the properties.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - self.assertEqual(webkit_time_object.timestamp, 12926120791546875) + def testProperties(self): + """Tests the properties.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + self.assertEqual(webkit_time_object.timestamp, 12926120791546875) - webkit_time_object = webkit_time.WebKitTime() - self.assertIsNone(webkit_time_object.timestamp) + webkit_time_object = webkit_time.WebKitTime() + self.assertIsNone(webkit_time_object.timestamp) - def testGetNormalizedTimestamp(self): - """Tests the _GetNormalizedTimestamp function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testGetNormalizedTimestamp(self): + """Tests the _GetNormalizedTimestamp function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281647191.546875')) + normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281647191.546875")) - webkit_time_object = webkit_time.WebKitTime( - time_zone_offset=60, timestamp=12926120791546875) + webkit_time_object = webkit_time.WebKitTime( + time_zone_offset=60, timestamp=12926120791546875 + ) - normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - webkit_time_object.time_zone_offset = 60 + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + webkit_time_object.time_zone_offset = 60 - normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() - self.assertEqual(normalized_timestamp, decimal.Decimal('1281643591.546875')) + normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() + self.assertEqual(normalized_timestamp, decimal.Decimal("1281643591.546875")) - webkit_time_object = webkit_time.WebKitTime(timestamp=0x1ffffffffffffffff) + webkit_time_object = webkit_time.WebKitTime(timestamp=0x1FFFFFFFFFFFFFFFF) - normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - webkit_time_object = webkit_time.WebKitTime() + webkit_time_object = webkit_time.WebKitTime() - normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() - self.assertIsNone(normalized_timestamp) + normalized_timestamp = webkit_time_object._GetNormalizedTimestamp() + self.assertIsNone(normalized_timestamp) - def testCopyFromDateTimeString(self): - """Tests the CopyFromDateTimeString function.""" - webkit_time_object = webkit_time.WebKitTime() + def testCopyFromDateTimeString(self): + """Tests the CopyFromDateTimeString function.""" + webkit_time_object = webkit_time.WebKitTime() - webkit_time_object.CopyFromDateTimeString('2010-08-12') - self.assertEqual(webkit_time_object._timestamp, 12926044800000000) - self.assertEqual(webkit_time_object._time_zone_offset, None) + webkit_time_object.CopyFromDateTimeString("2010-08-12") + self.assertEqual(webkit_time_object._timestamp, 12926044800000000) + self.assertEqual(webkit_time_object._time_zone_offset, None) - webkit_time_object.CopyFromDateTimeString('2010-08-12 21:06:31') - self.assertEqual(webkit_time_object._timestamp, 12926120791000000) - self.assertEqual(webkit_time_object._time_zone_offset, None) + webkit_time_object.CopyFromDateTimeString("2010-08-12 21:06:31") + self.assertEqual(webkit_time_object._timestamp, 12926120791000000) + self.assertEqual(webkit_time_object._time_zone_offset, None) - webkit_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875') - self.assertEqual(webkit_time_object._timestamp, 12926120791546875) - self.assertEqual(webkit_time_object._time_zone_offset, None) + webkit_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875") + self.assertEqual(webkit_time_object._timestamp, 12926120791546875) + self.assertEqual(webkit_time_object._time_zone_offset, None) - webkit_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875-01:00') - self.assertEqual(webkit_time_object._timestamp, 12926120791546875) - self.assertEqual(webkit_time_object._time_zone_offset, -60) + webkit_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875-01:00") + self.assertEqual(webkit_time_object._timestamp, 12926120791546875) + self.assertEqual(webkit_time_object._time_zone_offset, -60) - webkit_time_object.CopyFromDateTimeString( - '2010-08-12 21:06:31.546875+01:00') - self.assertEqual(webkit_time_object._timestamp, 12926120791546875) - self.assertEqual(webkit_time_object._time_zone_offset, 60) + webkit_time_object.CopyFromDateTimeString("2010-08-12 21:06:31.546875+01:00") + self.assertEqual(webkit_time_object._timestamp, 12926120791546875) + self.assertEqual(webkit_time_object._time_zone_offset, 60) - webkit_time_object.CopyFromDateTimeString('1601-01-02 00:00:00') - self.assertEqual(webkit_time_object._timestamp, 86400 * 1000000) - self.assertEqual(webkit_time_object._time_zone_offset, None) + webkit_time_object.CopyFromDateTimeString("1601-01-02 00:00:00") + self.assertEqual(webkit_time_object._timestamp, 86400 * 1000000) + self.assertEqual(webkit_time_object._time_zone_offset, None) - def testCopyToDateTimeString(self): - """Tests the CopyToDateTimeString function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testCopyToDateTimeString(self): + """Tests the CopyToDateTimeString function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - date_time_string = webkit_time_object.CopyToDateTimeString() - self.assertEqual(date_time_string, '2010-08-12 21:06:31.546875') + date_time_string = webkit_time_object.CopyToDateTimeString() + self.assertEqual(date_time_string, "2010-08-12 21:06:31.546875") - webkit_time_object = webkit_time.WebKitTime() + webkit_time_object = webkit_time.WebKitTime() - date_time_string = webkit_time_object.CopyToDateTimeString() - self.assertIsNone(date_time_string) + date_time_string = webkit_time_object.CopyToDateTimeString() + self.assertIsNone(date_time_string) - def testCopyToDateTimeStringISO8601(self): - """Tests the CopyToDateTimeStringISO8601 function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testCopyToDateTimeStringISO8601(self): + """Tests the CopyToDateTimeStringISO8601 function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - date_time_string = webkit_time_object.CopyToDateTimeStringISO8601() - self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875+00:00') + date_time_string = webkit_time_object.CopyToDateTimeStringISO8601() + self.assertEqual(date_time_string, "2010-08-12T21:06:31.546875+00:00") - def testGetDate(self): - """Tests the GetDate function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testGetDate(self): + """Tests the GetDate function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - date_tuple = webkit_time_object.GetDate() - self.assertEqual(date_tuple, (2010, 8, 12)) + date_tuple = webkit_time_object.GetDate() + self.assertEqual(date_tuple, (2010, 8, 12)) - webkit_time_object = webkit_time.WebKitTime() + webkit_time_object = webkit_time.WebKitTime() - date_tuple = webkit_time_object.GetDate() - self.assertEqual(date_tuple, (None, None, None)) + date_tuple = webkit_time_object.GetDate() + self.assertEqual(date_tuple, (None, None, None)) - def testGetDateWithTimeOfDay(self): - """Tests the GetDateWithTimeOfDay function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testGetDateWithTimeOfDay(self): + """Tests the GetDateWithTimeOfDay function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - date_with_time_of_day_tuple = webkit_time_object.GetDateWithTimeOfDay() - self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) + date_with_time_of_day_tuple = webkit_time_object.GetDateWithTimeOfDay() + self.assertEqual(date_with_time_of_day_tuple, (2010, 8, 12, 21, 6, 31)) - webkit_time_object = webkit_time.WebKitTime() + webkit_time_object = webkit_time.WebKitTime() - date_with_time_of_day_tuple = webkit_time_object.GetDateWithTimeOfDay() - self.assertEqual( - date_with_time_of_day_tuple, (None, None, None, None, None, None)) + date_with_time_of_day_tuple = webkit_time_object.GetDateWithTimeOfDay() + self.assertEqual( + date_with_time_of_day_tuple, (None, None, None, None, None, None) + ) - def testGetTimeOfDay(self): - """Tests the GetTimeOfDay function.""" - webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) + def testGetTimeOfDay(self): + """Tests the GetTimeOfDay function.""" + webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875) - time_of_day_tuple = webkit_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (21, 6, 31)) + time_of_day_tuple = webkit_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (21, 6, 31)) - webkit_time_object = webkit_time.WebKitTime() + webkit_time_object = webkit_time.WebKitTime() - time_of_day_tuple = webkit_time_object.GetTimeOfDay() - self.assertEqual(time_of_day_tuple, (None, None, None)) + time_of_day_tuple = webkit_time_object.GetTimeOfDay() + self.assertEqual(time_of_day_tuple, (None, None, None)) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() diff --git a/tox.ini b/tox.ini index 3ac8716..2c3b69e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py3{10,11,12,13,14},coverage,docs,lint,wheel +envlist = py3{10,11,12,13,14},black,coverage,docs,pylint,wheel [testenv] allowlist_externals = ./run_tests.py @@ -23,6 +23,22 @@ commands = coverage: coverage xml wheel: python -m build --no-isolation --wheel +[testenv:black] +skipsdist = True +pip_pre = True +passenv = + CFLAGS + CPPFLAGS + LDFLAGS +setenv = + PYTHONPATH = {toxinidir} +deps = + black + setuptools >= 65 +commands = + black --version + black --check . + [testenv:docs] usedevelop = True deps = @@ -31,7 +47,7 @@ commands = sphinx-build -b html -d build/doctrees docs dist/docs sphinx-build -b linkcheck docs dist/docs -[testenv:lint] +[testenv:pylint] skipsdist = True pip_pre = True passenv = diff --git a/utils/check_dependencies.py b/utils/check_dependencies.py index 97e95d3..6814c13 100755 --- a/utils/check_dependencies.py +++ b/utils/check_dependencies.py @@ -4,13 +4,12 @@ import sys # Change PYTHONPATH to include dependencies. -sys.path.insert(0, '.') +sys.path.insert(0, ".") import utils.dependencies # pylint: disable=wrong-import-position +if __name__ == "__main__": + dependency_helper = utils.dependencies.DependencyHelper() -if __name__ == '__main__': - dependency_helper = utils.dependencies.DependencyHelper() - - if not dependency_helper.CheckDependencies(): - sys.exit(1) + if not dependency_helper.CheckDependencies(): + sys.exit(1) diff --git a/utils/dependencies.py b/utils/dependencies.py index c94b92e..9e733f8 100644 --- a/utils/dependencies.py +++ b/utils/dependencies.py @@ -6,350 +6,375 @@ class DependencyDefinition: - """Dependency definition. - - Attributes: - dpkg_name (str): name of the dpkg package that provides the dependency. - is_optional (bool): True if the dependency is optional. - l2tbinaries_name (str): name of the l2tbinaries package that provides - the dependency. - maximum_version (str): maximum supported version, a greater or equal - version is not supported. - minimum_version (str): minimum supported version, a lesser version is - not supported. - name (str): name of (the Python module that provides) the dependency. - pypi_name (str): name of the PyPI package that provides the dependency. - python2_only (bool): True if the dependency is only supported by Python 2. - python3_only (bool): True if the dependency is only supported by Python 3. - rpm_name (str): name of the rpm package that provides the dependency. - skip_check (bool): True if the dependency should be skipped by the - CheckDependencies or CheckTestDependencies methods of DependencyHelper. - skip_requires (bool): True if the dependency should be excluded from - pyproject.toml dependencies. - version_property (str): name of the version attribute or function. - """ - - def __init__(self, name): - """Initializes a dependency configuration. - - Args: - name (str): name of the dependency. + """Dependency definition. + + Attributes: + dpkg_name (str): name of the dpkg package that provides the dependency. + is_optional (bool): True if the dependency is optional. + l2tbinaries_name (str): name of the l2tbinaries package that provides + the dependency. + maximum_version (str): maximum supported version, a greater or equal + version is not supported. + minimum_version (str): minimum supported version, a lesser version is + not supported. + name (str): name of (the Python module that provides) the dependency. + pypi_name (str): name of the PyPI package that provides the dependency. + python2_only (bool): True if the dependency is only supported by Python 2. + python3_only (bool): True if the dependency is only supported by Python 3. + rpm_name (str): name of the rpm package that provides the dependency. + skip_check (bool): True if the dependency should be skipped by the + CheckDependencies or CheckTestDependencies methods of DependencyHelper. + skip_requires (bool): True if the dependency should be excluded from + pyproject.toml dependencies. + version_property (str): name of the version attribute or function. """ - super().__init__() - self.dpkg_name = None - self.is_optional = False - self.l2tbinaries_name = None - self.maximum_version = None - self.minimum_version = None - self.name = name - self.pypi_name = None - self.python2_only = False - self.python3_only = False - self.rpm_name = None - self.skip_check = None - self.skip_requires = None - self.version_property = None + def __init__(self, name): + """Initializes a dependency configuration. + + Args: + name (str): name of the dependency. + """ + super().__init__() + self.dpkg_name = None + self.is_optional = False + self.l2tbinaries_name = None + self.maximum_version = None + self.minimum_version = None + self.name = name + self.pypi_name = None + self.python2_only = False + self.python3_only = False + self.rpm_name = None + self.skip_check = None + self.skip_requires = None + self.version_property = None -class DependencyDefinitionReader: - """Dependency definition reader.""" - - _VALUE_NAMES = frozenset([ - 'dpkg_name', - 'is_optional', - 'l2tbinaries_name', - 'maximum_version', - 'minimum_version', - 'pypi_name', - 'python2_only', - 'python3_only', - 'rpm_name', - 'skip_check', - 'skip_requires', - 'version_property']) - - def _GetConfigValue(self, config_parser, section_name, value_name): - """Retrieves a value from the config parser. - - Args: - config_parser (ConfigParser): configuration parser. - section_name (str): name of the section that contains the value. - value_name (str): name of the value. - - Returns: - object: configuration value or None if the value does not exists. - """ - try: - return config_parser.get(section_name, value_name) - except configparser.NoOptionError: - return None - - def Read(self, file_object): - """Reads dependency definitions. - - Args: - file_object (file): file-like object to read from. - - Yields: - DependencyDefinition: dependency definition. - """ - config_parser = configparser.ConfigParser(interpolation=None) - config_parser.read_file(file_object) - - for section_name in config_parser.sections(): - dependency_definition = DependencyDefinition(section_name) - for value_name in self._VALUE_NAMES: - value = self._GetConfigValue(config_parser, section_name, value_name) - setattr(dependency_definition, value_name, value) - yield dependency_definition +class DependencyDefinitionReader: + """Dependency definition reader.""" + + _VALUE_NAMES = frozenset( + [ + "dpkg_name", + "is_optional", + "l2tbinaries_name", + "maximum_version", + "minimum_version", + "pypi_name", + "python2_only", + "python3_only", + "rpm_name", + "skip_check", + "skip_requires", + "version_property", + ] + ) + + def _GetConfigValue(self, config_parser, section_name, value_name): + """Retrieves a value from the config parser. + + Args: + config_parser (ConfigParser): configuration parser. + section_name (str): name of the section that contains the value. + value_name (str): name of the value. + + Returns: + object: configuration value or None if the value does not exists. + """ + try: + return config_parser.get(section_name, value_name) + except configparser.NoOptionError: + return None + + def Read(self, file_object): + """Reads dependency definitions. + + Args: + file_object (file): file-like object to read from. + + Yields: + DependencyDefinition: dependency definition. + """ + config_parser = configparser.ConfigParser(interpolation=None) + config_parser.read_file(file_object) + + for section_name in config_parser.sections(): + dependency_definition = DependencyDefinition(section_name) + for value_name in self._VALUE_NAMES: + value = self._GetConfigValue(config_parser, section_name, value_name) + setattr(dependency_definition, value_name, value) + + yield dependency_definition class DependencyHelper: - """Dependency helper. - - Attributes: - dependencies (dict[str, DependencyDefinition]): dependencies. - """ - - _VERSION_NUMBERS_REGEX = re.compile(r'[0-9.]+') - _VERSION_SPLIT_REGEX = re.compile(r'\.|\-') - - def __init__( - self, dependencies_file='dependencies.ini', - test_dependencies_file='test_dependencies.ini'): - """Initializes a dependency helper. - - Args: - dependencies_file (Optional[str]): path to the dependencies configuration - file. - test_dependencies_file (Optional[str]): path to the test dependencies - configuration file. - """ - super().__init__() - self._test_dependencies = {} - self.dependencies = {} - - dependency_reader = DependencyDefinitionReader() - - with open(dependencies_file, 'r', encoding='utf-8') as file_object: - for dependency in dependency_reader.Read(file_object): - self.dependencies[dependency.name] = dependency - - if os.path.exists(test_dependencies_file): - with open(test_dependencies_file, 'r', encoding='utf-8') as file_object: - for dependency in dependency_reader.Read(file_object): - self._test_dependencies[dependency.name] = dependency - - def _CheckPythonModule(self, dependency): - """Checks the availability of a Python module. - - Args: - dependency (DependencyDefinition): dependency definition. - - Returns: - tuple: containing: - - bool: True if the Python module is available and conforms to - the minimum required version, False otherwise. - str: status message. - """ - module_object = self._ImportPythonModule(dependency.name) - if not module_object: - return False, f'missing: {dependency.name:s}' - - if not dependency.version_property: - return True, dependency.name - - return self._CheckPythonModuleVersion( - dependency.name, module_object, dependency.version_property, - dependency.minimum_version, dependency.maximum_version) - - def _CheckPythonModuleVersion( - self, module_name, module_object, version_property, minimum_version, - maximum_version): - """Checks the version of a Python module. - - Args: - module_object (module): Python module. - module_name (str): name of the Python module. - version_property (str): version attribute or function. - minimum_version (str): minimum version. - maximum_version (str): maximum version. - - Returns: - tuple: containing: - - bool: True if the Python module is available and conforms to - the minimum required version, False otherwise. - str: status message. - """ - module_version = None - if not version_property.endswith('()'): - module_version = getattr(module_object, version_property, None) - else: - version_method = getattr( - module_object, version_property[:-2], None) - if version_method: - module_version = version_method() - - if not module_version: - return False, ( - f'unable to determine version information for: {module_name:s}') - - # Make sure the module version is a string. - module_version = f'{module_version!s}' - - # Split the version string and convert every digit into an integer. - # A string compare of both version strings will yield an incorrect result. - - # Strip any semantic suffixes such as a1, b1, pre, post, rc, dev. - module_version = self._VERSION_NUMBERS_REGEX.findall(module_version)[0] - - if module_version[-1] == '.': - module_version = module_version[:-1] - - try: - module_version_map = list( - map(int, self._VERSION_SPLIT_REGEX.split(module_version))) - except ValueError: - return False, ( - f'unable to parse module version: {module_name:s} {module_version:s}') - - if minimum_version: - try: - minimum_version_map = list( - map(int, self._VERSION_SPLIT_REGEX.split(minimum_version))) - except ValueError: - return False, ( - f'unable to parse minimum version: {module_name:s} ' - f'{minimum_version:s}') - - if module_version_map < minimum_version_map: - return False, ( - f'{module_name:s} version: {module_version!s} is too old, ' - f'{minimum_version!s} or later required') - - if maximum_version: - try: - maximum_version_map = list( - map(int, self._VERSION_SPLIT_REGEX.split(maximum_version))) - except ValueError: - return False, ( - f'unable to parse maximum version: {module_name:s} ' - f'{maximum_version:s}') - - if module_version_map > maximum_version_map: - return False, ( - f'{module_name:s} version: {module_version!s} is too recent, ' - f'{maximum_version!s} or earlier required') - - return True, f'{module_name:s} version: {module_version!s}' - - def _ImportPythonModule(self, module_name): - """Imports a Python module. - - Args: - module_name (str): name of the module. - - Returns: - module: Python module or None if the module cannot be imported. - """ - try: - module_object = list(map(__import__, [module_name]))[0] - except ImportError: - return None - - # If the module name contains dots get the upper most module object. - if '.' in module_name: - for submodule_name in module_name.split('.')[1:]: - module_object = getattr(module_object, submodule_name, None) - - return module_object - - def _PrintCheckDependencyStatus( - self, dependency, result, status_message, verbose_output=True): - """Prints the check dependency status. - - Args: - dependency (DependencyDefinition): dependency definition. - result (bool): True if the Python module is available and conforms to - the minimum required version, False otherwise. - status_message (str): status message. - verbose_output (Optional[bool]): True if output should be verbose. - """ - if not result or dependency.is_optional: - if dependency.is_optional: - status_indicator = '[OPTIONAL]' - else: - status_indicator = '[FAILURE]' - - print(f'{status_indicator:s}\t{status_message:s}') - - elif verbose_output: - print(f'[OK]\t\t{status_message:s}') - - def CheckDependencies(self, verbose_output=True): - """Checks the availability of the dependencies. - - Args: - verbose_output (Optional[bool]): True if output should be verbose. - - Returns: - bool: True if the dependencies are available, False otherwise. - """ - print('Checking availability and versions of dependencies.') - check_result = True - - for _, dependency in sorted(self.dependencies.items()): - if dependency.skip_check: - continue - - result, status_message = self._CheckPythonModule(dependency) - - if not result and not dependency.is_optional: - check_result = False - - self._PrintCheckDependencyStatus( - dependency, result, status_message, verbose_output=verbose_output) - - if check_result and not verbose_output: - print('[OK]') - - print('') - return check_result - - def CheckTestDependencies(self, verbose_output=True): - """Checks the availability of the dependencies when running tests. - - Args: - verbose_output (Optional[bool]): True if output should be verbose. + """Dependency helper. - Returns: - bool: True if the dependencies are available, False otherwise. + Attributes: + dependencies (dict[str, DependencyDefinition]): dependencies. """ - if not self.CheckDependencies(verbose_output=verbose_output): - return False - print('Checking availability and versions of test dependencies.') - check_result = True + _VERSION_NUMBERS_REGEX = re.compile(r"[0-9.]+") + _VERSION_SPLIT_REGEX = re.compile(r"\.|\-") + + def __init__( + self, + dependencies_file="dependencies.ini", + test_dependencies_file="test_dependencies.ini", + ): + """Initializes a dependency helper. + + Args: + dependencies_file (Optional[str]): path to the dependencies configuration + file. + test_dependencies_file (Optional[str]): path to the test dependencies + configuration file. + """ + super().__init__() + self._test_dependencies = {} + self.dependencies = {} + + dependency_reader = DependencyDefinitionReader() + + with open(dependencies_file, "r", encoding="utf-8") as file_object: + for dependency in dependency_reader.Read(file_object): + self.dependencies[dependency.name] = dependency + + if os.path.exists(test_dependencies_file): + with open(test_dependencies_file, "r", encoding="utf-8") as file_object: + for dependency in dependency_reader.Read(file_object): + self._test_dependencies[dependency.name] = dependency + + def _CheckPythonModule(self, dependency): + """Checks the availability of a Python module. + + Args: + dependency (DependencyDefinition): dependency definition. + + Returns: + tuple: containing: + + bool: True if the Python module is available and conforms to + the minimum required version, False otherwise. + str: status message. + """ + module_object = self._ImportPythonModule(dependency.name) + if not module_object: + return False, f"missing: {dependency.name:s}" + + if not dependency.version_property: + return True, dependency.name + + return self._CheckPythonModuleVersion( + dependency.name, + module_object, + dependency.version_property, + dependency.minimum_version, + dependency.maximum_version, + ) + + def _CheckPythonModuleVersion( + self, + module_name, + module_object, + version_property, + minimum_version, + maximum_version, + ): + """Checks the version of a Python module. + + Args: + module_object (module): Python module. + module_name (str): name of the Python module. + version_property (str): version attribute or function. + minimum_version (str): minimum version. + maximum_version (str): maximum version. + + Returns: + tuple: containing: + + bool: True if the Python module is available and conforms to + the minimum required version, False otherwise. + str: status message. + """ + module_version = None + if not version_property.endswith("()"): + module_version = getattr(module_object, version_property, None) + else: + version_method = getattr(module_object, version_property[:-2], None) + if version_method: + module_version = version_method() + + if not module_version: + return False, ( + f"unable to determine version information for: {module_name:s}" + ) + + # Make sure the module version is a string. + module_version = f"{module_version!s}" + + # Split the version string and convert every digit into an integer. + # A string compare of both version strings will yield an incorrect result. + + # Strip any semantic suffixes such as a1, b1, pre, post, rc, dev. + module_version = self._VERSION_NUMBERS_REGEX.findall(module_version)[0] + + if module_version[-1] == ".": + module_version = module_version[:-1] + + try: + module_version_map = list( + map(int, self._VERSION_SPLIT_REGEX.split(module_version)) + ) + except ValueError: + return False, ( + f"unable to parse module version: {module_name:s} {module_version:s}" + ) + + if minimum_version: + try: + minimum_version_map = list( + map(int, self._VERSION_SPLIT_REGEX.split(minimum_version)) + ) + except ValueError: + return False, ( + f"unable to parse minimum version: {module_name:s} " + f"{minimum_version:s}" + ) + + if module_version_map < minimum_version_map: + return False, ( + f"{module_name:s} version: {module_version!s} is too old, " + f"{minimum_version!s} or later required" + ) + + if maximum_version: + try: + maximum_version_map = list( + map(int, self._VERSION_SPLIT_REGEX.split(maximum_version)) + ) + except ValueError: + return False, ( + f"unable to parse maximum version: {module_name:s} " + f"{maximum_version:s}" + ) + + if module_version_map > maximum_version_map: + return False, ( + f"{module_name:s} version: {module_version!s} is too recent, " + f"{maximum_version!s} or earlier required" + ) + + return True, f"{module_name:s} version: {module_version!s}" + + def _ImportPythonModule(self, module_name): + """Imports a Python module. + + Args: + module_name (str): name of the module. + + Returns: + module: Python module or None if the module cannot be imported. + """ + try: + module_object = list(map(__import__, [module_name]))[0] + except ImportError: + return None + + # If the module name contains dots get the upper most module object. + if "." in module_name: + for submodule_name in module_name.split(".")[1:]: + module_object = getattr(module_object, submodule_name, None) + + return module_object + + def _PrintCheckDependencyStatus( + self, dependency, result, status_message, verbose_output=True + ): + """Prints the check dependency status. + + Args: + dependency (DependencyDefinition): dependency definition. + result (bool): True if the Python module is available and conforms to + the minimum required version, False otherwise. + status_message (str): status message. + verbose_output (Optional[bool]): True if output should be verbose. + """ + if not result or dependency.is_optional: + if dependency.is_optional: + status_indicator = "[OPTIONAL]" + else: + status_indicator = "[FAILURE]" + + print(f"{status_indicator:s}\t{status_message:s}") + + elif verbose_output: + print(f"[OK]\t\t{status_message:s}") + + def CheckDependencies(self, verbose_output=True): + """Checks the availability of the dependencies. + + Args: + verbose_output (Optional[bool]): True if output should be verbose. + + Returns: + bool: True if the dependencies are available, False otherwise. + """ + print("Checking availability and versions of dependencies.") + check_result = True + + for _, dependency in sorted(self.dependencies.items()): + if dependency.skip_check: + continue + + result, status_message = self._CheckPythonModule(dependency) + + if not result and not dependency.is_optional: + check_result = False + + self._PrintCheckDependencyStatus( + dependency, result, status_message, verbose_output=verbose_output + ) + + if check_result and not verbose_output: + print("[OK]") + + print("") + return check_result + + def CheckTestDependencies(self, verbose_output=True): + """Checks the availability of the dependencies when running tests. + + Args: + verbose_output (Optional[bool]): True if output should be verbose. + + Returns: + bool: True if the dependencies are available, False otherwise. + """ + if not self.CheckDependencies(verbose_output=verbose_output): + return False + + print("Checking availability and versions of test dependencies.") + check_result = True - for dependency in sorted( - self._test_dependencies.values(), - key=lambda dependency: dependency.name): - if dependency.skip_check: - continue + for dependency in sorted( + self._test_dependencies.values(), key=lambda dependency: dependency.name + ): + if dependency.skip_check: + continue - result, status_message = self._CheckPythonModule(dependency) + result, status_message = self._CheckPythonModule(dependency) - if not result and not dependency.is_optional: - check_result = False + if not result and not dependency.is_optional: + check_result = False - self._PrintCheckDependencyStatus( - dependency, result, status_message, verbose_output=verbose_output) + self._PrintCheckDependencyStatus( + dependency, result, status_message, verbose_output=verbose_output + ) - if check_result and not verbose_output: - print('[OK]') + if check_result and not verbose_output: + print("[OK]") - print('') - return check_result + print("") + return check_result diff --git a/utils/update_release.sh b/utils/update_release.sh index 86433f7..cfc7d14 100755 --- a/utils/update_release.sh +++ b/utils/update_release.sh @@ -9,7 +9,7 @@ EXIT_SUCCESS=0 VERSION=$(date -u +"%Y%m%d") # Update the Python module version. -sed "s/__version__ = '[0-9]*'/__version__ = '${VERSION}'/" -i dfdatetime/__init__.py +sed "s/__version__ = \"[0-9]*\"/__version__ = \"${VERSION}\"/" -i dfdatetime/__init__.py # Update the version in the pyproject configuration. sed "s/version = \"[0-9]*\"/version = \"${VERSION}\"/" -i pyproject.toml