Codebase list dfdatetime / 3932ef2
New upstream release. Debian Janitor 2 years ago
46 changed file(s) with 1236 addition(s) and 153 deletion(s). Raw diff Collapse all Expand all
55 runs-on: ubuntu-latest
66 strategy:
77 matrix:
8 version: ['32', '33', '34']
8 version: ['34', '35']
99 container:
1010 image: registry.fedoraproject.org/fedora:${{ matrix.version }}
1111 steps:
1616 - name: Install dependencies
1717 run: |
1818 dnf copr -y enable @gift/dev
19 dnf install -y python3 python3-mock python3-pbr python3-setuptools python3-six
19 dnf install -y @development-tools python3 python3-devel python3-mock python3-pbr python3-setuptools python3-six
2020 - name: Run tests
2121 env:
2222 LANG: C.utf8
5656 run: |
5757 add-apt-repository -y ppa:gift/dev
5858 apt-get update -q
59 apt-get install -y python3 python3-distutils python3-mock python3-pbr python3-setuptools python3-six
59 apt-get install -y build-essential python3 python3-dev python3-distutils python3-mock python3-pbr python3-setuptools python3-six
6060 - name: Run tests
6161 env:
6262 LANG: en_US.UTF-8
00 # Run tox tests on Ubuntu Docker images using GIFT PPA
11 name: test_tox
2 on: [push, pull_request]
2 on:
3 pull_request:
4 branches:
5 - main
6 push:
7 branches:
8 - main
39 jobs:
410 build:
511 runs-on: ubuntu-latest
612 strategy:
713 matrix:
814 include:
9 - python-version: 3.6
15 - python-version: '3.6'
1016 toxenv: 'py36'
11 - python-version: 3.7
17 - python-version: '3.7'
1218 toxenv: 'py37'
13 - python-version: 3.8
19 - python-version: '3.8'
1420 toxenv: 'py38,coverage,codecov'
15 - python-version: 3.8
21 - python-version: '3.9'
22 toxenv: 'py39'
23 - python-version: '3.10'
24 toxenv: 'py310'
25 - python-version: '3.8'
1626 toxenv: 'pylint'
17 - python-version: 3.8
27 - python-version: '3.8'
1828 toxenv: 'docs'
1929 container:
2030 image: ubuntu:20.04
3646 add-apt-repository -y ppa:deadsnakes/ppa
3747 add-apt-repository -y ppa:gift/dev
3848 apt-get update -q
39 apt-get install -y build-essential git python${{ matrix.python-version }} python${{ matrix.python-version }}-dev tox python3-distutils python3-mock python3-pbr python3-setuptools python3-six
49 apt-get install -y build-essential git libffi-dev python${{ matrix.python-version }} python${{ matrix.python-version }}-dev python${{ matrix.python-version }}-venv python3-distutils python3-mock python3-pbr python3-pip python3-setuptools python3-six
50 - name: Install tox
51 run: |
52 python3 -m pip install tox
4053 - name: Run tests
4154 env:
4255 LANG: en_US.UTF-8
0 # Pylint 2.6.x configuration file
0 # Pylint 2.9.x configuration file
11 #
22 # This file is generated by l2tdevtools update-dependencies.py, any dependency
33 # related changes should be made in dependencies.ini.
66 # A comma-separated list of package or module names from where C extensions may
77 # be loaded. Extensions are loading into the active Python interpreter and may
88 # run arbitrary code.
9 extension-pkg-allow-list=
10
11 # A comma-separated list of package or module names from where C extensions may
12 # be loaded. Extensions are loading into the active Python interpreter and may
13 # run arbitrary code. (This is an alternative name to extension-pkg-allow-list
14 # for backward compatibility.)
915 extension-pkg-whitelist=
16
17 # Return non-zero exit code if any of these messages/categories are detected,
18 # even if score is above --fail-under value. Syntax same as enable. Messages
19 # specified are enabled, while categories only check already-enabled messages.
20 fail-on=
1021
1122 # Specify a score threshold to be exceeded before program exits with error.
1223 fail-under=10.0
1324
14 # Add files or directories to the blacklist. They should be base names, not
15 # paths.
25 # Files or directories to be skipped. They should be base names, not paths.
1626 ignore=CVS
1727
18 # Add files or directories matching the regex patterns to the blacklist. The
19 # regex matches against base names, not paths.
28 # Add files or directories matching the regex patterns to the ignore-list. The
29 # regex matches against paths.
30 ignore-paths=
31
32 # Files or directories matching the regex patterns are skipped. The regex
33 # matches against base names, not paths.
2034 ignore-patterns=
2135
2236 # Python code to execute, usually for sys.path manipulation such as
101115 # either give multiple identifier separated by comma (,) or put this option
102116 # multiple time (only on the command line, not in the configuration file where
103117 # it should appear only once). See also the "--disable" option for examples.
104 enable=
118 enable=c-extension-no-member
105119
106120
107121 [REPORTS]
138152 # inconsistent-return-statements if a never returning function is called then
139153 # it will be considered as an explicit return statement and no message will be
140154 # printed.
141 never-returning-functions=sys.exit
155 never-returning-functions=sys.exit,argparse.parse_error
142156
143157
144158 [VARIABLES]
149163
150164 # Tells whether unused global variables should be treated as a violation.
151165 allow-global-unused-variables=yes
166
167 # List of names allowed to shadow builtins
168 allowed-redefined-builtins=
152169
153170 # List of strings which can identify a callback function by name. A callback
154171 # name must start or end with one of those strings.
271288 # Regular expression matching correct class attribute names. Overrides class-
272289 # attribute-naming-style.
273290 class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]*|(__.*__))$
291
292 # Naming style matching correct class constant names.
293 class-const-naming-style=UPPER_CASE
294
295 # Regular expression matching correct class constant names. Overrides class-
296 # const-naming-style.
297 #class-const-rgx=
274298
275299 # Naming style matching correct class names.
276300 class-naming-style=PascalCase
409433 # (hunspell), en_ZM (hunspell), en_ZW (hunspell).
410434 spelling-dict=
411435
436 # List of comma separated words that should be considered directives if they
437 # appear and the beginning of a comment and should not be checked.
438 spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
439
412440 # List of comma separated words that should not be checked.
413441 spelling-ignore-words=
414442
431459 # Ignore imports when computing similarities.
432460 ignore-imports=no
433461
462 # Ignore function signatures when computing similarities.
463 ignore-signatures=no
464
434465 # Minimum lines number of a similarity.
435466 min-similarity-lines=4
436467
480511
481512
482513 [CLASSES]
514
515 # Warn about protected attribute access inside special methods
516 check-protected-access-in-special-methods=no
483517
484518 # List of method names used to declare (i.e. assign) instance attributes.
485519 defining-attr-methods=__init__,
519553 # Deprecated modules which should not be used, separated by a comma.
520554 deprecated-modules=optparse,tkinter.tix
521555
522 # Create a graph of external dependencies in the given file (report RP0402 must
523 # not be disabled).
556 # Output a graph (.gv or any supported image format) of external dependencies
557 # to the given file (report RP0402 must not be disabled).
524558 ext-import-graph=
525559
526 # Create a graph of every (i.e. internal and external) dependencies in the
527 # given file (report RP0402 must not be disabled).
560 # Output a graph (.gv or any supported image format) of all (i.e. internal and
561 # external) dependencies to the given file (report RP0402 must not be
562 # disabled).
528563 import-graph=
529564
530 # Create a graph of internal dependencies in the given file (report RP0402 must
531 # not be disabled).
565 # Output a graph (.gv or any supported image format) of internal dependencies
566 # to the given file (report RP0402 must not be disabled).
532567 int-import-graph=
533568
534569 # Force import order to recognize a module as part of the standard
540575
541576 # Couples of modules and preferred modules, separated by a comma.
542577 preferred-modules=
543
544
545 [PARAMETER_DOCUMENTATION]
546
547 # Whether to accept totally missing parameter documentation in the docstring of
548 # a function that has parameters.
549 accept-no-param-doc=yes
550
551 # Whether to accept totally missing raises documentation in the docstring of a
552 # function that raises an exception.
553 accept-no-raise-doc=yes
554
555 # Whether to accept totally missing return documentation in the docstring of a
556 # function that returns a statement.
557 accept-no-return-doc=yes
558
559 # Whether to accept totally missing yields documentation in the docstring of a
560 # generator.
561 accept-no-yields-doc=yes
562
563 # If the docstring type cannot be guessed the specified docstring type will be
564 # used.
565 default-docstring-type=default
566578
567579
568580 [EXCEPTIONS]
00 include ACKNOWLEDGEMENTS AUTHORS LICENSE README
11 include dependencies.ini run_tests.py utils/__init__.py utils/dependencies.py
22 include utils/check_dependencies.py
3 include requirements.txt test_requirements.txt
34 exclude .gitignore
45 exclude *.pyc
56 recursive-include config *
00 environment:
1 pypi_token:
1 PYPI_TOKEN:
22 secure: /FwQrmudDyj+Mu3DaxLEo23Y6/OEgdHJqyWyZTjkJKje8pxCOrUorN8ZlXRGXbd3UA60emClt0M+SI+xqyA/qkpqZTgd5CKohpVAGH2EfzRc/zwJSGJ4tmZmMVAG8ayk6N9zFxCeC+y0BgZPQnj/Eq/RfuS4YIuaKutIUa5gTMmhWpODFKGV/2Wx1w67xWxAoONfEC5j0Gu3R274SS7FfBb4qWyIiBIJMwHGjlgp1Onk8KlpCLauZv8/hGfQDmWEdZ+mjcsTYyQYr1xfr1/FjQ==
33 matrix:
4 - DESCRIPTION: "Windows with 32-bit Python 3.9"
4 - DESCRIPTION: "Windows with 32-bit Python 3.10"
55 MACHINE_TYPE: "x86"
66 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
7 PYTHON: "C:\\Python39"
8 PYTHON_VERSION: "3.9"
7 PYTHON: "C:\\Python310"
8 PYTHON_VERSION: "3.10"
99 L2TBINARIES_TRACK: "dev"
10 - DESCRIPTION: "Windows with 64-bit Python 3.9"
10 - DESCRIPTION: "Windows with 64-bit Python 3.10"
1111 MACHINE_TYPE: "amd64"
1212 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
13 PYTHON: "C:\\Python39-x64"
14 PYTHON_VERSION: "3.9"
13 PYTHON: "C:\\Python310-x64"
14 PYTHON_VERSION: "3.10"
1515 L2TBINARIES_TRACK: "dev"
16 - DESCRIPTION: "Mac OS with Python 3.9"
16 - DESCRIPTION: "Mac OS with Python 3.10"
1717 APPVEYOR_BUILD_WORKER_IMAGE: macos
1818 HOMEBREW_NO_INSTALL_CLEANUP: 1
1919
2020 install:
21 - cmd: "%PYTHON%\\python.exe -m pip install -U pip setuptools wheel"
21 - cmd: "%PYTHON%\\python.exe -m pip install -U pip setuptools twine wheel"
2222 - cmd: "%PYTHON%\\python.exe -m pip install pywin32 WMI"
2323 - cmd: "%PYTHON%\\python.exe %PYTHON%\\Scripts\\pywin32_postinstall.py -install"
2424 - ps: If ($isWindows) { .\config\appveyor\install.ps1 }
2525 - sh: config/appveyor/install.sh
2626
2727 build_script:
28 - cmd: "%PYTHON%\\python.exe setup.py bdist_msi bdist_wheel"
28 # Note that bdist_msi will change the version number to work-around limitations
29 # of the MSI version version numbering. Hence a MSI build is done separately
30 # from building the wheel to not influence its version number.
31 - cmd: "%PYTHON%\\python.exe setup.py bdist_msi"
32 - cmd: "%PYTHON%\\python.exe setup.py bdist_wheel"
2933
3034 test_script:
3135 - cmd: "%PYTHON%\\python.exe run_tests.py"
3842 - path: dist\*.whl
3943
4044 deploy_script:
41 - ps: If ($env:APPVEYOR_REPO_TAG -eq "true" -And $isWindows) {
45 - ps: If ($env:APPVEYOR_REPO_TAG -eq "true" -And $isWindows -And $env:MACHINE_TYPE -eq "x86") {
4246 Invoke-Expression "${env:PYTHON}\\python.exe -m twine upload dist/*.whl --username __token__ --password ${env:PYPI_TOKEN} --skip-existing" }
43
55 export LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib ${LDFLAGS}";
66 export TOX_TESTENV_PASSENV="CFLAGS LDFLAGS";
77
8 # Set the following environment variables to ensure tox can find Python 3.9.
9 export PATH="/usr/local/opt/python@3.9/bin:${PATH}";
8 # Set the following environment variables to ensure tox can find Python 3.10.
9 export PATH="/usr/local/opt/python@3.10/bin:${PATH}";
1010
11 tox -e py39
11 tox -e py310
0 dfdatetime (20210509-1) unstable; urgency=low
0 dfdatetime (20220131-1) unstable; urgency=low
11
22 * Auto-generated
33
4 -- Log2Timeline maintainers <log2timeline-maintainers@googlegroups.com> Sun, 09 May 2021 16:27:46 +0200
4 -- Log2Timeline maintainers <log2timeline-maintainers@googlegroups.com> Mon, 31 Jan 2022 12:59:15 +0100
88
99 Package: python3-dfdatetime
1010 Architecture: all
11 Depends: ${python3:Depends}, ${misc:Depends}
11 Depends: ${misc:Depends}
1212 Description: Python 3 module of dfDateTime
1313 dfDateTime, or Digital Forensics date and time, provides date and time objects
1414 to preserve accuracy and precision.
0 dfdatetime (20220131-1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Debian Janitor <janitor@jelmer.uk> Mon, 25 Apr 2022 05:21:56 -0000
5
06 dfdatetime (20210509-1) unstable; urgency=medium
17
28 * Team upload.
1111 from dfdatetime import fat_date_time
1212 from dfdatetime import filetime
1313 from dfdatetime import hfs_time
14 from dfdatetime import golang_time
1415 from dfdatetime import java_time
1516 from dfdatetime import ole_automation_date
1617 from dfdatetime import posix_time
1920 from dfdatetime import systemtime
2021 from dfdatetime import time_elements
2122 from dfdatetime import uuid_time
23 from dfdatetime import webkit_time
2224
23 __version__ = '20210509'
25
26 __version__ = '20220131'
1717 MICROSECONDS_PER_DECISECOND = 100000
1818 MICROSECONDS_PER_MILLISECOND = 1000
1919
20 NANOSECONDS_PER_MICROSECOND = 1000
2021 NANOSECONDS_PER_SECOND = 1000000000
2122
2223 PRECISION_1_DAY = '1d'
2626 9999-12-31 23:59:59.999
2727
2828 Also see:
29 http://docwiki.embarcadero.com/Libraries/XE3/en/System.TDateTime
29 https://docwiki.embarcadero.com/Libraries/XE3/en/System.TDateTime
3030
3131 Attributes:
3232 is_local_time (bool): True if the date and time value is in local time.
6363 if (self._timestamp is not None and self._timestamp >= 0 and
6464 self._timestamp <= self._UINT64_MAX):
6565 self._normalized_timestamp = (
66 decimal.Decimal(self._timestamp) / self._100NS_PER_SECOND)
66 decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND)
6767 self._normalized_timestamp -= self._FILETIME_TO_POSIX_BASE
6868
6969 if self._time_zone_offset:
104104 timestamp += self._FILETIME_TO_POSIX_BASE
105105 timestamp *= definitions.MICROSECONDS_PER_SECOND
106106 timestamp += date_time_values.get('microseconds', 0)
107 timestamp *= self._100NS_PER_MICROSECOND
107 timestamp *= self._100_NANOSECONDS_PER_MICROSECOND
108108
109109 self._normalized_timestamp = None
110110 self._timestamp = timestamp
121121 self._timestamp > self._UINT64_MAX):
122122 return None
123123
124 timestamp, remainder = divmod(self._timestamp, self._100NS_PER_SECOND)
124 timestamp, remainder = divmod(
125 self._timestamp, self._100_NANOSECONDS_PER_SECOND)
125126 number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
126127
127128 year, month, day_of_month = self._GetDateValuesWithEpoch(
0 # -*- coding: utf-8 -*-
1 """Golang time.Time timestamp implementation."""
2
3 import decimal
4 import struct
5
6 from dfdatetime import definitions
7 from dfdatetime import factory
8 from dfdatetime import interface
9
10
11 class GolangTimeEpoch(interface.DateTimeEpoch):
12 """Golang time.Time epoch."""
13
14 def __init__(self):
15 """Initializes a Golang time.Time epoch."""
16 super(GolangTimeEpoch, self).__init__(1, 1, 1)
17
18
19 class GolangTime(interface.DateTimeValues):
20 """Golang time.Time timestamp.
21
22 A Golang time.Time timestamp contans the number of nanoseconds since
23 January 1, 1 UTC. Depending on the version of the timestamp, the time
24 zone is stored in minutes or seconds relative to UTC.
25
26 A serialized version 1 Golang time.Time timestamp is a 15 byte value
27 that consists of:
28
29 * byte 0 - version as an 8-bit integer.
30 * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed
31 integer.
32 * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian
33 signed integer.
34 * bytes 13-14 - time zone offset in minutes as a 16-bit big endian integer,
35 where -1 represents UTC.
36
37 A serialized version 2 Golang time.Time timestamp is a 16 byte value
38 that consists of:
39
40 * byte 0 - version as an 8-bit integer.
41 * bytes 1-8 - number of seconds since January 1, 1 as a big-endian signed
42 integer.
43 * bytes 9-12 - fraction of second, number of nanoseconds as a big-endian
44 signed integer.
45 * bytes 13-14 - time zone offset in minutes as a 16-bit big endian integer,
46 where -1 represents UTC.
47 * byte 15 - time zone offset in seconds as an 8-bit integer.
48
49 Attributes:
50 is_local_time (bool): True if the date and time value is in local time
51 """
52
53 # The delta between January 1, 1970 (unix epoch) and January 1, 1
54 # (Golang epoch).
55 _GOLANG_TO_POSIX_BASE = (
56 ((1969 * 365) + (1969 // 4) - (1969 // 100) + (1969 // 400)) *
57 definitions.SECONDS_PER_DAY)
58
59 _EPOCH = GolangTimeEpoch()
60
61 def __init__(self, golang_timestamp=None):
62 """Initializes a Golang time.Time timestamp.
63
64 Args:
65 golang_timestamp (Optional[bytes]): the Golang time.Time timestamp.
66 """
67 number_of_seconds, nanoseconds, time_zone_offset = (None, None, None)
68 if golang_timestamp is not None:
69 number_of_seconds, nanoseconds, time_zone_offset = (
70 self._GetNumberOfSeconds(golang_timestamp))
71
72 super(GolangTime, self).__init__(time_zone_offset=time_zone_offset)
73 self._golang_timestamp = golang_timestamp
74 self._nanoseconds = nanoseconds
75 self._number_of_seconds = number_of_seconds
76 self._precision = definitions.PRECISION_1_NANOSECOND
77
78 if time_zone_offset:
79 self.is_local_time = True
80
81 @property
82 def golang_timestamp(self):
83 """int: Golang time.Time timestamp or None if not set."""
84 return self._golang_timestamp
85
86 def _GetNormalizedTimestamp(self):
87 """Retrieves the normalized timestamp.
88
89 Returns:
90 decimal.Decimal: normalized timestamp, which contains the number of
91 seconds since January 1, 1970 00:00:00 and a fraction of second used
92 for increased precision, or None if the normalized timestamp cannot be
93 determined.
94 """
95 if self._normalized_timestamp is None:
96 if (self._number_of_seconds is not None and
97 self._number_of_seconds >= self._GOLANG_TO_POSIX_BASE and
98 self._nanoseconds is not None and self._nanoseconds >= 0):
99
100 self._normalized_timestamp = decimal.Decimal(
101 self._number_of_seconds - GolangTime._GOLANG_TO_POSIX_BASE)
102
103 if self._nanoseconds is not None and self._nanoseconds >= 0:
104 self._normalized_timestamp += (
105 decimal.Decimal(self._nanoseconds) /
106 definitions.NANOSECONDS_PER_SECOND)
107
108 return self._normalized_timestamp
109
110 def _GetNumberOfSeconds(self, golang_timestamp):
111 """Retrieves the number of seconds from a Golang time.Time timestamp.
112
113 Args:
114 golang_timestamp (bytes): the Golang time.Time timestamp.
115
116 Returns:
117 tuple[int, int, int]: number of seconds since January 1, 1 00:00:00,
118 fraction of second in nanoseconds and time zone offset in minutes.
119
120 Raises:
121 ValueError: if the Golang time.Time timestamp could not be parsed.
122 """
123 byte_size = len(golang_timestamp)
124 if byte_size < 15:
125 raise ValueError('Unsupported Golang time.Time timestamp.')
126
127 version = golang_timestamp[0]
128 if version not in (1, 2):
129 raise ValueError(
130 'Unsupported Golang time.Time timestamp version: {0:d}.'.format(
131 version))
132
133 if (version == 1 and byte_size != 15) or (version == 2 and byte_size != 16):
134 raise ValueError('Unsupported Golang time.Time timestamp.')
135
136 try:
137 number_of_seconds, nanoseconds, time_zone_offset = struct.unpack(
138 '>qih', golang_timestamp[1:15])
139
140 # TODO: add support for version 2 time zone offset in seconds
141
142 except struct.error as exception:
143 raise ValueError((
144 'Unable to unpacke Golang time.Time timestamp with error: '
145 '{0:s}').format(exception))
146
147 # A time zone offset of -1 minute is a special representation for UTC.
148 if time_zone_offset == -1:
149 time_zone_offset = 0
150
151 return number_of_seconds, nanoseconds, time_zone_offset
152
153 def CopyFromDateTimeString(self, time_string):
154 """Copies a date time value from a date and time string.
155
156 Args:
157 time_string (str): date and time value formatted as:
158 YYYY-MM-DD hh:mm:ss.######[+-]##:##
159
160 Where # are numeric digits ranging from 0 to 9 and the seconds
161 fraction can be either 3 or 6 digits. The time of day, seconds
162 fraction and time zone offset are optional. The default time zone
163 is UTC.
164
165 Raises:
166 ValueError: if the time string is invalid or not supported.
167 """
168 date_time_values = self._CopyDateTimeFromString(time_string)
169 year = date_time_values.get('year', 0)
170 month = date_time_values.get('month', 0)
171 day_of_month = date_time_values.get('day_of_month', 0)
172 hours = date_time_values.get('hours', 0)
173 minutes = date_time_values.get('minutes', 0)
174 seconds = date_time_values.get('seconds', 0)
175 microseconds = date_time_values.get('microseconds', 0)
176 time_zone_offset = date_time_values.get('time_zone_offset', 0)
177
178 if year < 0:
179 raise ValueError('Year value not supported: {0!s}.'.format(year))
180
181 seconds = self._GetNumberOfSecondsFromElements(
182 year, month, day_of_month, hours, minutes, seconds)
183
184 seconds += self._GOLANG_TO_POSIX_BASE
185 nanoseconds = microseconds * definitions.NANOSECONDS_PER_MICROSECOND
186
187 self._normalized_timestamp = None
188 self._number_of_seconds = seconds
189 self._nanoseconds = nanoseconds
190 self._time_zone_offset = time_zone_offset
191
192 def CopyToDateTimeString(self):
193 """Copies the Golang time value to a date and time string.
194
195 Returns:
196 str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or
197 None if the timestamp cannot be copied to a date and time string.
198 """
199 if self._number_of_seconds is None or self._number_of_seconds < 0:
200 return None
201
202 seconds = self._number_of_seconds
203 nanoseconds_seconds, remainder = divmod(
204 self._nanoseconds, definitions.NANOSECONDS_PER_SECOND)
205
206 seconds += nanoseconds_seconds
207 remainder = remainder // definitions.NANOSECONDS_PER_MICROSECOND
208 number_of_days, hours, minutes, seconds = self._GetTimeValues(seconds)
209
210 year, month, day_of_month = self._GetDateValuesWithEpoch(
211 number_of_days, self._EPOCH)
212
213 return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'.format(
214 year, month, day_of_month, hours, minutes, seconds, remainder)
215
216
217 factory.Factory.RegisterDateTimeValues(GolangTime)
6060
6161 _EPOCH_NORMALIZED_TIME = NormalizedTimeEpoch()
6262
63 _100NS_PER_SECOND = 10000000
64 _100NS_PER_DECISECOND = 1000000
65 _100NS_PER_MILLISECOND = 10000
66 _100NS_PER_MICROSECOND = 10
63 _100_MILLISECONDS_PER_SECOND = 10
64 _100_NANOSECONDS_PER_SECOND = 10000000
65 _100_NANOSECONDS_PER_MICROSECOND = 10
6766
6867 _INT64_MIN = -(1 << 63)
6968 _INT64_MAX = (1 << 63) - 1
8079 from UTC or None if not set.
8180 """
8281 super(DateTimeValues, self).__init__()
82 self._cached_date_time_values = None
8383 self._normalized_timestamp = None
8484 self._precision = None
8585 self._time_zone_offset = time_zone_offset
601601 number_of_days, date_time_epoch.year, date_time_epoch.month,
602602 date_time_epoch.day_of_month)
603603
604 def _GetDateWithTimeOfDay(self):
605 """Retrieves the date with time of day.
606
607 Note that the date and time are adjusted to UTC.
608
609 Returns:
610 tuple[int, int, int, int, int, int]: year, month, day of month, hours,
611 minutes, seconds or (None, None, None, None, None, None)
612 if the date and time values do not represent a date or time of day.
613 """
614 normalized_timestamp = self._GetNormalizedTimestamp()
615 if normalized_timestamp is None:
616 return None, None, None, None, None, None
617
618 if (not self._cached_date_time_values or
619 self._cached_date_time_values[0] != normalized_timestamp):
620 number_of_days, hours, minutes, seconds = self._GetTimeValues(
621 normalized_timestamp)
622
623 try:
624 year, month, day_of_month = self._GetDateValuesWithEpoch(
625 number_of_days, self._EPOCH_NORMALIZED_TIME)
626
627 except ValueError:
628 return None, None, None, None, None, None
629
630 self._cached_date_time_values = (
631 normalized_timestamp, year, month, day_of_month, hours, minutes,
632 seconds)
633
634 return self._cached_date_time_values[1:]
635
604636 def _GetDayOfYear(self, year, month, day_of_month):
605637 """Retrieves the day of the year for a specific day of a month in a year.
606638
821853
822854 return int(normalized_timestamp)
823855
856 def CopyToPosixTimestampWithFractionOfSecond(self):
857 """Copies the date time value to a POSIX timestamp with fraction of second.
858
859 Returns:
860 tuple[int, int]: a POSIX timestamp in seconds with fraction of second or
861 None, None if no timestamp is available.
862 """
863 normalized_timestamp = self._GetNormalizedTimestamp()
864 if normalized_timestamp is None:
865 return None, None
866
867 remainder = None
868 if self._precision == definitions.PRECISION_1_NANOSECOND:
869 remainder = int(
870 (normalized_timestamp % 1) * definitions.NANOSECONDS_PER_SECOND)
871 elif self._precision == definitions.PRECISION_100_NANOSECONDS:
872 remainder = int(
873 (normalized_timestamp % 1) * self._100_NANOSECONDS_PER_SECOND)
874 elif self._precision == definitions.PRECISION_1_MICROSECOND:
875 remainder = int(
876 (normalized_timestamp % 1) * definitions.MICROSECONDS_PER_SECOND)
877 elif self._precision == definitions.PRECISION_1_MILLISECOND:
878 remainder = int(
879 (normalized_timestamp % 1) * definitions.MILLISECONDS_PER_SECOND)
880 elif self._precision == definitions.PRECISION_100_MILLISECONDS:
881 remainder = int(
882 (normalized_timestamp % 1) * self._100_MILLISECONDS_PER_SECOND)
883
884 return int(normalized_timestamp), remainder
885
824886 # TODO: remove this method when there is no more need for it in dfvfs.
825887 def CopyToStatTimeTuple(self):
826888 """Copies the date time value to a stat timestamp tuple.
839901 definitions.PRECISION_1_MICROSECOND,
840902 definitions.PRECISION_1_MILLISECOND,
841903 definitions.PRECISION_100_MILLISECONDS):
842 remainder = int((normalized_timestamp % 1) * self._100NS_PER_SECOND)
904 remainder = int(
905 (normalized_timestamp % 1) * self._100_NANOSECONDS_PER_SECOND)
843906
844907 return int(normalized_timestamp), remainder
845908
864927 date_time_string = self.CopyToDateTimeString()
865928 if date_time_string:
866929 date_time_string = date_time_string.replace(' ', 'T')
867 date_time_string = '{0:s}Z'.format(date_time_string)
930
931 if self._time_zone_offset is not None or not self.is_local_time:
932 time_zone_offset_hours, time_zone_offset_minutes = divmod(
933 self._time_zone_offset or 0, 60)
934 if time_zone_offset_hours > 0:
935 time_zone_offset_sign = '-'
936 else:
937 time_zone_offset_sign = '+'
938 time_zone_offset_hours *= -1
939
940 date_time_string = '{0:s}{1:s}{2:02d}:{3:02d}'.format(
941 date_time_string, time_zone_offset_sign, time_zone_offset_hours,
942 time_zone_offset_minutes)
943
868944 return date_time_string
869945
870946 def GetDate(self):
871947 """Retrieves the date represented by the date and time values.
872948
949 Note that the date is adjusted to UTC.
950
873951 Returns:
874952 tuple[int, int, int]: year, month, day of month or (None, None, None)
875953 if the date and time values do not represent a date.
876954 """
877 normalized_timestamp = self._GetNormalizedTimestamp()
878 if normalized_timestamp is None:
879 return None, None, None
880
881 number_of_days, _, _, _ = self._GetTimeValues(normalized_timestamp)
882
883 try:
884 return self._GetDateValuesWithEpoch(
885 number_of_days, self._EPOCH_NORMALIZED_TIME)
886
887 except ValueError:
888 return None, None, None
955 year, month, day_of_month, _, _, _ = self._GetDateWithTimeOfDay()
956 return year, month, day_of_month
889957
890958 def GetDateWithTimeOfDay(self):
891959 """Retrieves the date with time of day.
960
961 Note that the date and time are adjusted to UTC.
892962
893963 Returns:
894964 tuple[int, int, int, int, int, int]: year, month, day of month, hours,
895965 minutes, seconds or (None, None, None, None, None, None)
896966 if the date and time values do not represent a date or time of day.
897967 """
898 normalized_timestamp = self._GetNormalizedTimestamp()
899 if normalized_timestamp is None:
900 return None, None, None, None, None, None
901
902 number_of_days, hours, minutes, seconds = self._GetTimeValues(
903 normalized_timestamp)
904
905 try:
906 year, month, day_of_month = self._GetDateValuesWithEpoch(
907 number_of_days, self._EPOCH_NORMALIZED_TIME)
908
909 except ValueError:
910 return None, None, None, None, None, None
911
912 return year, month, day_of_month, hours, minutes, seconds
968 return self._GetDateWithTimeOfDay()
913969
914970 # TODO: remove this method when there is no more need for it in plaso.
915971 def GetPlasoTimestamp(self):
916 """Retrieves a timestamp that is compatible with plaso.
972 """Retrieves a timestamp that is compatible with Plaso.
917973
918974 Returns:
919975 int: a POSIX timestamp in microseconds or None if no timestamp is
931987 def GetTimeOfDay(self):
932988 """Retrieves the time of day represented by the date and time values.
933989
990 Note that the time is adjusted to UTC.
991
934992 Returns:
935993 tuple[int, int, int]: hours, minutes, seconds or (None, None, None)
936994 if the date and time values do not represent a time of day.
937995 """
938 normalized_timestamp = self._GetNormalizedTimestamp()
939 if normalized_timestamp is None:
940 return None, None, None
941
942 _, hours, minutes, seconds = self._GetTimeValues(normalized_timestamp)
996 _, _, _, hours, minutes, seconds = self._GetDateWithTimeOfDay()
943997 return hours, minutes, seconds
2626 }
2727
2828 Also see:
29 https://tools.ietf.org/html/rfc2579
29 https://datatracker.ietf.org/doc/html/rfc2579
3030
3131 Attributes:
3232 year (int): year, 0 through 65536.
0 # -*- coding: utf-8 -*-
1 """The date and time values serializer."""
2
3 from dfdatetime import factory
4 from dfdatetime import interface
5
6
7 class Serializer(object):
8 """Date and time values serializer."""
9
10 @classmethod
11 def ConvertDictToDateTimeValues(cls, json_dict):
12 """Converts a JSON dict into a date time values object.
13
14 This method is deprecated use ConvertJSONToDateTimeValues instead.
15
16 The dictionary of the JSON serialized objects consists of:
17 {
18 '__type__': 'DateTimeValues'
19 '__class_name__': 'RFC2579DateTime'
20 ...
21 }
22
23 Here '__type__' indicates the object base type. In this case this should
24 be 'DateTimeValues'. The rest of the elements of the dictionary make up the
25 date time values object properties.
26
27 Args:
28 json_dict (dict[str, object]): JSON serialized objects.
29
30 Returns:
31 dfdatetime.DateTimeValues: date and time values.
32 """
33 return cls.ConvertJSONToDateTimeValues(json_dict)
34
35 @classmethod
36 def ConvertDateTimeValuesToDict(cls, date_time_values):
37 """Converts a date and time values object into a JSON dictionary.
38
39 This method is deprecated use ConvertDateTimeValuesToJSON instead.
40
41 The resulting dictionary of the JSON serialized objects consists of:
42 {
43 '__type__': 'DateTimeValues'
44 '__class_name__': 'RFC2579DateTime'
45 ...
46 }
47
48 Here '__type__' indicates the object base type. In this case
49 'DateTimeValues'. The rest of the elements of the dictionary make up the
50 date and time value object properties.
51
52 Args:
53 date_time_values (dfdatetime.DateTimeValues): date and time values.
54
55 Returns:
56 dict[str, object]: JSON serialized objects.
57
58 Raises:
59 TypeError: if object is not an instance of DateTimeValues.
60 """
61 if not isinstance(date_time_values, interface.DateTimeValues):
62 raise TypeError
63
64 return cls.ConvertDateTimeValuesToJSON(date_time_values)
65
66 @classmethod
67 def ConvertDateTimeValuesToJSON(cls, date_time_values):
68 """Converts a date and time values object into a JSON dictionary.
69
70 The resulting dictionary of the JSON serialized objects consists of:
71 {
72 '__type__': 'DateTimeValues'
73 '__class_name__': 'RFC2579DateTime'
74 ...
75 }
76
77 Here '__type__' indicates the object base type. In this case
78 'DateTimeValues'. The rest of the elements of the dictionary make up the
79 date and time value object properties.
80
81 Args:
82 date_time_values (dfdatetime.DateTimeValues): date and time values.
83
84 Returns:
85 dict[str, object]: JSON serialized objects.
86 """
87 class_name = type(date_time_values).__name__
88
89 json_dict = {
90 '__class_name__': class_name,
91 '__type__': 'DateTimeValues'}
92
93 if hasattr(date_time_values, 'timestamp'):
94 json_dict['timestamp'] = date_time_values.timestamp
95
96 elif hasattr(date_time_values, 'string'):
97 json_dict['string'] = date_time_values.string
98
99 elif class_name == 'FATDateTime':
100 json_dict['fat_date_time'] = date_time_values.fat_date_time
101
102 elif class_name == 'GolangTime':
103 json_dict['golang_timestamp'] = date_time_values.golang_timestamp
104
105 elif class_name == 'RFC2579DateTime':
106 json_dict['rfc2579_date_time_tuple'] = (
107 date_time_values.year, date_time_values.month,
108 date_time_values.day_of_month, date_time_values.hours,
109 date_time_values.minutes, date_time_values.seconds,
110 date_time_values.deciseconds)
111
112 elif class_name == 'TimeElements':
113 json_dict['time_elements_tuple'] = (
114 date_time_values.year, date_time_values.month,
115 date_time_values.day_of_month, date_time_values.hours,
116 date_time_values.minutes, date_time_values.seconds)
117
118 elif class_name == 'TimeElementsInMilliseconds':
119 json_dict['time_elements_tuple'] = (
120 date_time_values.year, date_time_values.month,
121 date_time_values.day_of_month, date_time_values.hours,
122 date_time_values.minutes, date_time_values.seconds,
123 date_time_values.milliseconds)
124
125 elif class_name == 'TimeElementsInMicroseconds':
126 json_dict['time_elements_tuple'] = (
127 date_time_values.year, date_time_values.month,
128 date_time_values.day_of_month, date_time_values.hours,
129 date_time_values.minutes, date_time_values.seconds,
130 date_time_values.microseconds)
131
132 if date_time_values.time_zone_offset is not None:
133 json_dict['time_zone_offset'] = date_time_values.time_zone_offset
134
135 if date_time_values.is_local_time:
136 json_dict['is_local_time'] = True
137
138 return json_dict
139
140 @classmethod
141 def ConvertJSONToDateTimeValues(cls, json_dict):
142 """Converts a JSON dict into a date time values object.
143
144 The dictionary of the JSON serialized objects consists of:
145 {
146 '__type__': 'DateTimeValues'
147 '__class_name__': 'RFC2579DateTime'
148 ...
149 }
150
151 Here '__type__' indicates the object base type. In this case this should
152 be 'DateTimeValues'. The rest of the elements of the dictionary make up the
153 date time values object properties.
154
155 Args:
156 json_dict (dict[str, object]): JSON serialized objects.
157
158 Returns:
159 dfdatetime.DateTimeValues: date and time values.
160 """
161 class_name = json_dict.get('__class_name__', None)
162 if class_name:
163 del json_dict['__class_name__']
164
165 # Remove the class type from the JSON dict since we cannot pass it.
166 del json_dict['__type__']
167
168 is_local_time = json_dict.get('is_local_time', None)
169 if is_local_time is not None:
170 del json_dict['is_local_time']
171
172 if class_name in ('InvalidTime', 'Never', 'NotSet'):
173 string = json_dict.get('string', None)
174 if string is not None:
175 del json_dict['string']
176
177 date_time = factory.Factory.NewDateTimeValues(class_name, **json_dict)
178 if is_local_time:
179 date_time.is_local_time = is_local_time
180
181 return date_time
378378 ValueError: if the time string is invalid or not supported.
379379 """
380380 if time_string.endswith('Z'):
381 time_string = time_string[:-1]
381 time_string = ''.join([time_string[:-1], '+00:00'])
382382
383383 time_string_length = len(time_string)
384384
6868 if (self._timestamp is not None and self._timestamp >= 0 and
6969 self._timestamp <= self._UINT60_MAX):
7070 self._normalized_timestamp = (
71 decimal.Decimal(self._timestamp) / self._100NS_PER_SECOND)
71 decimal.Decimal(self._timestamp) / self._100_NANOSECONDS_PER_SECOND)
7272 self._normalized_timestamp -= self._UUID_TO_POSIX_BASE
7373
7474 if self._time_zone_offset:
109109 timestamp += self._UUID_TO_POSIX_BASE
110110 timestamp *= definitions.MICROSECONDS_PER_SECOND
111111 timestamp += date_time_values.get('microseconds', 0)
112 timestamp *= self._100NS_PER_MICROSECOND
112 timestamp *= self._100_NANOSECONDS_PER_MICROSECOND
113113
114114 self._normalized_timestamp = None
115115 self._timestamp = timestamp
126126 self._timestamp > self._UINT60_MAX):
127127 return None
128128
129 timestamp, remainder = divmod(self._timestamp, self._100NS_PER_SECOND)
129 timestamp, remainder = divmod(
130 self._timestamp, self._100_NANOSECONDS_PER_SECOND)
130131 number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
131132
132133 year, month, day_of_month = self._GetDateValuesWithEpoch(
77 description_short: Digital Forensics date and time (dfDateTime).
88 description_long: dfDateTime, or Digital Forensics date and time, provides date and time objects
99 to preserve accuracy and precision.
10 pypi_token: /FwQrmudDyj+Mu3DaxLEo23Y6/OEgdHJqyWyZTjkJKje8pxCOrUorN8ZlXRGXbd3UA60emClt0M+SI+xqyA/qkpqZTgd5CKohpVAGH2EfzRc/zwJSGJ4tmZmMVAG8ayk6N9zFxCeC+y0BgZPQnj/Eq/RfuS4YIuaKutIUa5gTMmhWpODFKGV/2Wx1w67xWxAoONfEC5j0Gu3R274SS7FfBb4qWyIiBIJMwHGjlgp1Onk8KlpCLauZv8/hGfQDmWEdZ+mjcsTYyQYr1xfr1/FjQ==
11
5757 # General information about the project.
5858 # pylint: disable=redefined-builtin
5959 project = 'dfDateTime'
60 copyright = 'The dfDateTime Project Authors'
60 copyright = 'The dfDateTime authors'
6161 version = dfdatetime.__version__
6262 release = dfdatetime.__version__
6363
2626
2727 * :ref:`genindex`
2828 * :ref:`modindex`
29 * :ref:`search`
3029
00 docutils
11 recommonmark
2 sphinx >= 2.0.1
2 sphinx >= 4.1.0
33 sphinx-markdown-tables
44 sphinx-rtd-theme >= 0.5.1
123123
124124 ### Also see
125125
126 * [Embarcadero: System.TDateTime](http://docwiki.embarcadero.com/Libraries/XE3/en/System.TDateTime)
126 * [Embarcadero: System.TDateTime](https://docwiki.embarcadero.com/Libraries/XE3/en/System.TDateTime)
127127
128128 ## FAT date and time
129129 ### Characteristics
196196
197197 * [MSDN: FILETIME](https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime)
198198
199 ## Golang time.Time timestamp
200
201 ### Characteristics
202
203 Attribute | Description
204 --- | ---
205 Supported date range | 0001-01-01 00:00:00.0000000 through ...
206 Storage granularity | 1 nanosecond
207 Time zone | internally represented.
208
209 The granularity of the time zone value depends on the version of the timestamp.
210 Version 1 timestamps are stored in minutes and version 2 timestamps add a
211 seconds component. *Note: Version 2 is currently not supported.*
212
213 ### Format
214
215 Offset | Size | Description
216 --- | --- | ---
217 0 | 1 | version (known values are 1 or 2)
218 1 | 8 | seconds since January, 1, 1 stored as a 64-bit big-endian signed integer
219 9 | 4 | fraction of second, in nanoseconds stored as a 32-bit big-endian signed integer
220 13 | 2 | time zone offset in minutes as a 16-bit big-endian signed integer.
221 15 | 1 | time zone offset in seconds (only for version 2)
222
223 A value of -1 is a special value when the Time instance is initialised as UTC
224 (e.g. ```time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)```).
225
226 ### Also see
227
228 * [Golang time.go](https://cs.opensource.google/go/go/+/master:src/time/time.go)
229
199230 ## HFS timestamp
200231
201232 Sometimes a distinction is made between HFS and HFS+ timestamps is that the
239270 --- | --- | ---
240271 0 | 8 | timestamp, integer value containing the number of milliseconds before (when negative) or after (when positive) 1970-01-01 00:00:00.000 (or POSIX or Unix epoch)
241272
242 ### Also see:
273 ### Also see
243274
244275 * [Class java.util.Date](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html)
245276
317348
318349 ### Also see
319350
320 * [RFC2579](https://tools.ietf.org/html/rfc2579)
351 * [RFC2579](https://datatracker.ietf.org/doc/html/rfc2579)
321352
322353 ## SYSTEMTIME
323354 ### Characteristics
349380
350381 * [MSDN: SYSTEMTIME](https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime)
351382
383 ## Time element strings
384
385 ### ISO 8601 / RFC 3339
386
387 Example `2020-05-31T00:00:47.044800+00:00`
388
389 ### RFC 822
390
391 Example `Tue, 15 Nov 94 08:12:31 GMT`
392
393 ### RFC 1123
394
395 Example `Tue, 15 Nov 1994 08:12:31 GMT`
396
397 ### RFC 2822
398
399 ### Also see
400
401 * [RFC 822 - Date and time specification](https://datatracker.ietf.org/doc/html/rfc822#section-5)
402 * [RFC 1123 - RFC-822 date and time specification](https://datatracker.ietf.org/doc/html/rfc1123#section-5)
403 * [RFC 2822 - Date and time specification](https://datatracker.ietf.org/doc/html/rfc2822#section-3.3)
404 * [RFC 3339 - Internet date/time format](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6)
405
352406 ## UUID version 1 time
353407 ### Characteristics
354408
388442
389443 ### Also see
390444
391 * [Chromium source: time.h](https://chromium.googlesource.com/chromium/src/base/+/master/time/time.h#5)
445 * [Chromium source: time.h](https://chromium.googlesource.com/chromium/src/base/+/refs/heads/main/time/time.h#5)
7575 :undoc-members:
7676 :show-inheritance:
7777
78 dfdatetime.golang\_time module
79 ------------------------------
80
81 .. automodule:: dfdatetime.golang_time
82 :members:
83 :undoc-members:
84 :show-inheritance:
85
7886 dfdatetime.hfs\_time module
7987 ---------------------------
8088
139147 :undoc-members:
140148 :show-inheritance:
141149
150 dfdatetime.serializer module
151 ----------------------------
152
153 .. automodule:: dfdatetime.serializer
154 :members:
155 :undoc-members:
156 :show-inheritance:
157
142158 dfdatetime.systemtime module
143159 ----------------------------
144160
6262 ```
6363 set PYTHONPATH=.
6464
65 C:\Python38\python.exe tools\update.py --preset dfdatetime
65 C:\Python3\python.exe tools\update.py --preset dfdatetime
6666 ```
11 # -*- coding: utf-8 -*-
22 """Installation and deployment script."""
33
4 import os
5 import pkg_resources
46 import sys
57
68 try:
145147 python_spec_file.append(line)
146148
147149 return python_spec_file
150
151
152 def parse_requirements_from_file(path):
153 """Parses requirements from a requirements file.
154
155 Args:
156 path (str): path to the requirements file.
157
158 Returns:
159 list[str]: name and optional version information of the required packages.
160 """
161 requirements = []
162 if os.path.isfile(path):
163 with open(path, 'r') as file_object:
164 file_contents = file_object.read()
165
166 for requirement in pkg_resources.parse_requirements(file_contents):
167 try:
168 name = str(requirement.req)
169 except AttributeError:
170 name = str(requirement)
171
172 if not name.startswith('pip '):
173 requirements.append(name)
174
175 return requirements
148176
149177
150178 dfdatetime_description = (
181209 ('share/doc/dfdatetime', [
182210 'ACKNOWLEDGEMENTS', 'AUTHORS', 'LICENSE', 'README']),
183211 ],
212 install_requires=parse_requirements_from_file('requirements.txt'),
213 tests_require=parse_requirements_from_file('test_requirements.txt'),
184214 )
100100 cocoa_time_object = cocoa_time.CocoaTime(timestamp=395011845.546875)
101101
102102 date_time_string = cocoa_time_object.CopyToDateTimeStringISO8601()
103 self.assertEqual(date_time_string, '2013-07-08T21:30:45.546875Z')
103 self.assertEqual(date_time_string, '2013-07-08T21:30:45.546875+00:00')
104104
105105 def testGetDate(self):
106106 """Tests the GetDate function."""
138138 timestamp=41443.8263953)
139139
140140 date_time_string = delphi_date_time_object.CopyToDateTimeStringISO8601()
141 self.assertEqual(date_time_string, '2013-06-18T19:50:00.553919Z')
141 self.assertEqual(date_time_string, '2013-06-18T19:50:00.553919+00:00')
142142
143143 def testGetDate(self):
144144 """Tests the GetDate function."""
9494 fake_time_object.CopyFromDateTimeString('2010-08-12 21:06:31.546875')
9595
9696 date_time_string = fake_time_object.CopyToDateTimeStringISO8601()
97 self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875Z')
97 self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875+00:00')
9898
9999 def testGetDate(self):
100100 """Tests the GetDate function."""
120120 fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c)
121121
122122 date_time_string = fat_date_time_object.CopyToDateTimeStringISO8601()
123 self.assertEqual(date_time_string, '2010-08-12T21:06:32Z')
123 self.assertEqual(date_time_string, '2010-08-12T21:06:32+00:00')
124124
125125 def testGetDate(self):
126126 """Tests the GetDate function."""
100100 filetime_object = filetime.Filetime(timestamp=0x01cb3a623d0a17ce)
101101
102102 date_time_string = filetime_object.CopyToDateTimeStringISO8601()
103 self.assertEqual(date_time_string, '2010-08-12T21:06:31.5468750Z')
103 self.assertEqual(date_time_string, '2010-08-12T21:06:31.5468750+00:00')
104104
105105 def testGetDate(self):
106106 """Tests the GetDate function."""
0 # -*- coding: utf-8 -*-
1 """Tests for the Golang time.Time timestamp implementation."""
2
3 import decimal
4 import struct
5 import unittest
6
7 from dfdatetime import golang_time
8
9
10 class GolangEpochTest(unittest.TestCase):
11 """Test for the Golang time.Time epoch."""
12
13 def testInitialize(self):
14 """Tests the __init__ function."""
15 golang_epoch = golang_time.GolangTimeEpoch()
16 self.assertIsNotNone(golang_epoch)
17
18 def testEpochDate(self):
19 """Tests the Golang time.Time epoch properties."""
20 golang_epoch = golang_time.GolangTimeEpoch()
21 self.assertEqual(golang_epoch.year, 1)
22 self.assertEqual(golang_epoch.month, 1)
23 self.assertEqual(golang_epoch.day_of_month, 1)
24
25
26 class GolangTest(unittest.TestCase):
27 """Tests for the Golang time.Time timestamp."""
28
29 # pylint: disable=protected-access
30
31 def testProperties(self):
32 """Tests the Golang time.Time timestamp properties."""
33 golang_timestamp = struct.pack('>Bqih', 1, 0, 0, -1)
34 golang_time_object = golang_time.GolangTime(
35 golang_timestamp=golang_timestamp)
36 self.assertEqual(golang_time_object._number_of_seconds, 0)
37 self.assertEqual(golang_time_object._nanoseconds, 0)
38 self.assertEqual(golang_time_object.is_local_time, False)
39 self.assertEqual(golang_time_object._time_zone_offset, 0)
40
41 golang_timestamp = struct.pack(
42 '>Bqih', 1, golang_time.GolangTime._GOLANG_TO_POSIX_BASE, 0, 1)
43 golang_time_object = golang_time.GolangTime(
44 golang_timestamp=golang_timestamp)
45 self.assertEqual(golang_time_object._number_of_seconds,
46 golang_time.GolangTime._GOLANG_TO_POSIX_BASE)
47 self.assertEqual(golang_time_object._nanoseconds, 0)
48 self.assertEqual(golang_time_object.is_local_time, True)
49 self.assertEqual(golang_time_object._time_zone_offset, 1)
50
51 golang_timestamp = bytes.fromhex('010000000e7791f70000000000ffff')
52 golang_time_object = golang_time.GolangTime(
53 golang_timestamp=golang_timestamp)
54 self.assertEqual(golang_time_object._number_of_seconds,
55 golang_time.GolangTime._GOLANG_TO_POSIX_BASE)
56 self.assertEqual(golang_time_object._nanoseconds, 0)
57 self.assertEqual(golang_time_object.is_local_time, False)
58 self.assertEqual(golang_time_object._time_zone_offset, 0)
59
60 def testGetNormalizedTimestamp(self):
61 """Test the _GetNormalizedTimestamp function."""
62 golang_timestamp = bytes.fromhex('010000000000000000000000000000')
63 golang_time_object = golang_time.GolangTime(
64 golang_timestamp=golang_timestamp)
65
66 normalized_timestamp = golang_time_object._GetNormalizedTimestamp()
67 self.assertIsNone(normalized_timestamp)
68
69 golang_timestamp = struct.pack('>Bqih', 1, 63772480949, 711098348, 0)
70 golang_time_object = golang_time.GolangTime(
71 golang_timestamp=golang_timestamp)
72
73 normalized_timestamp = golang_time_object._GetNormalizedTimestamp()
74 self.assertEqual(
75 normalized_timestamp, decimal.Decimal('1636884149.711098348'))
76
77 golang_timestamp = bytes.fromhex('010000000e7791f70000000000ffff')
78 golang_time_object = golang_time.GolangTime(
79 golang_timestamp=golang_timestamp)
80
81 normalized_timestamp = golang_time_object._GetNormalizedTimestamp()
82 self.assertEqual(normalized_timestamp, decimal.Decimal('0'))
83
84 golang_timestamp = bytes.fromhex('010000000e7791f60000000000ffff')
85 golang_time_object = golang_time.GolangTime(
86 golang_timestamp=golang_timestamp)
87
88 normalized_timestamp = golang_time_object._GetNormalizedTimestamp()
89 self.assertIsNone(normalized_timestamp)
90
91 def testGetNumberOfSeconds(self):
92 """Test the _GetNumberOfSeconds function."""
93 golang_time_object = golang_time.GolangTime()
94
95 golang_timestamp = bytes.fromhex('010000000000000002000000030004')
96 number_of_seconds, nanoseconds, time_zone_offset = (
97 golang_time_object._GetNumberOfSeconds(golang_timestamp))
98 self.assertEqual(number_of_seconds, 2)
99 self.assertEqual(nanoseconds, 3)
100 self.assertEqual(time_zone_offset, 4)
101
102 golang_timestamp = bytes.fromhex('02000000000000000500000006ffff08')
103 number_of_seconds, nanoseconds, time_zone_offset = (
104 golang_time_object._GetNumberOfSeconds(golang_timestamp))
105 self.assertEqual(number_of_seconds, 5)
106 self.assertEqual(nanoseconds, 6)
107 self.assertEqual(time_zone_offset, 0)
108
109 with self.assertRaises(ValueError):
110 golang_timestamp = bytes.fromhex('0100')
111 golang_time_object._GetNumberOfSeconds(golang_timestamp)
112
113 with self.assertRaises(ValueError):
114 golang_timestamp = bytes.fromhex('020000000000000000000000000000')
115 golang_time_object._GetNumberOfSeconds(golang_timestamp)
116
117 with self.assertRaises(ValueError):
118 golang_timestamp = bytes.fromhex('ff0000000000000000000000000000')
119 golang_time_object._GetNumberOfSeconds(golang_timestamp)
120
121 def testCopyFromDateTimeString(self):
122 """Tests the CopyFromDateTimeString function."""
123 golang_time_object = golang_time.GolangTime()
124
125 golang_time_object.CopyFromDateTimeString('0001-01-01')
126 self.assertEqual(golang_time_object._number_of_seconds, 0)
127 self.assertEqual(golang_time_object._nanoseconds, 0)
128 self.assertEqual(golang_time_object._time_zone_offset, 0)
129
130 golang_time_object.CopyFromDateTimeString('0001-01-01 00:01:00')
131 self.assertEqual(golang_time_object._number_of_seconds, 60)
132 self.assertEqual(golang_time_object._nanoseconds, 0)
133 self.assertEqual(golang_time_object._time_zone_offset, 0)
134
135 golang_time_object.CopyFromDateTimeString('0001-01-01 00:00:00.000001')
136 self.assertEqual(golang_time_object._number_of_seconds, 0)
137 self.assertEqual(golang_time_object._nanoseconds, 1000)
138 self.assertEqual(golang_time_object._time_zone_offset, 0)
139
140 golang_time_object.CopyFromDateTimeString('2000-01-01')
141 self.assertEqual(golang_time_object._number_of_seconds, 63082281600)
142 self.assertEqual(golang_time_object._nanoseconds, 0)
143 self.assertEqual(golang_time_object._time_zone_offset, 0)
144
145 golang_time_object.CopyFromDateTimeString('2000-01-01 12:23:45.567890')
146 self.assertEqual(golang_time_object._number_of_seconds, 63082326225)
147 self.assertEqual(golang_time_object._nanoseconds, 567890000)
148 self.assertEqual(golang_time_object._time_zone_offset, 0)
149
150 golang_time_object.CopyFromDateTimeString(
151 '2000-01-01 12:23:45.567890+01:00')
152 self.assertEqual(golang_time_object._number_of_seconds, 63082326225)
153 self.assertEqual(golang_time_object._nanoseconds, 567890000)
154 self.assertEqual(golang_time_object._time_zone_offset, 60)
155
156 def testCopyToDateTimeString(self):
157 """Test the CopyToDateTimeString function."""
158 golang_timestamp = bytes.fromhex('010000000eafffe8d121d95050ffff')
159 golang_time_object = golang_time.GolangTime(
160 golang_timestamp=golang_timestamp)
161
162 self.assertEqual(golang_time_object._number_of_seconds, 63082326225)
163 self.assertEqual(golang_time_object._nanoseconds, 567890000)
164 self.assertEqual(golang_time_object._time_zone_offset, 0)
165
166 date_time_string = golang_time_object.CopyToDateTimeString()
167 self.assertEqual(date_time_string, '2000-01-01 12:23:45.567890')
168
169 golang_timestamp = bytes.fromhex('010000000eafffe8d10000ddd5ffff')
170 golang_time_object = golang_time.GolangTime(
171 golang_timestamp=golang_timestamp)
172
173 self.assertEqual(golang_time_object._number_of_seconds, 63082326225)
174 self.assertEqual(golang_time_object._nanoseconds, 56789)
175 self.assertEqual(golang_time_object._time_zone_offset, 0)
176
177 date_time_string = golang_time_object.CopyToDateTimeString()
178 self.assertEqual(date_time_string, '2000-01-01 12:23:45.000056')
105105 hfs_time_object = hfs_time.HFSTime(timestamp=3458215528)
106106
107107 date_time_string = hfs_time_object.CopyToDateTimeStringISO8601()
108 self.assertEqual(date_time_string, '2013-08-01T15:25:28Z')
108 self.assertEqual(date_time_string, '2013-08-01T15:25:28+00:00')
109109
110110 def testGetDate(self):
111111 """Tests the GetDate function."""
8383 java_time_object = java_time.JavaTime(timestamp=1281643591546)
8484
8585 date_time_string = java_time_object.CopyToDateTimeStringISO8601()
86 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546Z')
86 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546+00:00')
8787
8888 def testGetDate(self):
8989 """Tests the GetDate function."""
103103 timestamp=43044.480556)
104104
105105 date_time_string = ole_automation_date_object.CopyToDateTimeStringISO8601()
106 self.assertEqual(date_time_string, '2017-11-05T11:32:00.038400Z')
106 self.assertEqual(date_time_string, '2017-11-05T11:32:00.038400+00:00')
107107
108108 def testGetDate(self):
109109 """Tests the GetDate function."""
9292 posix_time_object = posix_time.PosixTime(timestamp=1281643591)
9393
9494 date_time_string = posix_time_object.CopyToDateTimeStringISO8601()
95 self.assertEqual(date_time_string, '2010-08-12T20:06:31Z')
95 self.assertEqual(date_time_string, '2010-08-12T20:06:31+00:00')
96
97 def testCopyToPosixTimestampWithFractionOfSecond(self):
98 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
99 posix_time_object = posix_time.PosixTime(timestamp=1281643591)
100
101 posix_timestamp, fraction_of_second = (
102 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
103 self.assertEqual(posix_timestamp, 1281643591)
104 self.assertIsNone(fraction_of_second)
105
106 posix_time_object = posix_time.PosixTime()
107
108 posix_timestamp, fraction_of_second = (
109 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
110 self.assertIsNone(posix_timestamp)
111 self.assertIsNone(fraction_of_second)
96112
97113 # TODO: remove this method when there is no more need for it in dfvfs.
98114 def testCopyToStatTimeTuple(self):
227243 timestamp=1281643591546)
228244
229245 date_time_string = posix_time_object.CopyToDateTimeStringISO8601()
230 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546Z')
246 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546+00:00')
247
248 def testCopyToPosixTimestampWithFractionOfSecond(self):
249 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
250 posix_time_object = posix_time.PosixTimeInMilliseconds(
251 timestamp=1281643591546)
252
253 posix_timestamp, fraction_of_second = (
254 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
255 self.assertEqual(posix_timestamp, 1281643591)
256 self.assertEqual(fraction_of_second, 546)
257
258 posix_time_object = posix_time.PosixTime()
259
260 posix_timestamp, fraction_of_second = (
261 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
262 self.assertIsNone(posix_timestamp)
263 self.assertIsNone(fraction_of_second)
231264
232265 # TODO: remove this method when there is no more need for it in dfvfs.
233266 def testCopyToStatTimeTuple(self):
366399 timestamp=1281643591546875)
367400
368401 date_time_string = posix_time_object.CopyToDateTimeStringISO8601()
369 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546875Z')
402 self.assertEqual(date_time_string, '2010-08-12T20:06:31.546875+00:00')
403
404 def testCopyToPosixTimestampWithFractionOfSecond(self):
405 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
406 posix_time_object = posix_time.PosixTimeInMicroseconds(
407 timestamp=1281643591546875)
408
409 posix_timestamp, fraction_of_second = (
410 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
411 self.assertEqual(posix_timestamp, 1281643591)
412 self.assertEqual(fraction_of_second, 546875)
413
414 posix_time_object = posix_time.PosixTime()
415
416 posix_timestamp, fraction_of_second = (
417 posix_time_object.CopyToPosixTimestampWithFractionOfSecond())
418 self.assertIsNone(posix_timestamp)
419 self.assertIsNone(fraction_of_second)
370420
371421 # TODO: remove this method when there is no more need for it in dfvfs.
372422 def testCopyToStatTimeTuple(self):
507557 timestamp=1281643591987654321)
508558
509559 date_time_string = posix_time_object.CopyToDateTimeStringISO8601()
510 self.assertEqual(date_time_string, '2010-08-12T20:06:31.987654321Z')
560 self.assertEqual(date_time_string, '2010-08-12T20:06:31.987654321+00:00')
511561
512562 def testGetDate(self):
513563 """Tests the GetDate function."""
222222 rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 0, 0))
223223
224224 date_time_string = rfc2579_date_time_object.CopyToDateTimeStringISO8601()
225 self.assertEqual(date_time_string, '2010-08-12T20:06:31.6Z')
225 self.assertEqual(date_time_string, '2010-08-12T20:06:31.6+00:00')
226226
227227 def testGetDate(self):
228228 """Tests the GetDate function."""
8484 date_time_string = semantic_time_object.CopyToDateTimeStringISO8601()
8585 self.assertIsNone(date_time_string)
8686
87 def testCopyToPosixTimestamp(self):
88 """Tests the CopyToPosixTimestamp function."""
89 semantic_time_object = semantic_time.SemanticTime()
90
91 posix_timestamp = semantic_time_object.CopyToPosixTimestamp()
92 self.assertIsNone(posix_timestamp)
93
94 def testCopyToPosixTimestampWithFractionOfSecond(self):
95 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
96 semantic_time_object = semantic_time.SemanticTime()
97
98 posix_timestamp, fraction_of_second = (
99 semantic_time_object.CopyToPosixTimestampWithFractionOfSecond())
100 self.assertIsNone(posix_timestamp)
101 self.assertIsNone(fraction_of_second)
102
87103 def testCopyToStatTimeTuple(self):
88104 """Tests the CopyToStatTimeTuple function."""
89105 semantic_time_object = semantic_time.SemanticTime()
0 #!/usr/bin/env python3
1 # -*- coding: utf-8 -*-
2 """Tests for the date and time values serializer."""
3
4 import unittest
5
6 from dfdatetime import fat_date_time
7 from dfdatetime import golang_time
8 from dfdatetime import posix_time
9 from dfdatetime import rfc2579_date_time
10 from dfdatetime import semantic_time
11 from dfdatetime import serializer
12 from dfdatetime import time_elements
13
14
15 class SerializerTest(unittest.TestCase):
16 """Tests for the date and time values serializer."""
17
18 def testConvertDateTimeValuesToJSON(self):
19 """Test ConvertDateTimeValuesToJSON function."""
20 posix_time_object = posix_time.PosixTime(timestamp=1281643591)
21
22 expected_json_dict = {
23 '__class_name__': 'PosixTime',
24 '__type__': 'DateTimeValues',
25 'timestamp': 1281643591}
26
27 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
28 posix_time_object)
29 self.assertEqual(json_dict, expected_json_dict)
30
31 posix_time_object.is_local_time = True
32
33 expected_json_dict = {
34 '__class_name__': 'PosixTime',
35 '__type__': 'DateTimeValues',
36 'is_local_time': True,
37 'timestamp': 1281643591}
38
39 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
40 posix_time_object)
41 self.assertEqual(json_dict, expected_json_dict)
42
43 never_time_object = semantic_time.Never()
44
45 expected_json_dict = {
46 '__class_name__': 'Never',
47 '__type__': 'DateTimeValues',
48 'string': 'Never'}
49
50 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
51 never_time_object)
52 self.assertEqual(json_dict, expected_json_dict)
53
54 fat_date_time_object = fat_date_time.FATDateTime(fat_date_time=0xa8d03d0c)
55
56 expected_json_dict = {
57 '__class_name__': 'FATDateTime',
58 '__type__': 'DateTimeValues',
59 'fat_date_time': 2832219404}
60
61 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
62 fat_date_time_object)
63 self.assertEqual(json_dict, expected_json_dict)
64
65 golang_timestamp = bytes.fromhex('01000000000000000200000003ffff')
66 golang_time_object = golang_time.GolangTime(
67 golang_timestamp=golang_timestamp)
68
69 expected_json_dict = {
70 '__class_name__': 'GolangTime',
71 '__type__': 'DateTimeValues',
72 'golang_timestamp': (
73 b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff'),
74 'time_zone_offset': 0}
75
76 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
77 golang_time_object)
78 self.assertEqual(json_dict, expected_json_dict)
79
80 rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime(
81 rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 0))
82
83 expected_json_dict = {
84 '__class_name__': 'RFC2579DateTime',
85 '__type__': 'DateTimeValues',
86 'rfc2579_date_time_tuple': (2010, 8, 12, 20, 6, 31, 6),
87 'time_zone_offset': 120}
88
89 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
90 rfc2579_date_time_object)
91 self.assertEqual(json_dict, expected_json_dict)
92
93 time_elements_object = time_elements.TimeElements(
94 time_elements_tuple=(2010, 8, 12, 20, 6, 31))
95
96 expected_json_dict = {
97 '__class_name__': 'TimeElements',
98 '__type__': 'DateTimeValues',
99 'time_elements_tuple': (2010, 8, 12, 20, 6, 31)}
100
101 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
102 time_elements_object)
103 self.assertEqual(json_dict, expected_json_dict)
104
105 time_elements_object = time_elements.TimeElementsInMilliseconds(
106 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546))
107
108 expected_json_dict = {
109 '__class_name__': 'TimeElementsInMilliseconds',
110 '__type__': 'DateTimeValues',
111 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 546)}
112
113 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
114 time_elements_object)
115 self.assertEqual(json_dict, expected_json_dict)
116
117 time_elements_object = time_elements.TimeElementsInMicroseconds(
118 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876))
119
120 expected_json_dict = {
121 '__class_name__': 'TimeElementsInMicroseconds',
122 '__type__': 'DateTimeValues',
123 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 429876)}
124
125 json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON(
126 time_elements_object)
127 self.assertEqual(json_dict, expected_json_dict)
128
129 # TODO: add tests for ConvertJSONToDateTimeValues
130
131
132 if __name__ == '__main__':
133 unittest.main()
178178 system_time_tuple=(2010, 8, 4, 12, 20, 6, 31, 142))
179179
180180 date_time_string = systemtime_object.CopyToDateTimeStringISO8601()
181 self.assertEqual(date_time_string, '2010-08-12T20:06:31.142Z')
181 self.assertEqual(date_time_string, '2010-08-12T20:06:31.142+00:00')
182182
183183 def testGetDate(self):
184184 """Tests the GetDate function."""
274274 time_tuple = time_elements_object._CopyTimeFromStringISO8601('2023.5')
275275 self.assertEqual(time_tuple, expected_time_tuple)
276276
277 expected_time_tuple = (8, 4, 32, None, None)
278 time_tuple = time_elements_object._CopyTimeFromStringISO8601('08:04:32Z')
279 self.assertEqual(time_tuple, expected_time_tuple)
280
281277 expected_time_tuple = (20, 23, 56, None, None)
282278 time_tuple = time_elements_object._CopyTimeFromStringISO8601('20:23:56')
283279 self.assertEqual(time_tuple, expected_time_tuple)
301297 '20:23:56.327124')
302298 self.assertEqual(time_tuple, expected_time_tuple)
303299
300 expected_time_tuple = (8, 4, 32, None, 0)
301 time_tuple = time_elements_object._CopyTimeFromStringISO8601('08:04:32Z')
302 self.assertEqual(time_tuple, expected_time_tuple)
303
304 expected_time_tuple = (8, 4, 32, None, 0)
305 time_tuple = time_elements_object._CopyTimeFromStringISO8601(
306 '08:04:32+00:00')
307 self.assertEqual(time_tuple, expected_time_tuple)
308
304309 expected_time_tuple = (20, 23, 56, 327124, -300)
305310 time_tuple = time_elements_object._CopyTimeFromStringISO8601(
306311 '20:23:56.327124-05:00')
517522 self.assertEqual(time_elements_object._time_zone_offset, 0)
518523
519524 expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31)
520 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31Z')
525 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00')
521526 self.assertEqual(
522527 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
523528 self.assertEqual(time_elements_object._number_of_seconds, 1281647191)
561566 self.assertEqual(time_elements_object._time_zone_offset, 60)
562567
563568 expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0)
564 time_elements_object.CopyFromStringISO8601('2012-03-05T20:40:00.0000000Z')
569 time_elements_object.CopyFromStringISO8601(
570 '2012-03-05T20:40:00.0000000+00:00')
565571 self.assertEqual(
566572 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
567573 self.assertEqual(time_elements_object._number_of_seconds, 1330980000)
645651 time_elements_tuple=(2010, 8, 12, 20, 6, 31))
646652
647653 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
648 self.assertEqual(date_time_string, '2010-08-12T20:06:31Z')
654 self.assertEqual(date_time_string, '2010-08-12T20:06:31+00:00')
655
656 time_elements_object.is_local_time = True
657
658 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
659 self.assertEqual(date_time_string, '2010-08-12T20:06:31')
660
661 time_elements_object = time_elements.TimeElements(
662 time_elements_tuple=(2010, 8, 12, 20, 6, 31),
663 time_zone_offset=-120)
664
665 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
666 self.assertEqual(date_time_string, '2010-08-12T20:06:31+02:00')
667
668 time_elements_object = time_elements.TimeElements(
669 time_elements_tuple=(2010, 8, 12, 20, 6, 31),
670 time_zone_offset=300)
671
672 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
673 self.assertEqual(date_time_string, '2010-08-12T20:06:31-05:00')
649674
650675 def testCopyToPosixTimestamp(self):
651676 """Tests the CopyToPosixTimestamp function."""
660685 posix_timestamp = time_elements_object.CopyToPosixTimestamp()
661686 self.assertIsNone(posix_timestamp)
662687
688 def testCopyToPosixTimestampWithFractionOfSecond(self):
689 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
690 time_elements_object = time_elements.TimeElements(
691 time_elements_tuple=(2010, 8, 12, 20, 6, 31))
692
693 posix_timestamp, fraction_of_second = (
694 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
695 self.assertEqual(posix_timestamp, 1281643591)
696 self.assertIsNone(fraction_of_second)
697
698 time_elements_object = time_elements.TimeElements()
699
700 posix_timestamp, fraction_of_second = (
701 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
702 self.assertIsNone(posix_timestamp)
703 self.assertIsNone(fraction_of_second)
704
663705 def testGetDate(self):
664706 """Tests the GetDate function."""
665707 time_elements_object = time_elements.TimeElements(
852894 self.assertEqual(time_elements_object._time_zone_offset, 0)
853895
854896 expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31)
855 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31Z')
897 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00')
856898 self.assertEqual(
857899 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
858900 self.assertEqual(time_elements_object._number_of_seconds, 1281647191)
902944 self.assertEqual(time_elements_object._time_zone_offset, 60)
903945
904946 expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0)
905 time_elements_object.CopyFromStringISO8601('2012-03-05T20:40:00.0000000Z')
947 time_elements_object.CopyFromStringISO8601(
948 '2012-03-05T20:40:00.0000000+00:00')
906949 self.assertEqual(
907950 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
908951 self.assertEqual(time_elements_object._number_of_seconds, 1330980000)
9681011 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429))
9691012
9701013 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
971 self.assertEqual(date_time_string, '2010-08-12T20:06:31.429Z')
1014 self.assertEqual(date_time_string, '2010-08-12T20:06:31.429+00:00')
1015
1016 def testCopyToPosixTimestamp(self):
1017 """Tests the CopyToPosixTimestamp function."""
1018 time_elements_object = time_elements.TimeElementsInMilliseconds(
1019 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429))
1020
1021 posix_timestamp = time_elements_object.CopyToPosixTimestamp()
1022 self.assertEqual(posix_timestamp, 1281643591)
1023
1024 time_elements_object = time_elements.TimeElements()
1025
1026 posix_timestamp = time_elements_object.CopyToPosixTimestamp()
1027 self.assertIsNone(posix_timestamp)
1028
1029 def testCopyToPosixTimestampWithFractionOfSecond(self):
1030 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
1031 time_elements_object = time_elements.TimeElementsInMilliseconds(
1032 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429))
1033
1034 posix_timestamp, fraction_of_second = (
1035 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
1036 self.assertEqual(posix_timestamp, 1281643591)
1037 self.assertEqual(fraction_of_second, 429)
1038
1039 time_elements_object = time_elements.TimeElements()
1040
1041 posix_timestamp, fraction_of_second = (
1042 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
1043 self.assertIsNone(posix_timestamp)
1044 self.assertIsNone(fraction_of_second)
9721045
9731046 def testGetDate(self):
9741047 """Tests the GetDate function."""
11631236 self.assertEqual(time_elements_object._time_zone_offset, 0)
11641237
11651238 expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31)
1166 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31Z')
1239 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31+00:00')
11671240 self.assertEqual(
11681241 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
11691242 self.assertEqual(time_elements_object._number_of_seconds, 1281647191)
12131286 self.assertEqual(time_elements_object._time_zone_offset, 60)
12141287
12151288 expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0)
1216 time_elements_object.CopyFromStringISO8601('2012-03-05T20:40:00.0000000Z')
1289 time_elements_object.CopyFromStringISO8601(
1290 '2012-03-05T20:40:00.0000000+00:00')
12171291 self.assertEqual(
12181292 time_elements_object._time_elements_tuple, expected_time_elements_tuple)
12191293 self.assertEqual(time_elements_object._number_of_seconds, 1330980000)
12791353 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876))
12801354
12811355 date_time_string = time_elements_object.CopyToDateTimeStringISO8601()
1282 self.assertEqual(date_time_string, '2010-08-12T20:06:31.429876Z')
1356 self.assertEqual(date_time_string, '2010-08-12T20:06:31.429876+00:00')
1357
1358 def testCopyToPosixTimestamp(self):
1359 """Tests the CopyToPosixTimestamp function."""
1360 time_elements_object = time_elements.TimeElementsInMicroseconds(
1361 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876))
1362
1363 posix_timestamp = time_elements_object.CopyToPosixTimestamp()
1364 self.assertEqual(posix_timestamp, 1281643591)
1365
1366 time_elements_object = time_elements.TimeElements()
1367
1368 posix_timestamp = time_elements_object.CopyToPosixTimestamp()
1369 self.assertIsNone(posix_timestamp)
1370
1371 def testCopyToPosixTimestampWithFractionOfSecond(self):
1372 """Tests the CopyToPosixTimestampWithFractionOfSecond function."""
1373 time_elements_object = time_elements.TimeElementsInMicroseconds(
1374 time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876))
1375
1376 posix_timestamp, fraction_of_second = (
1377 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
1378 self.assertEqual(posix_timestamp, 1281643591)
1379 self.assertEqual(fraction_of_second, 429876)
1380
1381 time_elements_object = time_elements.TimeElements()
1382
1383 posix_timestamp, fraction_of_second = (
1384 time_elements_object.CopyToPosixTimestampWithFractionOfSecond())
1385 self.assertIsNone(posix_timestamp)
1386 self.assertIsNone(fraction_of_second)
12831387
12841388 def testGetDate(self):
12851389 """Tests the GetDate function."""
132132 uuid_time_object = uuid_time.UUIDTime(timestamp=uuid_object.time)
133133
134134 date_time_string = uuid_time_object.CopyToDateTimeStringISO8601()
135 self.assertEqual(date_time_string, '2012-05-16T01:11:01.6544084Z')
135 self.assertEqual(date_time_string, '2012-05-16T01:11:01.6544084+00:00')
136136
137137 def testGetDate(self):
138138 """Tests the GetDate function."""
9999 webkit_time_object = webkit_time.WebKitTime(timestamp=12926120791546875)
100100
101101 date_time_string = webkit_time_object.CopyToDateTimeStringISO8601()
102 self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875Z')
102 self.assertEqual(date_time_string, '2010-08-12T21:06:31.546875+00:00')
103103
104104 def testGetDate(self):
105105 """Tests the GetDate function."""
00 [tox]
1 envlist = py3{6,7,8,9},coverage,docs,pylint
1 envlist = py3{6,7,8,9,10},coverage,docs,pylint
22
33 [testenv]
44 pip_pre = True
99 -rtest_requirements.txt
1010 coverage: coverage
1111 commands =
12 py3{6,7,8,9}: ./run_tests.py
12 py3{6,7,8,9,10}: ./run_tests.py
1313 coverage: coverage erase
1414 coverage: coverage run --source=dfdatetime --omit="*_test*,*__init__*,*test_lib*" run_tests.py
1515
4343 deps =
4444 -rrequirements.txt
4545 -rtest_requirements.txt
46 pylint >= 2.6.0, < 2.7.0
46 pylint >= 2.9.0, < 2.10.0
4747 commands =
4848 pylint --version
4949 # Ignore setup.py for now due to:
2424 rpm_name (str): name of the rpm package that provides the dependency.
2525 skip_check (bool): True if the dependency should be skipped by the
2626 CheckDependencies or CheckTestDependencies methods of DependencyHelper.
27 skip_requires (bool): True if the dependency should be excluded from
28 requirements.txt or setup.py install_requires.
2729 version_property (str): name of the version attribute or function.
2830 """
2931
4547 self.python3_only = False
4648 self.rpm_name = None
4749 self.skip_check = None
50 self.skip_requires = None
4851 self.version_property = None
4952
5053
6265 'python3_only',
6366 'rpm_name',
6467 'skip_check',
68 'skip_requires',
6569 'version_property'])
6670
6771 def _GetConfigValue(self, config_parser, section_name, value_name):