test_datetime.py
Overview
`test_datetime.py` is a comprehensive test suite designed to validate the serialization of Python `datetime`, `date`, and `time` objects using the `orjson` library. The file contains multiple test classes, each focusing on different aspects of date and time serialization, including timezone handling, microsecond precision, edge cases (minimum and maximum values), and compatibility with various timezone libraries such as `zoneinfo`, `pytz`, `pendulum`, and `dateutil.tz`.
This suite ensures that `orjson` correctly serializes datetime-related objects into JSON-compliant ISO 8601 strings, respecting timezone offsets, handling optional serialization flags, and following RFC 3339 standards where applicable.
Detailed Explanations
Imported Modules and Setup
datetime: Standard Python library for date and time types.pytest: Testing framework used for running and marking tests.orjson: Ultra-fast JSON serialization library being tested.Optional timezone libraries:
zoneinfo(Python 3.9+ standard lib; fallback if not installed)pytzpendulumdateutil.tz
The code conditionally imports these timezone libraries and disables them if unavailable. This allows tests to run or skip accordingly.
Constants
AMSTERDAM_1937_DATETIMES: Tuple of expected JSON byte strings representing a historical datetime in Amsterdam with different timezone offset representations, used to verify serialization correctness with partial-second precision and non-standard offsets.AMSTERDAM_1937_DATETIMES_WITH_Z: Similar to the above but includes a representation with a 'Z' suffix (UTC), used in tests with UTC-Z option.
Class: TestDatetime
This class contains tests for `datetime.datetime` objects serialization.
Key Methods:
test_datetime_naive(self):
Tests serialization of naive (timezone-unaware) datetime without offset.
Example:orjson.dumps([datetime.datetime(2000, 1, 1, 2, 3, 4, 123)]) # Expected: b'["2000-01-01T02:03:04.000123"]'test_datetime_naive_utc(self):
Tests naive datetime serialization assuming UTC when theOPT_NAIVE_UTCoption is set.
Option:orjson.OPT_NAIVE_UTCappends+00:00offset to naive datetimes.test_datetime_min(self)andtest_datetime_max(self):
Validate serialization of minimum and maximum representable datetime values.test_datetime_three_digits(self)andtest_datetime_two_digits(self):
Test serialization of years with 3 and 2 digits, ensuring zero-padding to 4 digits in output.test_datetime_tz_assume(self):
Usesdateutil.tzto attach timezone info and test serialization withOPT_NAIVE_UTC.test_datetime_timezone_utc(self)and related tests withpytz,zoneinfo,pendulum, anddateutil.tz:
Verify that timezone-aware datetimes serialize with correct ISO 8601 offsets, including positive/negative offsets and daylight saving time (DST) adjustments.test_datetime_omit_microseconds(self):
Tests theOPT_OMIT_MICROSECONDSoption, which removes microseconds from the output string.test_datetime_utc_z_naive(self)and related:
Tests theOPT_UTC_Zoption, which serializes UTC datetimes with a trailingZinstead of+00:00.test_datetime_roundtrip(self):
Verifies serialization followed by parsing back (usingpendulum) preserves all datetime attributes.
Class: TestDate
Tests serialization of `datetime.date` objects.
test_date(self): Basic date serialization.test_date_min(self)andtest_date_max(self): Edge cases.test_date_three_digits(self)andtest_date_two_digits(self): Year padding tests.
Class: TestTime
Tests serialization of `datetime.time` objects.
test_time(self): Serialization with and without microseconds.test_time_tz(self): Tests that serializingtimeobjects with timezone info raisesorjson.JSONEncodeError(timezone-awaretimeis unsupported).test_time_microsecond_max(self)andtest_time_microsecond_min(self): Microsecond boundary tests.
Class: TestDateclassPassthrough
Tests behavior of `orjson.OPT_PASSTHROUGH_DATETIME` option.
When this option is set,
orjsonraises aJSONEncodeErrorfordatetime,date, andtimeobjects if no custom serializer is provided.Demonstrates usage of the
defaultcallable to customize serialization format (e.g., RFC 1123 format string).
Important Implementation Details and Algorithms
The tests heavily rely on the
orjsonserialization options:OPT_NAIVE_UTC: Treat naive datetime as UTC.OPT_OMIT_MICROSECONDS: Omit microseconds if zero/non-zero.OPT_UTC_Z: Represent UTC timezone as 'Z' instead of '+00:00'.OPT_PASSTHROUGH_DATETIME: Pass through datetime types without serializing, leading to errors unless a default handler is provided.
Timezone-aware datetime serialization respects the offset returned by
tzinfo.utcoffset(). This supports complex cases including partial hour offsets (e.g., +10:30 in Australia/Adelaide) and historical DST changes (e.g., America/New_York offsets).Partial second precision is tested against RFC 3339 section 5.8 recommendations, ensuring correct handling of fractional seconds and offsets.
The tests use conditional skipping based on availability of optional timezone libraries, enabling flexible testing environments.
Interactions with Other Parts of the System
This file is a test module primarily interacting with the
orjsonlibrary, specifically its datetime serialization capabilities.It indirectly interacts with timezone libraries (
zoneinfo,pytz,pendulum,dateutil.tz) to validate correct handling of timezone-aware datetime objects.It uses
pytestfor test execution and marking tests to skip when optional dependencies are missing.The serialization output is verified against expected byte strings, ensuring consistent JSON output from
orjson.
Usage Examples
import datetime
import orjson
# Serialize naive datetime (no timezone)
print(orjson.dumps([datetime.datetime(2024, 1, 1, 12, 0, 0)]))
# Output: b'["2024-01-01T12:00:00"]'
# Serialize naive datetime assuming UTC offset
print(
orjson.dumps(
[datetime.datetime(2024, 1, 1, 12, 0, 0)],
option=orjson.OPT_NAIVE_UTC,
)
)
# Output: b'["2024-01-01T12:00:00+00:00"]'
# Serialize datetime with timezone from zoneinfo
from zoneinfo import ZoneInfo
dt = datetime.datetime(2024, 1, 1, 12, 0, 0, tzinfo=ZoneInfo("Asia/Tokyo"))
print(orjson.dumps([dt]))
# Output: b'["2024-01-01T12:00:00+09:00"]'
Visual Diagram
classDiagram
class TestDatetime {
+test_datetime_naive()
+test_datetime_naive_utc()
+test_datetime_min()
+test_datetime_max()
+test_datetime_three_digits()
+test_datetime_two_digits()
+test_datetime_tz_assume()
+test_datetime_timezone_utc()
+test_datetime_pytz_utc()
+test_datetime_zoneinfo_utc()
+test_datetime_zoneinfo_positive()
+test_datetime_zoneinfo_negative()
+test_datetime_pendulum_utc()
+test_datetime_arrow_positive()
+test_datetime_pytz_positive()
+test_datetime_pendulum_positive()
+test_datetime_pytz_negative_dst()
+test_datetime_pendulum_negative_dst()
+test_datetime_zoneinfo_negative_non_dst()
+test_datetime_pytz_negative_non_dst()
+test_datetime_pendulum_negative_non_dst()
+test_datetime_zoneinfo_partial_hour()
+test_datetime_pytz_partial_hour()
+test_datetime_pendulum_partial_hour()
+test_datetime_partial_second_pendulum_supported()
+test_datetime_partial_second_zoneinfo()
+test_datetime_partial_second_pytz()
+test_datetime_partial_second_dateutil()
+test_datetime_microsecond_max()
+test_datetime_microsecond_min()
+test_datetime_omit_microseconds()
+test_datetime_omit_microseconds_naive()
+test_datetime_utc_z_naive_omit()
+test_datetime_utc_z_naive()
+test_datetime_utc_z_without_tz()
+test_datetime_utc_z_with_tz()
+test_datetime_roundtrip()
}
class TestDate {
+test_date()
+test_date_min()
+test_date_max()
+test_date_three_digits()
+test_date_two_digits()
}
class TestTime {
+test_time()
+test_time_tz()
+test_time_microsecond_max()
+test_time_microsecond_min()
}
class TestDateclassPassthrough {
+test_passthrough_datetime()
+test_passthrough_date()
+test_passthrough_time()
+test_passthrough_datetime_default()
}
TestDatetime --> orjson : uses
TestDate --> orjson : uses
TestTime --> orjson : uses
TestDateclassPassthrough --> orjson : uses
Summary
`test_datetime.py` is a pytest-based test suite for validating `orjson` serialization of datetime-related types across various scenarios including naive and timezone-aware datetimes, edge cases, and serialization options. It supports testing with multiple timezone libs and ensures JSON outputs conform to ISO 8601 and RFC 3339 standards. The suite is essential for maintaining the correctness and robustness of datetime serialization in `orjson`.