1
- # Copyright 2020 Google LLC
1
+ # Copyright 2024 Ryan Benson
2
2
#
3
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
4
# you may not use this file except in compliance with the License.
14
14
15
15
import datetime
16
16
import re
17
+
17
18
from unfurl import utils
18
19
19
20
timestamp_edge = {
@@ -50,7 +51,11 @@ def decode_epoch_seconds(seconds):
50
51
2030: 1900000000
51
52
52
53
"""
53
- return datetime .datetime .utcfromtimestamp (float (seconds )), 'Epoch seconds'
54
+ return {
55
+ 'data_type' : 'timestamp.epoch-seconds' ,
56
+ 'display_type' : 'Epoch seconds' ,
57
+ 'timestamp_value' : str (datetime .datetime .fromtimestamp (float (seconds ), datetime .UTC ))
58
+ }
54
59
55
60
56
61
def decode_epoch_centiseconds (centiseconds ):
@@ -68,9 +73,13 @@ def decode_epoch_centiseconds(centiseconds):
68
73
"""
69
74
# Trim off the 4 trailing 0s (don't add precision that wasn't in the timestamp)
70
75
converted_ts = trim_zero_fractional_seconds (
71
- str (datetime .datetime .utcfromtimestamp (float (centiseconds ) / 100 )), 4 )
72
- return converted_ts , 'Epoch centiseconds'
76
+ str (datetime .datetime .fromtimestamp (float (centiseconds ) / 100 , datetime .UTC )), 4 )
73
77
78
+ return {
79
+ 'data_type' : 'timestamp.epoch-centiseconds' ,
80
+ 'display_type' : 'Epoch centiseconds' ,
81
+ 'timestamp_value' : converted_ts
82
+ }
74
83
75
84
def decode_epoch_milliseconds (milliseconds ):
76
85
"""Decode a numeric timestamp in Epoch milliseconds format to a human-readable timestamp.
@@ -87,7 +96,12 @@ def decode_epoch_milliseconds(milliseconds):
87
96
converted_dt = datetime .datetime (1970 , 1 , 1 ) + datetime .timedelta (milliseconds = float (milliseconds ))
88
97
# Trim off the 3 trailing 0s (don't add precision that wasn't in the timestamp)
89
98
converted_ts = trim_zero_fractional_seconds (str (converted_dt ), 3 )
90
- return converted_ts , 'Epoch milliseconds'
99
+
100
+ return {
101
+ 'data_type' : 'timestamp.epoch-milliseconds' ,
102
+ 'display_type' : 'Epoch milliseconds' ,
103
+ 'timestamp_value' : converted_ts
104
+ }
91
105
92
106
93
107
def decode_epoch_ten_microseconds (ten_microseconds ):
@@ -105,9 +119,13 @@ def decode_epoch_ten_microseconds(ten_microseconds):
105
119
"""
106
120
# Trim off the trailing 0 (don't add precision that wasn't in the timestamp)
107
121
converted_ts = trim_zero_fractional_seconds (
108
- str (datetime .datetime .utcfromtimestamp (float (ten_microseconds ) / 100000 )), 1 )
109
- return converted_ts , 'Epoch ten-microsecond increments'
122
+ str (datetime .datetime .fromtimestamp (float (ten_microseconds ) / 100000 , datetime .UTC )), 1 )
110
123
124
+ return {
125
+ 'data_type' : 'timestamp.epoch-ten-microseconds' ,
126
+ 'display_type' : 'Epoch ten-microsecond increments' ,
127
+ 'timestamp_value' : converted_ts
128
+ }
111
129
112
130
def decode_epoch_microseconds (microseconds ):
113
131
"""Decode a numeric timestamp in Epoch microseconds format to a human-readable timestamp.
@@ -121,8 +139,13 @@ def decode_epoch_microseconds(microseconds):
121
139
2030: 1900000000000000
122
140
123
141
"""
124
- converted_ts = str (datetime .datetime .utcfromtimestamp (float (microseconds ) / 1000000 ))
125
- return converted_ts , 'Epoch microseconds'
142
+ converted_ts = datetime .datetime .fromtimestamp (float (microseconds ) / 1000000 , datetime .UTC )
143
+
144
+ return {
145
+ 'data_type' : 'timestamp.epoch-microseconds' ,
146
+ 'display_type' : 'Epoch microseconds' ,
147
+ 'timestamp_value' : str (converted_ts )
148
+ }
126
149
127
150
128
151
def decode_webkit (microseconds ):
@@ -136,8 +159,13 @@ def decode_webkit(microseconds):
136
159
2025: 13380163200000000
137
160
138
161
"""
139
- return datetime .datetime .utcfromtimestamp ((float (microseconds ) / 1000000 ) - 11644473600 ), 'Webkit'
162
+ converted_ts = datetime .datetime .fromtimestamp ((float (microseconds ) / 1000000 ) - 11644473600 , datetime . UTC )
140
163
164
+ return {
165
+ 'data_type' : 'timestamp.webkit' ,
166
+ 'display_type' : 'Webkit' ,
167
+ 'timestamp_value' : str (converted_ts )
168
+ }
141
169
142
170
def decode_windows_filetime (intervals ):
143
171
"""Decode a numeric timestamp in Windows FileTime format to a human-readable timestamp.
@@ -152,8 +180,13 @@ def decode_windows_filetime(intervals):
152
180
2065: 146424672000000000
153
181
154
182
"""
155
- return datetime .datetime .utcfromtimestamp ((float (intervals ) / 10000000 ) - 11644473600 ), 'Windows FileTime'
183
+ converted_ts = datetime .datetime .fromtimestamp ((float (intervals ) / 10000000 ) - 11644473600 , datetime . UTC )
156
184
185
+ return {
186
+ 'data_type' : 'timestamp.windows-filetime' ,
187
+ 'display_type' : 'Windows FileTime' ,
188
+ 'timestamp_value' : str (converted_ts )
189
+ }
157
190
158
191
def decode_datetime_ticks (ticks ):
159
192
"""Decode a numeric timestamp in .Net/C# DateTime ticks format to a human-readable timestamp.
@@ -175,7 +208,13 @@ def decode_datetime_ticks(ticks):
175
208
176
209
"""
177
210
seconds = (ticks - 621355968000000000 ) / 10000000
178
- return (datetime .datetime .fromtimestamp (seconds )), 'DateTime ticks'
211
+ converted_ts = datetime .datetime .fromtimestamp (seconds )
212
+
213
+ return {
214
+ 'data_type' : 'timestamp.datetime-ticks' ,
215
+ 'display_type' : 'DateTime ticks' ,
216
+ 'timestamp_value' : str (converted_ts )
217
+ }
179
218
180
219
181
220
def decode_mac_absolute_time (seconds ):
@@ -194,7 +233,13 @@ def decode_mac_absolute_time(seconds):
194
233
2035: 1072915200
195
234
196
235
"""
197
- return datetime .datetime .utcfromtimestamp (float (seconds )+ 978307200 ), 'Mac Absolute Time / Cocoa'
236
+ converted_ts = datetime .datetime .fromtimestamp (float (seconds ) + 978307200 , datetime .UTC )
237
+
238
+ return {
239
+ 'data_type' : 'timestamp.mac-absolute-time' ,
240
+ 'display_type' : 'Mac Absolute Time / Cocoa' ,
241
+ 'timestamp_value' : str (converted_ts )
242
+ }
198
243
199
244
200
245
def decode_epoch_hex (seconds ):
@@ -209,7 +254,12 @@ def decode_epoch_hex(seconds):
209
254
210
255
"""
211
256
timestamp , _ = decode_epoch_seconds (int (seconds , 16 ))
212
- return timestamp , 'Epoch seconds (hex)'
257
+
258
+ return {
259
+ 'data_type' : 'timestamp.epoch-seconds-hex' ,
260
+ 'display_type' : 'Epoch seconds (hex)' ,
261
+ 'timestamp_value' : str (timestamp )
262
+ }
213
263
214
264
215
265
def decode_windows_filetime_hex (intervals ):
@@ -227,7 +277,12 @@ def decode_windows_filetime_hex(intervals):
227
277
"""
228
278
int_right = int (intervals , 16 )
229
279
timestamp , _ = decode_windows_filetime (int_right )
230
- return timestamp , 'Windows FileTime (hex)'
280
+
281
+ return {
282
+ 'data_type' : 'timestamp.windows-filetime-hex' ,
283
+ 'display_type' : 'Windows FileTime (hex)' ,
284
+ 'timestamp_value' : str (timestamp )
285
+ }
231
286
232
287
233
288
def run (unfurl , node ):
@@ -333,6 +388,6 @@ def run(unfurl, node):
333
388
334
389
if new_timestamp != (None , 'unknown' ):
335
390
unfurl .add_to_queue (
336
- data_type = new_timestamp [1 ], key = None , value = new_timestamp [0 ],
337
- hover = f'Converted as { new_timestamp [1 ]} ' , parent_id = node .node_id ,
391
+ data_type = new_timestamp ['data_type' ], key = None , value = new_timestamp ['timestamp_value' ],
392
+ hover = f'Converted as { new_timestamp ["display_type" ]} ' , parent_id = node .node_id ,
338
393
incoming_edge_config = timestamp_edge )
0 commit comments