dfdatetime 20260730__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dfdatetime/__init__.py +26 -0
- dfdatetime/apfs_time.py +86 -0
- dfdatetime/cocoa_time.py +149 -0
- dfdatetime/decorators.py +23 -0
- dfdatetime/definitions.py +97 -0
- dfdatetime/delphi_date_time.py +166 -0
- dfdatetime/dotnet_datetime.py +157 -0
- dfdatetime/factory.py +59 -0
- dfdatetime/fake_time.py +139 -0
- dfdatetime/fat_date_time.py +337 -0
- dfdatetime/filetime.py +164 -0
- dfdatetime/golang_time.py +234 -0
- dfdatetime/hfs_time.py +150 -0
- dfdatetime/interface.py +1071 -0
- dfdatetime/java_time.py +66 -0
- dfdatetime/ole_automation_date.py +158 -0
- dfdatetime/posix_time.py +501 -0
- dfdatetime/precisions.py +425 -0
- dfdatetime/rfc2579_date_time.py +289 -0
- dfdatetime/semantic_time.py +329 -0
- dfdatetime/serializer.py +154 -0
- dfdatetime/systemtime.py +253 -0
- dfdatetime/time_elements.py +1732 -0
- dfdatetime/uuid_time.py +170 -0
- dfdatetime/webkit_time.py +159 -0
- dfdatetime-20260730.dist-info/METADATA +25 -0
- dfdatetime-20260730.dist-info/RECORD +32 -0
- dfdatetime-20260730.dist-info/WHEEL +5 -0
- dfdatetime-20260730.dist-info/licenses/ACKNOWLEDGEMENTS +16 -0
- dfdatetime-20260730.dist-info/licenses/AUTHORS +14 -0
- dfdatetime-20260730.dist-info/licenses/LICENSE +202 -0
- dfdatetime-20260730.dist-info/top_level.txt +1 -0
dfdatetime/posix_time.py
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"""POSIX timestamp implementation."""
|
|
2
|
+
|
|
3
|
+
import decimal
|
|
4
|
+
|
|
5
|
+
from dfdatetime import definitions
|
|
6
|
+
from dfdatetime import factory
|
|
7
|
+
from dfdatetime import interface
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PosixTimeEpoch(interface.DateTimeEpoch):
|
|
11
|
+
"""POSIX time epoch."""
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
"""Initializes a POSIX time epoch."""
|
|
15
|
+
super().__init__(1970, 1, 1)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PosixTime(interface.DateTimeValues):
|
|
19
|
+
"""POSIX timestamp.
|
|
20
|
+
|
|
21
|
+
The POSIX timestamp is a signed integer that contains the number of
|
|
22
|
+
seconds since 1970-01-01 00:00:00 (also known as the POSIX epoch).
|
|
23
|
+
Negative values represent date and times predating the POSIX epoch.
|
|
24
|
+
|
|
25
|
+
The POSIX timestamp was initially 32-bit though 64-bit variants
|
|
26
|
+
are known to be used.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
is_local_time (bool): True if the date and time value is in local time.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
_EPOCH = PosixTimeEpoch()
|
|
33
|
+
|
|
34
|
+
def __init__(self, precision=None, time_zone_offset=None, timestamp=None):
|
|
35
|
+
"""Initializes a POSIX timestamp.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
precision (Optional[str]): precision of the date and time value, which
|
|
39
|
+
should be one of the PRECISION_VALUES in definitions.
|
|
40
|
+
time_zone_offset (Optional[int]): time zone offset in number of minutes
|
|
41
|
+
from UTC or None if not set.
|
|
42
|
+
timestamp (Optional[int]): POSIX timestamp.
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(
|
|
45
|
+
precision=precision or definitions.PRECISION_1_SECOND,
|
|
46
|
+
time_zone_offset=time_zone_offset,
|
|
47
|
+
)
|
|
48
|
+
self._timestamp = timestamp
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def timestamp(self):
|
|
52
|
+
"""int: POSIX timestamp or None if not set."""
|
|
53
|
+
return self._timestamp
|
|
54
|
+
|
|
55
|
+
def _GetNormalizedTimestamp(self):
|
|
56
|
+
"""Retrieves the normalized timestamp.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
decimal.Decimal: normalized timestamp, which contains the number of
|
|
60
|
+
seconds since January 1, 1970 00:00:00 and a fraction of second used
|
|
61
|
+
for increased precision, or None if the normalized timestamp cannot be
|
|
62
|
+
determined.
|
|
63
|
+
"""
|
|
64
|
+
if self._normalized_timestamp is None:
|
|
65
|
+
if self._timestamp is not None:
|
|
66
|
+
self._normalized_timestamp = decimal.Decimal(self._timestamp)
|
|
67
|
+
|
|
68
|
+
if self._time_zone_offset:
|
|
69
|
+
self._normalized_timestamp -= self._time_zone_offset * 60
|
|
70
|
+
|
|
71
|
+
return self._normalized_timestamp
|
|
72
|
+
|
|
73
|
+
def CopyFromDateTimeString(self, time_string):
|
|
74
|
+
"""Copies a POSIX timestamp from a date and time string.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
time_string (str): date and time value formatted as:
|
|
78
|
+
YYYY-MM-DD hh:mm:ss.######[+-]##:##
|
|
79
|
+
|
|
80
|
+
Where # are numeric digits ranging from 0 to 9 and the seconds
|
|
81
|
+
fraction can be either 3, 6 or 9 digits. The time of day, seconds
|
|
82
|
+
fraction and time zone offset are optional. The default time zone
|
|
83
|
+
is UTC.
|
|
84
|
+
"""
|
|
85
|
+
date_time_values = self._CopyDateTimeFromString(time_string)
|
|
86
|
+
|
|
87
|
+
year = date_time_values.get("year", 0)
|
|
88
|
+
month = date_time_values.get("month", 0)
|
|
89
|
+
day_of_month = date_time_values.get("day_of_month", 0)
|
|
90
|
+
hours = date_time_values.get("hours", 0)
|
|
91
|
+
minutes = date_time_values.get("minutes", 0)
|
|
92
|
+
seconds = date_time_values.get("seconds", 0)
|
|
93
|
+
time_zone_offset = date_time_values.get("time_zone_offset")
|
|
94
|
+
|
|
95
|
+
self._timestamp = self._GetNumberOfSecondsFromElements(
|
|
96
|
+
year, month, day_of_month, hours, minutes, seconds
|
|
97
|
+
)
|
|
98
|
+
self._time_zone_offset = time_zone_offset
|
|
99
|
+
|
|
100
|
+
def CopyToDateTimeString(self):
|
|
101
|
+
"""Copies the POSIX timestamp to a date and time string.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss" or None
|
|
105
|
+
if the timestamp is missing.
|
|
106
|
+
"""
|
|
107
|
+
if self._timestamp is None:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
number_of_days, hours, minutes, seconds = self._GetTimeValues(self._timestamp)
|
|
111
|
+
|
|
112
|
+
year, month, day_of_month = self._GetDateValuesWithEpoch(
|
|
113
|
+
number_of_days, self._EPOCH
|
|
114
|
+
)
|
|
115
|
+
return (
|
|
116
|
+
f"{year:04d}-{month:02d}-{day_of_month:02d} "
|
|
117
|
+
f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def CopyToSerializableDict(self):
|
|
121
|
+
"""Copies the date time value to a serializable dictionary.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
dict[str, object]: serializable dictionary.
|
|
125
|
+
"""
|
|
126
|
+
serializable_dict = self._CreateSerializableDict()
|
|
127
|
+
|
|
128
|
+
serializable_dict["timestamp"] = self._timestamp
|
|
129
|
+
|
|
130
|
+
return serializable_dict
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class PosixTimeInMilliseconds(interface.DateTimeValues):
|
|
134
|
+
"""POSIX timestamp in milliseconds.
|
|
135
|
+
|
|
136
|
+
Variant of the POSIX timestamp in milliseconds.
|
|
137
|
+
|
|
138
|
+
Attributes:
|
|
139
|
+
is_local_time (bool): True if the date and time value is in local time.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
_EPOCH = PosixTimeEpoch()
|
|
143
|
+
|
|
144
|
+
def __init__(self, precision=None, time_zone_offset=None, timestamp=None):
|
|
145
|
+
"""Initializes a POSIX timestamp in milliseconds.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
precision (Optional[str]): precision of the date and time value, which
|
|
149
|
+
should be one of the PRECISION_VALUES in definitions.
|
|
150
|
+
time_zone_offset (Optional[int]): time zone offset in number of minutes
|
|
151
|
+
from UTC or None if not set.
|
|
152
|
+
timestamp (Optional[int]): POSIX timestamp in milliseconds.
|
|
153
|
+
"""
|
|
154
|
+
super().__init__(
|
|
155
|
+
precision=precision or definitions.PRECISION_1_MILLISECOND,
|
|
156
|
+
time_zone_offset=time_zone_offset,
|
|
157
|
+
)
|
|
158
|
+
self._timestamp = timestamp
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def timestamp(self):
|
|
162
|
+
"""int: POSIX timestamp in milliseconds or None if not set."""
|
|
163
|
+
return self._timestamp
|
|
164
|
+
|
|
165
|
+
def _GetNormalizedTimestamp(self):
|
|
166
|
+
"""Retrieves the normalized timestamp.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
decimal.Decimal: normalized timestamp, which contains the number of
|
|
170
|
+
seconds since January 1, 1970 00:00:00 and a fraction of second used
|
|
171
|
+
for increased precision, or None if the normalized timestamp cannot be
|
|
172
|
+
determined.
|
|
173
|
+
"""
|
|
174
|
+
if self._normalized_timestamp is None:
|
|
175
|
+
if self._timestamp is not None:
|
|
176
|
+
self._normalized_timestamp = (
|
|
177
|
+
decimal.Decimal(self._timestamp)
|
|
178
|
+
/ definitions.MILLISECONDS_PER_SECOND
|
|
179
|
+
)
|
|
180
|
+
if self._time_zone_offset:
|
|
181
|
+
self._normalized_timestamp -= self._time_zone_offset * 60
|
|
182
|
+
|
|
183
|
+
return self._normalized_timestamp
|
|
184
|
+
|
|
185
|
+
def CopyFromDateTimeString(self, time_string):
|
|
186
|
+
"""Copies a POSIX timestamp from a date and time string.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
time_string (str): date and time value formatted as:
|
|
190
|
+
YYYY-MM-DD hh:mm:ss.######[+-]##:##
|
|
191
|
+
|
|
192
|
+
Where # are numeric digits ranging from 0 to 9 and the seconds
|
|
193
|
+
fraction can be either 3, 6 or 9 digits. The time of day, seconds
|
|
194
|
+
fraction and time zone offset are optional. The default time zone
|
|
195
|
+
is UTC.
|
|
196
|
+
"""
|
|
197
|
+
date_time_values = self._CopyDateTimeFromString(time_string)
|
|
198
|
+
|
|
199
|
+
year = date_time_values.get("year", 0)
|
|
200
|
+
month = date_time_values.get("month", 0)
|
|
201
|
+
day_of_month = date_time_values.get("day_of_month", 0)
|
|
202
|
+
hours = date_time_values.get("hours", 0)
|
|
203
|
+
minutes = date_time_values.get("minutes", 0)
|
|
204
|
+
seconds = date_time_values.get("seconds", 0)
|
|
205
|
+
nanoseconds = date_time_values.get("nanoseconds", 0)
|
|
206
|
+
time_zone_offset = date_time_values.get("time_zone_offset")
|
|
207
|
+
|
|
208
|
+
milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MILLISECOND)
|
|
209
|
+
|
|
210
|
+
timestamp = self._GetNumberOfSecondsFromElements(
|
|
211
|
+
year, month, day_of_month, hours, minutes, seconds
|
|
212
|
+
)
|
|
213
|
+
timestamp *= definitions.MILLISECONDS_PER_SECOND
|
|
214
|
+
timestamp += milliseconds
|
|
215
|
+
|
|
216
|
+
self._timestamp = timestamp
|
|
217
|
+
self._time_zone_offset = time_zone_offset
|
|
218
|
+
|
|
219
|
+
def CopyToDateTimeString(self):
|
|
220
|
+
"""Copies the POSIX timestamp to a date and time string.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or
|
|
224
|
+
None if the timestamp is missing.
|
|
225
|
+
"""
|
|
226
|
+
if self._timestamp is None:
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
timestamp, milliseconds = divmod(
|
|
230
|
+
self._timestamp, definitions.MILLISECONDS_PER_SECOND
|
|
231
|
+
)
|
|
232
|
+
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
|
|
233
|
+
|
|
234
|
+
year, month, day_of_month = self._GetDateValuesWithEpoch(
|
|
235
|
+
number_of_days, self._EPOCH
|
|
236
|
+
)
|
|
237
|
+
return (
|
|
238
|
+
f"{year:04d}-{month:02d}-{day_of_month:02d} "
|
|
239
|
+
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
def CopyToSerializableDict(self):
|
|
243
|
+
"""Copies the date time value to a serializable dictionary.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
dict[str, object]: serializable dictionary.
|
|
247
|
+
"""
|
|
248
|
+
serializable_dict = self._CreateSerializableDict()
|
|
249
|
+
|
|
250
|
+
serializable_dict["timestamp"] = self._timestamp
|
|
251
|
+
|
|
252
|
+
return serializable_dict
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class PosixTimeInMicroseconds(interface.DateTimeValues):
|
|
256
|
+
"""POSIX timestamp in microseconds.
|
|
257
|
+
|
|
258
|
+
Variant of the POSIX timestamp in microseconds.
|
|
259
|
+
|
|
260
|
+
Attributes:
|
|
261
|
+
is_local_time (bool): True if the date and time value is in local time.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
_EPOCH = PosixTimeEpoch()
|
|
265
|
+
|
|
266
|
+
def __init__(self, precision=None, time_zone_offset=None, timestamp=None):
|
|
267
|
+
"""Initializes a POSIX timestamp in microseconds.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
precision (Optional[str]): precision of the date and time value, which
|
|
271
|
+
should be one of the PRECISION_VALUES in definitions.
|
|
272
|
+
time_zone_offset (Optional[int]): time zone offset in number of minutes
|
|
273
|
+
from UTC or None if not set.
|
|
274
|
+
timestamp (Optional[int]): POSIX timestamp in microseconds.
|
|
275
|
+
"""
|
|
276
|
+
super().__init__(
|
|
277
|
+
precision=precision or definitions.PRECISION_1_MICROSECOND,
|
|
278
|
+
time_zone_offset=time_zone_offset,
|
|
279
|
+
)
|
|
280
|
+
self._timestamp = timestamp
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
def timestamp(self):
|
|
284
|
+
"""int: POSIX timestamp in microseconds or None if not set."""
|
|
285
|
+
return self._timestamp
|
|
286
|
+
|
|
287
|
+
def _GetNormalizedTimestamp(self):
|
|
288
|
+
"""Retrieves the normalized timestamp.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
decimal.Decimal: normalized timestamp, which contains the number of
|
|
292
|
+
seconds since January 1, 1970 00:00:00 and a fraction of second used
|
|
293
|
+
for increased precision, or None if the normalized timestamp cannot be
|
|
294
|
+
determined.
|
|
295
|
+
"""
|
|
296
|
+
if self._normalized_timestamp is None:
|
|
297
|
+
if self._timestamp is not None:
|
|
298
|
+
self._normalized_timestamp = (
|
|
299
|
+
decimal.Decimal(self._timestamp)
|
|
300
|
+
/ definitions.MICROSECONDS_PER_SECOND
|
|
301
|
+
)
|
|
302
|
+
if self._time_zone_offset:
|
|
303
|
+
self._normalized_timestamp -= self._time_zone_offset * 60
|
|
304
|
+
|
|
305
|
+
return self._normalized_timestamp
|
|
306
|
+
|
|
307
|
+
def CopyFromDateTimeString(self, time_string):
|
|
308
|
+
"""Copies a POSIX timestamp from a date and time string.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
time_string (str): date and time value formatted as:
|
|
312
|
+
YYYY-MM-DD hh:mm:ss.######[+-]##:##
|
|
313
|
+
|
|
314
|
+
Where # are numeric digits ranging from 0 to 9 and the seconds
|
|
315
|
+
fraction can be either 3, 6 or 9 digits. The time of day, seconds
|
|
316
|
+
fraction and time zone offset are optional. The default time zone
|
|
317
|
+
is UTC.
|
|
318
|
+
"""
|
|
319
|
+
date_time_values = self._CopyDateTimeFromString(time_string)
|
|
320
|
+
|
|
321
|
+
year = date_time_values.get("year", 0)
|
|
322
|
+
month = date_time_values.get("month", 0)
|
|
323
|
+
day_of_month = date_time_values.get("day_of_month", 0)
|
|
324
|
+
hours = date_time_values.get("hours", 0)
|
|
325
|
+
minutes = date_time_values.get("minutes", 0)
|
|
326
|
+
seconds = date_time_values.get("seconds", 0)
|
|
327
|
+
nanoseconds = date_time_values.get("nanoseconds", 0)
|
|
328
|
+
time_zone_offset = date_time_values.get("time_zone_offset")
|
|
329
|
+
|
|
330
|
+
milliseconds, _ = divmod(nanoseconds, definitions.NANOSECONDS_PER_MICROSECOND)
|
|
331
|
+
|
|
332
|
+
timestamp = self._GetNumberOfSecondsFromElements(
|
|
333
|
+
year, month, day_of_month, hours, minutes, seconds
|
|
334
|
+
)
|
|
335
|
+
timestamp *= definitions.MICROSECONDS_PER_SECOND
|
|
336
|
+
timestamp += milliseconds
|
|
337
|
+
|
|
338
|
+
self._timestamp = timestamp
|
|
339
|
+
self._time_zone_offset = time_zone_offset
|
|
340
|
+
|
|
341
|
+
def CopyToDateTimeString(self):
|
|
342
|
+
"""Copies the POSIX timestamp to a date and time string.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.######" or
|
|
346
|
+
None if the timestamp is missing.
|
|
347
|
+
"""
|
|
348
|
+
if self._timestamp is None:
|
|
349
|
+
return None
|
|
350
|
+
|
|
351
|
+
timestamp, microseconds = divmod(
|
|
352
|
+
self._timestamp, definitions.MICROSECONDS_PER_SECOND
|
|
353
|
+
)
|
|
354
|
+
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
|
|
355
|
+
|
|
356
|
+
year, month, day_of_month = self._GetDateValuesWithEpoch(
|
|
357
|
+
number_of_days, self._EPOCH
|
|
358
|
+
)
|
|
359
|
+
return (
|
|
360
|
+
f"{year:04d}-{month:02d}-{day_of_month:02d} "
|
|
361
|
+
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}"
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
def CopyToSerializableDict(self):
|
|
365
|
+
"""Copies the date time value to a serializable dictionary.
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
dict[str, object]: serializable dictionary.
|
|
369
|
+
"""
|
|
370
|
+
serializable_dict = self._CreateSerializableDict()
|
|
371
|
+
|
|
372
|
+
serializable_dict["timestamp"] = self._timestamp
|
|
373
|
+
|
|
374
|
+
return serializable_dict
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
class PosixTimeInNanoseconds(interface.DateTimeValues):
|
|
378
|
+
"""POSIX timestamp in nanoseconds.
|
|
379
|
+
|
|
380
|
+
Variant of the POSIX timestamp in nanoseconds.
|
|
381
|
+
|
|
382
|
+
Attributes:
|
|
383
|
+
is_local_time (bool): True if the date and time value is in local time.
|
|
384
|
+
"""
|
|
385
|
+
|
|
386
|
+
_EPOCH = PosixTimeEpoch()
|
|
387
|
+
|
|
388
|
+
def __init__(self, precision=None, time_zone_offset=None, timestamp=None):
|
|
389
|
+
"""Initializes a POSIX timestamp in nanoseconds.
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
precision (Optional[str]): precision of the date and time value, which
|
|
393
|
+
should be one of the PRECISION_VALUES in definitions.
|
|
394
|
+
time_zone_offset (Optional[int]): time zone offset in number of minutes
|
|
395
|
+
from UTC or None if not set.
|
|
396
|
+
timestamp (Optional[int]): POSIX timestamp in nanoseconds.
|
|
397
|
+
"""
|
|
398
|
+
super().__init__(
|
|
399
|
+
precision=precision or definitions.PRECISION_1_NANOSECOND,
|
|
400
|
+
time_zone_offset=time_zone_offset,
|
|
401
|
+
)
|
|
402
|
+
self._timestamp = timestamp
|
|
403
|
+
|
|
404
|
+
@property
|
|
405
|
+
def timestamp(self):
|
|
406
|
+
"""int: POSIX timestamp or None if not set."""
|
|
407
|
+
return self._timestamp
|
|
408
|
+
|
|
409
|
+
def _GetNormalizedTimestamp(self):
|
|
410
|
+
"""Retrieves the normalized timestamp.
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
decimal.Decimal: normalized timestamp, which contains the number of
|
|
414
|
+
seconds since January 1, 1970 00:00:00 and a fraction of second used
|
|
415
|
+
for increased precision, or None if the normalized timestamp cannot be
|
|
416
|
+
determined.
|
|
417
|
+
"""
|
|
418
|
+
if self._normalized_timestamp is None:
|
|
419
|
+
if self._timestamp is not None:
|
|
420
|
+
self._normalized_timestamp = (
|
|
421
|
+
decimal.Decimal(self._timestamp)
|
|
422
|
+
/ definitions.NANOSECONDS_PER_SECOND
|
|
423
|
+
)
|
|
424
|
+
if self._time_zone_offset:
|
|
425
|
+
self._normalized_timestamp -= self._time_zone_offset * 60
|
|
426
|
+
|
|
427
|
+
return self._normalized_timestamp
|
|
428
|
+
|
|
429
|
+
def CopyFromDateTimeString(self, time_string):
|
|
430
|
+
"""Copies a POSIX timestamp from a date and time string.
|
|
431
|
+
|
|
432
|
+
Args:
|
|
433
|
+
time_string (str): date and time value formatted as:
|
|
434
|
+
YYYY-MM-DD hh:mm:ss.######[+-]##:##
|
|
435
|
+
|
|
436
|
+
Where # are numeric digits ranging from 0 to 9 and the seconds
|
|
437
|
+
fraction can be either 3, 6 or 9 digits. The time of day, seconds
|
|
438
|
+
fraction and time zone offset are optional. The default time zone
|
|
439
|
+
is UTC.
|
|
440
|
+
"""
|
|
441
|
+
date_time_values = self._CopyDateTimeFromString(time_string)
|
|
442
|
+
|
|
443
|
+
year = date_time_values.get("year", 0)
|
|
444
|
+
month = date_time_values.get("month", 0)
|
|
445
|
+
day_of_month = date_time_values.get("day_of_month", 0)
|
|
446
|
+
hours = date_time_values.get("hours", 0)
|
|
447
|
+
minutes = date_time_values.get("minutes", 0)
|
|
448
|
+
seconds = date_time_values.get("seconds", 0)
|
|
449
|
+
nanoseconds = date_time_values.get("nanoseconds", 0)
|
|
450
|
+
time_zone_offset = date_time_values.get("time_zone_offset")
|
|
451
|
+
|
|
452
|
+
timestamp = self._GetNumberOfSecondsFromElements(
|
|
453
|
+
year, month, day_of_month, hours, minutes, seconds
|
|
454
|
+
)
|
|
455
|
+
timestamp *= definitions.NANOSECONDS_PER_SECOND
|
|
456
|
+
timestamp += nanoseconds
|
|
457
|
+
|
|
458
|
+
self._normalized_timestamp = None
|
|
459
|
+
self._timestamp = timestamp
|
|
460
|
+
self._time_zone_offset = time_zone_offset
|
|
461
|
+
|
|
462
|
+
def CopyToDateTimeString(self):
|
|
463
|
+
"""Copies the POSIX timestamp to a date and time string.
|
|
464
|
+
|
|
465
|
+
Returns:
|
|
466
|
+
str: date and time value formatted as: "YYYY-MM-DD hh:mm:ss.#########" or
|
|
467
|
+
None if the timestamp is missing or invalid.
|
|
468
|
+
"""
|
|
469
|
+
if self._timestamp is None:
|
|
470
|
+
return None
|
|
471
|
+
|
|
472
|
+
timestamp, nanoseconds = divmod(
|
|
473
|
+
self._timestamp, definitions.NANOSECONDS_PER_SECOND
|
|
474
|
+
)
|
|
475
|
+
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
|
|
476
|
+
|
|
477
|
+
year, month, day_of_month = self._GetDateValuesWithEpoch(
|
|
478
|
+
number_of_days, self._EPOCH
|
|
479
|
+
)
|
|
480
|
+
return (
|
|
481
|
+
f"{year:04d}-{month:02d}-{day_of_month:02d} "
|
|
482
|
+
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{nanoseconds:09d}"
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
def CopyToSerializableDict(self):
|
|
486
|
+
"""Copies the date time value to a serializable dictionary.
|
|
487
|
+
|
|
488
|
+
Returns:
|
|
489
|
+
dict[str, object]: serializable dictionary.
|
|
490
|
+
"""
|
|
491
|
+
serializable_dict = self._CreateSerializableDict()
|
|
492
|
+
|
|
493
|
+
serializable_dict["timestamp"] = self._timestamp
|
|
494
|
+
|
|
495
|
+
return serializable_dict
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
factory.Factory.RegisterDateTimeValues(PosixTime)
|
|
499
|
+
factory.Factory.RegisterDateTimeValues(PosixTimeInMilliseconds)
|
|
500
|
+
factory.Factory.RegisterDateTimeValues(PosixTimeInMicroseconds)
|
|
501
|
+
factory.Factory.RegisterDateTimeValues(PosixTimeInNanoseconds)
|