Civil Time

Now that we can schedule work in terms of a floating-point timestamp, let’s take a look at scheduling things in terms of years, months, days, hours, and minutes using fritter.drivers.datetime.DateTimeDriver.

Note

The following examples use the datetype library, but datetype.DateTime objects are actually just slightly better type-hints around datetime objects so you can type-check whether they have timezones or not with Mypy; at run-time, they are datetimes.

First, let’s get all our imports sorted out:

from datetime import datetime, timedelta
from datetype import DateTime, aware
from zoneinfo import ZoneInfo

from fritter.boundaries import TimeDriver, CivilScheduler
from fritter.drivers.memory import MemoryDriver
from fritter.drivers.datetimes import DateTimeDriver
from fritter.scheduler import schedulerFromDriver

We’ll need a driver, as usual. MemoryDriver, like other low-level drivers, is a float driver, which we will need first.

advancer = MemoryDriver()
base: TimeDriver[float] = advancer

DateTimeDriver is a wrapper around any TimeDriver[float], so we can wrap it around a memory driver (or, similarly, another TimeDriver[float] such as twisted, asyncio or just sleep). We need to create a time zone first — a ZoneInfo, specifically.

TZ = ZoneInfo("US/Pacific")
dtdriver: TimeDriver[DateTime[ZoneInfo]] = DateTimeDriver(base, TZ)

Next, we’ll pick a datetime as a reference point for our example.

dt = datetime(2023, 5, 5, tzinfo=TZ)

And catch our driver up to the timestamp that corresponds to the date.

advancer.advance(dt.timestamp() - advancer.now())

We’ll schedule some work using a timedelta, and then advance by a number of seconds which calls our callable.

scheduler.callAt(aware(dt, ZoneInfo) + timedelta(days=2), hi)
advancer.advance(2 * (60 * 60 * 24))

We will then see the ISO format of the timestamp print out, 2 days after our reference time of May 5, 2023:

hi 2023-05-07T00:00:00-07:00