Temporal and Duration Validation
Validate dates, times, and durations using the temporal schema types in pydantic-core. These schemas support strict or lax validation, range constraints, timezone enforcement, and precision handling.
Basic Temporal Validation
To validate a datetime, use cs.datetime_schema(). In lax mode (default), it accepts datetime objects, date objects, ISO8601 strings, and Unix timestamps.
from datetime import datetime, timezone
from pydantic_core import SchemaValidator, core_schema as cs
# Basic datetime validation
v = SchemaValidator(cs.datetime_schema())
# Validates from datetime object
v.validate_python(datetime(2022, 6, 8, 12, 13, 14))
# Validates from ISO8601 string (Lax mode)
v.validate_python('2022-06-08T12:13:14Z')
# Validates from Unix timestamp (Lax mode)
v.validate_python(1654646400)
# Returns: datetime(2022, 6, 8, 0, 0, tzinfo=timezone.utc)
Strict Mode
Enforce strict validation to reject strings and numeric timestamps, requiring actual Python objects.
v = SchemaValidator(cs.datetime_schema(strict=True))
# This will raise a ValidationError
try:
v.validate_python('2022-06-08T12:13:14')
except Exception as e:
print(e)
Range Constraints
All temporal schemas (DateSchema, TimeSchema, DatetimeSchema, TimedeltaSchema) support range constraints: le (less than or equal), ge (greater than or equal), lt (less than), and gt (greater than).
from datetime import datetime
from pydantic_core import SchemaValidator, core_schema as cs
# Datetime must be after Jan 1st, 2022
v = SchemaValidator(cs.datetime_schema(gt=datetime(2022, 1, 1)))
v.validate_python(datetime(2022, 6, 8)) # OK
# v.validate_python(datetime(2021, 12, 31)) # Raises ValidationError
Timezone Constraints
Use tz_constraint to enforce timezone awareness or specific offsets for DatetimeSchema and TimeSchema.
Enforcing Awareness
Set tz_constraint to 'aware' or 'naive'.
# Require timezone-aware datetimes
v = SchemaValidator(cs.datetime_schema(tz_constraint='aware'))
v.validate_python('2022-06-08T12:13:14Z') # OK
# v.validate_python('2022-06-08T12:13:14') # Raises ValidationError
Specific Offsets
Set tz_constraint to an integer representing the required UTC offset in seconds.
# Require UTC (offset 0)
v = SchemaValidator(cs.datetime_schema(tz_constraint=0))
v.validate_python('2022-06-08T12:13:14Z') # OK
# v.validate_python('2022-06-08T12:13:14+01:00') # Raises ValidationError (offset 3600)
Relative Validation (Past/Future)
DateSchema and DatetimeSchema support now_op for validating values relative to the current time.
# Validate that a date is in the past
v = SchemaValidator(cs.date_schema(now_op='past'))
# If today is 2023-10-27:
v.validate_python('2022-01-01') # OK
# v.validate_python('2099-01-01') # Raises ValidationError
You can control the "now" reference point using now_utc_offset. If not provided, it defaults to the local system's UTC offset.
Timedelta Formats
TimedeltaSchema supports a wide variety of input formats in lax mode, including ISO8601 durations, numeric seconds, and human-readable strings.
from datetime import timedelta
from pydantic_core import SchemaValidator, core_schema as cs
v = SchemaValidator(cs.timedelta_schema())
# ISO8601 Duration
v.validate_python('P2DT1H') # 2 days, 1 hour
# Numeric seconds
v.validate_python(3601) # 1 hour, 1 second
# Human readable
v.validate_python('123days, 12:34') # 123 days, 12 hours, 34 minutes
Microsecond Precision
By default, sub-microsecond precision is truncated. You can change this behavior using microseconds_precision.
# Fail if precision would be lost
v = SchemaValidator(cs.time_schema(microseconds_precision='error'))
# 6 digits is fine
v.validate_python('12:13:14.123456')
# 7 digits raises ValidationError
# v.validate_python('12:13:14.1234567')
Troubleshooting
Timezone Comparison Gotchas
When using now_op with timezone-naive inputs, the comparison is performed "dumbly" against the system time. If your input is naive but represents a time in a different zone, it may fail unexpectedly.
Unix Timestamp Limits
Unix timestamps are supported for dates between 0000-01-01 and 9999-12-31. Values outside this range (e.g., year 10000) will raise a ValidationError.
Date from Datetime
When validating a DateSchema, if a datetime object or string is provided, it must have zero time (midnight).
v = SchemaValidator(cs.date_schema())
v.validate_python('2022-06-08T00:00:00') # OK
# v.validate_python('2022-06-08T12:00:00') # Raises date_from_datetime_inexact
Temporal Units
When validating from numbers, the unit (seconds vs milliseconds) can be configured via the val_temporal_unit setting in the validator config. Options are 'seconds', 'milliseconds', or 'infer'.