|
32 | 32 | import firebase_functions.options as _options |
33 | 33 | import firebase_functions.private.util as _util |
34 | 34 | from firebase_functions.core import _with_init |
35 | | -import dateutil.parser as dateutil_parser |
36 | 35 |
|
37 | 36 | # Re-export Timezone from options module so users can import it directly from scheduler_fn |
38 | 37 | # This provides a more convenient API: from firebase_functions.scheduler_fn import Timezone |
@@ -105,11 +104,24 @@ def on_schedule_wrapped(request: _Request) -> _Response: |
105 | 104 | schedule_time = _dt.datetime.utcnow() |
106 | 105 | else: |
107 | 106 | try: |
108 | | - # Robust RFC 3339 parsing |
109 | | - schedule_time = dateutil_parser.isoparse(schedule_time_str) |
110 | | - except ValueError as e: |
111 | | - print(f"Failed to parse RFC 3339 timestamp: {e}") |
112 | | - schedule_time = _dt.utcnow() |
| 107 | + # Try to parse with the stdlib which supports fractional |
| 108 | + # seconds and offsets in Python 3.11+ via fromisoformat. |
| 109 | + # Normalize RFC3339 'Z' to '+00:00' for fromisoformat. |
| 110 | + iso_str = schedule_time_str |
| 111 | + if iso_str.endswith("Z"): |
| 112 | + iso_str = iso_str[:-1] + "+00:00" |
| 113 | + schedule_time = _dt.datetime.fromisoformat(iso_str) |
| 114 | + except Exception: |
| 115 | + # Fallback to strict parsing without fractional seconds |
| 116 | + try: |
| 117 | + schedule_time = _dt.datetime.strptime( |
| 118 | + schedule_time_str, |
| 119 | + "%Y-%m-%dT%H:%M:%S%z", |
| 120 | + ) |
| 121 | + except Exception as e: |
| 122 | + # If all parsing fails, log and use current UTC time |
| 123 | + _logging.exception(e) |
| 124 | + schedule_time = _dt.datetime.utcnow() |
113 | 125 | event = ScheduledEvent( |
114 | 126 | job_name=request.headers.get("X-CloudScheduler-JobName"), |
115 | 127 | schedule_time=schedule_time, |
|
0 commit comments