0
# Date/Time Utilities
1
2
Utilities for handling datetime objects in Google APIs, including RFC3339 formatting, timezone handling, and high-precision timestamps with nanosecond support.
3
4
## Capabilities
5
6
### High-Precision Datetime Class
7
8
Extended datetime class with nanosecond precision for Google API timestamps.
9
10
```python { .api }
11
class DatetimeWithNanoseconds(datetime.datetime):
12
"""
13
Datetime subclass that adds nanosecond precision.
14
15
Args:
16
year (int): Year
17
month (int): Month (1-12)
18
day (int): Day of month (1-31)
19
hour (int, optional): Hour (0-23)
20
minute (int, optional): Minute (0-59)
21
second (int, optional): Second (0-59)
22
microsecond (int, optional): Microsecond (0-999999)
23
nanosecond (int, optional): Nanosecond component (0-999)
24
tzinfo: Timezone information
25
**kwargs: Additional datetime arguments
26
"""
27
def __new__(cls, year, month, day, hour=0, minute=0, second=0, microsecond=0, nanosecond=0, tzinfo=None, **kwargs): ...
28
29
@property
30
def nanosecond(self):
31
"""
32
Nanosecond component (0-999).
33
34
Returns:
35
int: Nanosecond value
36
"""
37
38
def timestamp(self):
39
"""
40
Get timestamp with nanosecond precision.
41
42
Returns:
43
float: Timestamp including nanoseconds
44
"""
45
46
def rfc3339(self):
47
"""
48
Format as RFC3339 string with nanosecond precision.
49
50
Returns:
51
str: RFC3339 formatted timestamp
52
"""
53
```
54
55
### Time Conversion Functions
56
57
Functions for converting between different time representations used in Google APIs.
58
59
```python { .api }
60
def utcnow():
61
"""
62
Get current UTC datetime (mockable version of datetime.utcnow).
63
64
Returns:
65
datetime.datetime: Current UTC datetime
66
"""
67
68
def to_milliseconds(value):
69
"""
70
Convert datetime to milliseconds since Unix epoch.
71
72
Args:
73
value (datetime.datetime): Datetime to convert
74
75
Returns:
76
int: Milliseconds since epoch
77
"""
78
79
def from_microseconds(value):
80
"""
81
Convert microseconds since epoch to datetime.
82
83
Args:
84
value (int): Microseconds since Unix epoch
85
86
Returns:
87
datetime.datetime: Converted datetime in UTC
88
"""
89
90
def to_microseconds(value):
91
"""
92
Convert datetime to microseconds since Unix epoch.
93
94
Args:
95
value (datetime.datetime): Datetime to convert
96
97
Returns:
98
int: Microseconds since epoch
99
"""
100
```
101
102
### RFC3339 Parsing and Formatting
103
104
Functions for parsing and formatting RFC3339 timestamps with timezone support.
105
106
```python { .api }
107
def from_rfc3339(value):
108
"""
109
Parse RFC3339 timestamp string to datetime with nanosecond precision.
110
111
Args:
112
value (str): RFC3339 formatted timestamp string
113
114
Returns:
115
DatetimeWithNanoseconds: Parsed datetime with nanosecond precision
116
"""
117
118
def to_rfc3339(value, ignore_zone=True):
119
"""
120
Convert datetime to RFC3339 formatted string.
121
122
Args:
123
value (datetime.datetime): Datetime to format
124
ignore_zone (bool): Whether to ignore timezone info (default: True)
125
126
Returns:
127
str: RFC3339 formatted timestamp string
128
"""
129
130
def from_rfc3339_nanos(value):
131
"""
132
Deprecated alias for from_rfc3339.
133
134
Args:
135
value (str): RFC3339 formatted timestamp string
136
137
Returns:
138
DatetimeWithNanoseconds: Parsed datetime
139
"""
140
```
141
142
### ISO8601 Parsing
143
144
Functions for parsing ISO8601 date and time strings.
145
146
```python { .api }
147
def from_iso8601_date(value):
148
"""
149
Parse ISO8601 date string to datetime.
150
151
Args:
152
value (str): ISO8601 date string (YYYY-MM-DD)
153
154
Returns:
155
datetime.datetime: Parsed date as datetime at midnight UTC
156
"""
157
158
def from_iso8601_time(value):
159
"""
160
Parse ISO8601 time string to datetime.
161
162
Args:
163
value (str): ISO8601 time string (HH:MM:SS or HH:MM:SS.fff)
164
165
Returns:
166
datetime.datetime: Parsed time as datetime on epoch date
167
"""
168
```
169
170
## Usage Examples
171
172
### Working with Nanosecond Precision
173
174
```python
175
from google.api_core import datetime_helpers
176
from datetime import datetime, timezone
177
178
# Create datetime with nanosecond precision
179
precise_time = datetime_helpers.DatetimeWithNanoseconds(
180
2023, 12, 25, 14, 30, 45, 123456, nanosecond=789,
181
tzinfo=timezone.utc
182
)
183
184
print(f"Nanoseconds: {precise_time.nanosecond}")
185
print(f"RFC3339: {precise_time.rfc3339()}")
186
print(f"Timestamp: {precise_time.timestamp()}")
187
188
# Convert to/from microseconds with nanosecond precision
189
microseconds = datetime_helpers.to_microseconds(precise_time)
190
recovered = datetime_helpers.from_microseconds(microseconds)
191
print(f"Microseconds: {microseconds}")
192
```
193
194
### RFC3339 Timestamp Handling
195
196
```python
197
from google.api_core import datetime_helpers
198
199
# Parse RFC3339 timestamps from API responses
200
api_timestamp = "2023-12-25T14:30:45.123456789Z"
201
parsed_time = datetime_helpers.from_rfc3339(api_timestamp)
202
203
print(f"Parsed time: {parsed_time}")
204
print(f"Nanoseconds: {parsed_time.nanosecond}")
205
print(f"Year: {parsed_time.year}")
206
207
# Format datetime for API requests
208
current_time = datetime_helpers.utcnow()
209
rfc3339_string = datetime_helpers.to_rfc3339(current_time)
210
print(f"Current time RFC3339: {rfc3339_string}")
211
212
# Handle timezone-aware timestamps
213
timezone_timestamp = "2023-12-25T14:30:45.123-08:00"
214
parsed_tz = datetime_helpers.from_rfc3339(timezone_timestamp)
215
print(f"Timezone aware: {parsed_tz}")
216
```
217
218
### API Response Processing
219
220
```python
221
from google.api_core import datetime_helpers
222
import json
223
224
def process_api_response(response_data):
225
"""Process API response with timestamp fields."""
226
processed = {}
227
228
for key, value in response_data.items():
229
if key.endswith('_time') or key.endswith('_timestamp'):
230
# Convert timestamp strings to datetime objects
231
if isinstance(value, str):
232
try:
233
processed[key] = datetime_helpers.from_rfc3339(value)
234
except ValueError:
235
# Fallback for other timestamp formats
236
processed[key] = value
237
else:
238
processed[key] = value
239
else:
240
processed[key] = value
241
242
return processed
243
244
# Example API response
245
api_response = {
246
"id": "123",
247
"name": "Resource",
248
"created_time": "2023-12-25T14:30:45.123456789Z",
249
"updated_time": "2023-12-25T15:45:30.987654321Z",
250
"status": "active"
251
}
252
253
processed = process_api_response(api_response)
254
print(f"Created: {processed['created_time']}")
255
print(f"Updated: {processed['updated_time']}")
256
```
257
258
### Time Range Queries
259
260
```python
261
from google.api_core import datetime_helpers
262
from datetime import datetime, timedelta, timezone
263
264
def create_time_range_filter(days_back=7):
265
"""Create time range filter for API queries."""
266
now = datetime_helpers.utcnow()
267
start_time = now - timedelta(days=days_back)
268
269
return {
270
"start_time": datetime_helpers.to_rfc3339(start_time),
271
"end_time": datetime_helpers.to_rfc3339(now)
272
}
273
274
# Create filter for last 30 days
275
time_filter = create_time_range_filter(30)
276
print(f"Query range: {time_filter['start_time']} to {time_filter['end_time']}")
277
278
def query_logs_by_time_range(start_time, end_time):
279
"""Query logs within time range."""
280
request = {
281
"filter": f"timestamp >= '{start_time}' AND timestamp <= '{end_time}'",
282
"order_by": "timestamp desc"
283
}
284
285
# Make API call with time range filter
286
return request
287
288
query = query_logs_by_time_range(
289
time_filter["start_time"],
290
time_filter["end_time"]
291
)
292
```
293
294
### Millisecond Precision Operations
295
296
```python
297
from google.api_core import datetime_helpers
298
import time
299
300
# Work with millisecond timestamps (common in APIs)
301
current_millis = int(time.time() * 1000)
302
print(f"Current milliseconds: {current_millis}")
303
304
# Convert datetime to milliseconds for API calls
305
now = datetime_helpers.utcnow()
306
millis = datetime_helpers.to_milliseconds(now)
307
print(f"Datetime to millis: {millis}")
308
309
# Convert API millisecond response back to datetime
310
api_millis = 1703516245123 # Example from API
311
dt_from_millis = datetime.utcfromtimestamp(api_millis / 1000.0)
312
print(f"Millis to datetime: {dt_from_millis}")
313
314
# High precision timing
315
def measure_operation_time():
316
"""Measure operation with high precision."""
317
start = datetime_helpers.utcnow()
318
319
# Simulate some operation
320
time.sleep(0.1)
321
322
end = datetime_helpers.utcnow()
323
324
duration_micros = (
325
datetime_helpers.to_microseconds(end) -
326
datetime_helpers.to_microseconds(start)
327
)
328
329
print(f"Operation took {duration_micros} microseconds")
330
return duration_micros
331
332
measure_operation_time()
333
```
334
335
### Timezone Handling
336
337
```python
338
from google.api_core import datetime_helpers
339
from datetime import datetime, timezone, timedelta
340
341
# Parse timestamps with different timezone formats
342
timestamps = [
343
"2023-12-25T14:30:45Z", # UTC
344
"2023-12-25T14:30:45.123Z", # UTC with milliseconds
345
"2023-12-25T14:30:45+00:00", # UTC with offset
346
"2023-12-25T14:30:45-08:00", # Pacific Standard Time
347
"2023-12-25T14:30:45.123456+05:30" # India Standard Time with microseconds
348
]
349
350
for ts in timestamps:
351
parsed = datetime_helpers.from_rfc3339(ts)
352
# Convert to UTC for consistent handling
353
utc_time = parsed.replace(tzinfo=timezone.utc) if parsed.tzinfo is None else parsed.astimezone(timezone.utc)
354
print(f"Original: {ts}")
355
print(f"UTC: {datetime_helpers.to_rfc3339(utc_time)}")
356
print("---")
357
```