Date/Time Fields
Handle date, time, and duration values stored in binary formats. These fields convert between
Python’s datetime objects and their binary representations.
Timestamp
The Timestamp field stores datetime objects as POSIX timestamps (seconds since midnight UTC
on January 1, 1970). It automatically converts between Python datetime objects and integer
timestamps.
created_at = steel.Timestamp()
modified_at = steel.Timestamp(timezone=ZoneInfo("America/New_York"))
Parameters
timezone: Timezone to use when converting timestamps to datetime objects (default: UTC). Must be a
ZoneInfoobject. Alldatetimeobjects produced by this field will have this timestamp attached to them, so that conversions can be done properly. Can be specified at the structure level.
Warning
This field uses its timezone attribute to automatically convert the timestamp to UTC before
writing out the data, and it assumes all input is in UTC. If you need to read or write data in a
local timezone instead of UTC, consider writing a custom field.
Example Usage
from datetime import datetime
from zoneinfo import ZoneInfo
import steel
class LogEntry(steel.Structure):
timestamp = steel.Timestamp(timezone=ZoneInfo("UTC"))
level = steel.Integer(size=1)
# Create with current time
entry = LogEntry(timestamp=datetime.now(), level=1)
buffer = BytesIO()
entry.write(buffer)
Naive datetime objects
`datetime` objects can be created without specifying a timezone, which are considered to be
“naive”. These can introduce uncertainty when converting to explicit timezones elsewhere. Python’s
own behavior is to use the system’s local timezone for timezone-aware operations, under the
assumption that the time in the object is valid for the computer running the code.
Steel doesn’t need to make that assumption, because a timezone is always configured into the
Timestamp field itself. So any naive datetime objects that are supplied for this field will
automatically have the field’s timezone applied to them before converting to UTC during the writing
process.
Important
Just to be very clear, Steel’s behavior for naive datetime objects differs from Python’s own
behavior. Steel has access to more information and can be more consistent. If your programs are
relying on an implicit local timezone, it’s best to either specify that same timezone on all of
your Timestamp fields or add it to your datetime objects directly, making them
timezone-aware.
Duration
The Duration field handles lengths of time as a number of seconds. Because Python’s timedelta
objects include fractional seconds, Duration fields store their values using a 4-byte
FloatField internally.
timeout = steel.Duration()
interval = steel.Duration()
Note
Any use of floating-point values has a possibility of losing a small amount of precision. Even
though Duration doesn’t directly do any mathematical calculations that would affect the
precision of the provided value, a roundtrip conversion from Python to a file and back can result
in a slightly different value. This is simply part of the nature of working with floating-point
numbers.
Example Usage
from datetime import timedelta
import steel
class TaskConfig(steel.Structure):
timeout = steel.Duration()
retry_interval = steel.Duration()
config = TaskConfig(
timeout=timedelta(minutes=5),
retry_interval=timedelta(seconds=2.5),
)