Skip to content

Commit 8ad792b

Browse files
authored
Added method to serialize DateTimeValues (#309)
1 parent d13752b commit 8ad792b

36 files changed

Lines changed: 726 additions & 324 deletions

dfdatetime/apfs_time.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def CopyFromDateTimeString(self, time_string):
5757
Raises:
5858
ValueError: if the date and time value is not supported.
5959
"""
60-
super()._CopyFromDateTimeString(time_string)
60+
super().CopyFromDateTimeString(time_string)
6161

6262
if (
6363
self._timestamp is None
@@ -80,7 +80,7 @@ def CopyToDateTimeString(self):
8080
):
8181
return None
8282

83-
return super()._CopyToDateTimeString()
83+
return super().CopyToDateTimeString()
8484

8585

8686
factory.Factory.RegisterDateTimeValues(APFSTime)

dfdatetime/cocoa_time.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ def _GetNormalizedTimestamp(self):
5656
"""Retrieves the normalized timestamp.
5757
5858
Returns:
59-
float: normalized timestamp, which contains the number of seconds since
60-
January 1, 1970 00:00:00 and a fraction of second used for increased
61-
precision, or None if the normalized timestamp cannot be determined.
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.
6263
"""
6364
if self._normalized_timestamp is None:
6465
if self._timestamp is not None:
@@ -122,17 +123,27 @@ def CopyToDateTimeString(self):
122123
number_of_days, hours, minutes, seconds = self._GetTimeValues(
123124
int(self._timestamp)
124125
)
125-
126126
year, month, day_of_month = self._GetDateValuesWithEpoch(
127127
number_of_days, self._EPOCH
128128
)
129-
130129
microseconds = int((self._timestamp % 1) * definitions.MICROSECONDS_PER_SECOND)
131130

132131
return (
133132
f"{year:04d}-{month:02d}-{day_of_month:02d} "
134133
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}"
135134
)
136135

136+
def CopyToSerializableDict(self):
137+
"""Copies the date time value to a serializable dictionary.
138+
139+
Returns:
140+
dict[str, object]: serializable dictionary.
141+
"""
142+
serializable_dict = self._CreateSerializableDict()
143+
144+
serializable_dict["timestamp"] = self._timestamp
145+
146+
return serializable_dict
147+
137148

138149
factory.Factory.RegisterDateTimeValues(CocoaTime)

dfdatetime/delphi_date_time.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ def CopyFromDateTimeString(self, time_string):
108108
timestamp = self._GetNumberOfSecondsFromElements(
109109
year, month, day_of_month, hours, minutes, seconds
110110
)
111-
112111
timestamp = float(timestamp) / definitions.SECONDS_PER_DAY
113112
timestamp += self._DELPHI_TO_POSIX_BASE
114113
timestamp += float(nanoseconds) / definitions.NANOSECONDS_PER_DAY
@@ -132,26 +131,36 @@ def CopyToDateTimeString(self):
132131
number_of_days, hours, minutes, seconds = self._GetTimeValues(
133132
int(number_of_seconds)
134133
)
135-
136134
# The maximum date supported by TDateTime values is limited to:
137135
# 9999-12-31 23:59:59.999 (approximate 2958465 days since epoch).
138136
# The minimum date is unknown hence assuming it is limited to:
139137
# 0001-01-01 00:00:00.000 (approximate -693593 days since epoch).
138+
140139
if number_of_days < -693593 or number_of_days > 2958465:
141140
return None
142141

143142
year, month, day_of_month = self._GetDateValuesWithEpoch(
144143
number_of_days, self._EPOCH
145144
)
146-
147145
microseconds = int(
148146
(number_of_seconds % 1) * definitions.MICROSECONDS_PER_SECOND
149147
)
150-
151148
return (
152149
f"{year:04d}-{month:02d}-{day_of_month:02d} "
153150
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{microseconds:06d}"
154151
)
155152

153+
def CopyToSerializableDict(self):
154+
"""Copies the date time value to a serializable dictionary.
155+
156+
Returns:
157+
dict[str, object]: serializable dictionary.
158+
"""
159+
serializable_dict = self._CreateSerializableDict()
160+
161+
serializable_dict["timestamp"] = self._timestamp
162+
163+
return serializable_dict
164+
156165

157166
factory.Factory.RegisterDateTimeValues(DelphiDateTime)

dfdatetime/dotnet_datetime.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,22 @@ def CopyToDateTimeString(self):
136136
year, month, day_of_month = self._GetDateValuesWithEpoch(
137137
number_of_days, self._EPOCH
138138
)
139-
140139
return (
141140
f"{year:04d}-{month:02d}-{day_of_month:02d} "
142141
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}"
143142
)
144143

144+
def CopyToSerializableDict(self):
145+
"""Copies the date time value to a serializable dictionary.
146+
147+
Returns:
148+
dict[str, object]: serializable dictionary.
149+
"""
150+
serializable_dict = self._CreateSerializableDict()
151+
152+
serializable_dict["timestamp"] = self._timestamp
153+
154+
return serializable_dict
155+
145156

146157
factory.Factory.RegisterDateTimeValues(DotNetDateTime)

dfdatetime/fake_time.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ def CopyFromDateTimeString(self, time_string):
9090
self._number_of_seconds = self._GetNumberOfSecondsFromElements(
9191
year, month, day_of_month, hours, minutes, seconds
9292
)
93-
9493
if nanoseconds is None:
9594
self._microseconds = None
9695
else:
@@ -112,17 +111,29 @@ def CopyToDateTimeString(self):
112111
number_of_days, hours, minutes, seconds = self._GetTimeValues(
113112
self._number_of_seconds
114113
)
115-
116114
year, month, day_of_month = self._GetDateValuesWithEpoch(
117115
number_of_days, self._EPOCH
118116
)
119-
120117
date_time_string = (
121118
f"{year:04d}-{month:02d}-{day_of_month:02d} "
122119
f"{hours:02d}:{minutes:02d}:{seconds:02d}"
123120
)
124-
125121
if self._microseconds is not None:
126122
date_time_string = ".".join([date_time_string, f"{self._microseconds:06d}"])
127123

128124
return date_time_string
125+
126+
def CopyToSerializableDict(self):
127+
"""Copies the date time value to a serializable dictionary.
128+
129+
Returns:
130+
dict[str, object]: serializable dictionary.
131+
"""
132+
normalized_timestamp = self._GetNormalizedTimestamp()
133+
134+
serializable_dict = self._CreateSerializableDict()
135+
136+
serializable_dict["timestamp"] = int(
137+
normalized_timestamp * definitions.MICROSECONDS_PER_SECOND
138+
)
139+
return serializable_dict

dfdatetime/fat_date_time.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ def _GetNormalizedTimestamp(self):
8282
decimal.Decimal(self._number_of_seconds)
8383
+ self._FAT_DATE_TO_POSIX_BASE
8484
)
85-
8685
if self._time_zone_offset:
8786
self._normalized_timestamp -= self._time_zone_offset * 60
8887

@@ -181,16 +180,26 @@ def CopyToDateTimeString(self):
181180
number_of_days, hours, minutes, seconds = self._GetTimeValues(
182181
self._number_of_seconds
183182
)
184-
185183
year, month, day_of_month = self._GetDateValuesWithEpoch(
186184
number_of_days, self._EPOCH
187185
)
188-
189186
return (
190187
f"{year:04d}-{month:02d}-{day_of_month:02d} "
191188
f"{hours:02d}:{minutes:02d}:{seconds:02d}"
192189
)
193190

191+
def CopyToSerializableDict(self):
192+
"""Copies the date time value to a serializable dictionary.
193+
194+
Returns:
195+
dict[str, object]: serializable dictionary.
196+
"""
197+
serializable_dict = self._CreateSerializableDict()
198+
199+
serializable_dict["fat_date_time"] = self._fat_date_time
200+
201+
return serializable_dict
202+
194203

195204
class FATTimestamp(interface.DateTimeValues):
196205
"""FAT timestamp.
@@ -306,12 +315,23 @@ def CopyToDateTimeString(self):
306315
year, month, day_of_month = self._GetDateValuesWithEpoch(
307316
number_of_days, self._EPOCH
308317
)
309-
310318
return (
311319
f"{year:04d}-{month:02d}-{day_of_month:02d} "
312320
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:02d}"
313321
)
314322

323+
def CopyToSerializableDict(self):
324+
"""Copies the date time value to a serializable dictionary.
325+
326+
Returns:
327+
dict[str, object]: serializable dictionary.
328+
"""
329+
serializable_dict = self._CreateSerializableDict()
330+
331+
serializable_dict["timestamp"] = self._timestamp
332+
333+
return serializable_dict
334+
315335

316336
factory.Factory.RegisterDateTimeValues(FATDateTime)
317337
factory.Factory.RegisterDateTimeValues(FATTimestamp)

dfdatetime/filetime.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,22 @@ def CopyToDateTimeString(self):
143143
year, month, day_of_month = self._GetDateValuesWithEpoch(
144144
number_of_days, self._EPOCH
145145
)
146-
147146
return (
148147
f"{year:04d}-{month:02d}-{day_of_month:02d} "
149148
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{fraction_of_second:07d}"
150149
)
151150

151+
def CopyToSerializableDict(self):
152+
"""Copies the date time value to a serializable dictionary.
153+
154+
Returns:
155+
dict[str, object]: serializable dictionary.
156+
"""
157+
serializable_dict = self._CreateSerializableDict()
158+
159+
serializable_dict["timestamp"] = self._timestamp
160+
161+
return serializable_dict
162+
152163

153164
factory.Factory.RegisterDateTimeValues(Filetime)

dfdatetime/golang_time.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def __init__(self, golang_timestamp=None, precision=None):
8282

8383
@property
8484
def golang_timestamp(self):
85-
"""int: Golang time.Time timestamp or None if not set."""
85+
"""bytes: Golang time.Time timestamp or None if not set."""
8686
return self._golang_timestamp
8787

8888
def _GetNormalizedTimestamp(self):
@@ -101,11 +101,9 @@ def _GetNormalizedTimestamp(self):
101101
and self._nanoseconds is not None
102102
and self._nanoseconds >= 0
103103
):
104-
105104
self._normalized_timestamp = decimal.Decimal(
106105
self._number_of_seconds - GolangTime._GOLANG_TO_POSIX_BASE
107106
)
108-
109107
if self._nanoseconds is not None and self._nanoseconds >= 0:
110108
self._normalized_timestamp += (
111109
decimal.Decimal(self._nanoseconds)
@@ -147,15 +145,12 @@ def _GetNumberOfSeconds(self, golang_timestamp):
147145
number_of_seconds, nanoseconds, time_zone_offset = struct.unpack(
148146
">qih", golang_timestamp[1:15]
149147
)
150-
151148
# TODO: add support for version 2 time zone offset in seconds
152149

153150
except (TypeError, struct.error) as exception:
154151
raise ValueError(
155-
(
156-
f"Unable to unpacked Golang time.Time timestamp with error: "
157-
f"{exception!s}"
158-
)
152+
f"Unable to unpacked Golang time.Time timestamp with error: "
153+
f"{exception!s}"
159154
)
160155

161156
# A time zone offset of -1 minute is a special representation for UTC.
@@ -195,7 +190,6 @@ def CopyFromDateTimeString(self, time_string):
195190
seconds = self._GetNumberOfSecondsFromElements(
196191
year, month, day_of_month, hours, minutes, seconds
197192
)
198-
199193
seconds += self._GOLANG_TO_POSIX_BASE
200194

201195
self._normalized_timestamp = None
@@ -216,15 +210,25 @@ def CopyToDateTimeString(self):
216210
number_of_days, hours, minutes, seconds = self._GetTimeValues(
217211
self._number_of_seconds
218212
)
219-
220213
year, month, day_of_month = self._GetDateValuesWithEpoch(
221214
number_of_days, self._EPOCH
222215
)
223-
224216
return (
225217
f"{year:04d}-{month:02d}-{day_of_month:02d} "
226218
f"{hours:02d}:{minutes:02d}:{seconds:02d}.{self._nanoseconds:09d}"
227219
)
228220

221+
def CopyToSerializableDict(self):
222+
"""Copies the date time value to a serializable dictionary.
223+
224+
Returns:
225+
dict[str, object]: serializable dictionary.
226+
"""
227+
return {
228+
"__class_name__": type(self).__name__,
229+
"__type__": "DateTimeValues",
230+
"golang_timestamp": self._golang_timestamp,
231+
}
232+
229233

230234
factory.Factory.RegisterDateTimeValues(GolangTime)

dfdatetime/hfs_time.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def _GetNormalizedTimestamp(self):
7070
self._normalized_timestamp = (
7171
decimal.Decimal(self._timestamp) - self._HFS_TO_POSIX_BASE
7272
)
73-
7473
if self._time_zone_offset:
7574
self._normalized_timestamp -= self._time_zone_offset * 60
7675

@@ -130,11 +129,22 @@ def CopyToDateTimeString(self):
130129
year, month, day_of_month = self._GetDateValuesWithEpoch(
131130
number_of_days, self._EPOCH
132131
)
133-
134132
return (
135133
f"{year:04d}-{month:02d}-{day_of_month:02d} "
136134
f"{hours:02d}:{minutes:02d}:{seconds:02d}"
137135
)
138136

137+
def CopyToSerializableDict(self):
138+
"""Copies the date time value to a serializable dictionary.
139+
140+
Returns:
141+
dict[str, object]: serializable dictionary.
142+
"""
143+
serializable_dict = self._CreateSerializableDict()
144+
145+
serializable_dict["timestamp"] = self._timestamp
146+
147+
return serializable_dict
148+
139149

140150
factory.Factory.RegisterDateTimeValues(HFSTime)

0 commit comments

Comments
 (0)