Skip to content

Commit 708a36f

Browse files
committed
Add timezone section
- Clarified the behaviour of ZenML regarding timezone-aware and naive datetime inputs for scheduled runs. - Added detailed examples demonstrating how to set schedules using local and UTC timezones. - Included reminders about the interpretation of cron expressions in relation to system timezones. This update aims to help users avoid confusion with scheduled pipeline timings, ensuring they understand how to manage timezones effectively.
1 parent ae6d68d commit 708a36f

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

docs/book/user-guide/tutorials/managing-scheduled-pipelines.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ python run.py # or whatever you named your script
215215
> corresponding schedule in your orchestrator (Vertex AI in this example). You
216216
> can do this through the Google Cloud Console or using the orchestrator's API
217217
> (see below for code example).
218-
> ZenML's delete command may not always completely remove the underlying
218+
> ZenML's delete command never removes the underlying
219219
> orchestrator schedule.
220220
221221
## Step 4.1: Delete Schedule on GCP
@@ -322,6 +322,48 @@ for schedule in vertex_schedules:
322322

323323
Here are some practical fixes for issues you might encounter with your scheduled pipelines:
324324

325+
### Issue: Timezone Confusion with Scheduled Runs
326+
327+
A common issue with scheduled pipelines is timezone confusion. Here's how ZenML handles timezone information:
328+
329+
1. **If you provide a timezone-aware datetime**, ZenML will use it as is
330+
2. **If you provide a datetime without timezone information**, ZenML assumes it's in your local timezone and converts it to UTC for storage and communication with orchestrators
331+
332+
For cloud orchestrators like Vertex AI, Kubeflow, and Airflow, schedules typically run in the orchestrator's timezone, which is usually UTC. This can lead to confusion if you expect a schedule to run at 9 AM in your local timezone but it runs at 9 AM UTC instead.
333+
334+
To ensure your schedule runs at the expected time:
335+
336+
```python
337+
from datetime import datetime, timezone
338+
import pytz
339+
from zenml.config.schedule import Schedule
340+
341+
# Option 1: Explicitly use your local timezone (recommended)
342+
local_tz = pytz.timezone('America/Los_Angeles') # Replace with your timezone
343+
local_time = local_tz.localize(datetime(2025, 1, 1, 9, 0)) # 9 AM in your timezone
344+
schedule = Schedule(
345+
name="local-time-schedule",
346+
cron_expression="0 9 * * *",
347+
start_time=local_time # ZenML will convert to UTC internally
348+
)
349+
350+
# Option 2: Use UTC explicitly for clarity
351+
utc_time = datetime(2025, 1, 1, 17, 0, tzinfo=timezone.utc) # 5 PM UTC = 9 AM PST
352+
schedule = Schedule(
353+
name="utc-time-schedule",
354+
cron_expression="0 17 * * *", # Using UTC time in cron expression
355+
start_time=utc_time
356+
)
357+
358+
# To verify how ZenML interprets your times:
359+
from zenml.utils.time_utils import to_utc_timezone, to_local_tz
360+
print(f"Schedule will start at: {schedule.start_time} (as stored by ZenML)")
361+
print(f"In UTC that's: {to_utc_timezone(schedule.start_time)}")
362+
print(f"In your local time that's: {to_local_tz(schedule.start_time)}")
363+
```
364+
365+
Remember that cron expressions themselves don't have timezone information - they're interpreted in the timezone of the system executing them (which for cloud orchestrators is usually UTC).
366+
325367
### Issue: Schedule Doesn't Run at the Expected Time
326368

327369
If your pipeline doesn't run when scheduled:

0 commit comments

Comments
 (0)