fasttime is a fast, lightweight UTC-focused date/time library for Python, powered by Rust. It provides simple, ergonomic APIs for working with dates, times, and durations with nanosecond precision.
- Fast: Built with Rust using Ben Joffe's constant-time 64-bit days→date algorithm
- Simple: Clean, Pythonic API for common date/time operations
- Precise: Nanosecond precision for all time values
- UTC-focused: All datetime operations are in UTC by default
- RFC 3339 support: Parse and format timestamps with fixed offsets
- Type-safe: Full type hints for better IDE support and type checking
pip install fasttime-rsRequires Python 3.10 or later.
import fasttime
# Create dates
date = fasttime.Date(2024, 1, 15)
print(date) # 2024-01-15
print(date.weekday()) # Weekday.Monday
print(date.ordinal()) # 15
# Work with times
time = fasttime.Time(14, 30, 45, nanosecond=123_456_789)
print(time) # 14:30:45.123456789
# Combine into UTC datetimes
dt = fasttime.DateTime(date, time)
print(dt) # 2024-01-15T14:30:45.123456789Z
# Get current UTC time
now = fasttime.DateTime.now_utc()
print(f"Current UTC time: {now}")
# Work with durations
later = now.add_duration(fasttime.Duration.seconds(3600))
diff = later.difference(now)
print(f"Difference: {diff.total_seconds()} seconds")
# Parse from strings
parsed_date = fasttime.Date.parse("2024-12-25")
parsed_time = fasttime.Time.parse("23:59:59.999")
parsed_dt = fasttime.DateTime.parse("2024-12-25T23:59:59.999Z")
# Work with time zones (fixed offsets)
offset = fasttime.UtcOffset.from_hours_minutes(True, 5, 30) # +05:30
local_dt = fasttime.OffsetDateTime.from_local(date, time, offset)
print(local_dt) # 2024-01-15T14:30:45.123456789+05:30
# Unix timestamps
timestamp = dt.unix_timestamp() # seconds
timestamp_ns = dt.unix_timestamp_nanos() # nanoseconds
dt_from_ts = fasttime.DateTime.from_unix_timestamp(timestamp, 123_456_789)DateTime and Duration support pickle.dumps() and pickle.loads() with all
pickle protocols supported by your Python version. Integer nanoseconds preserve
full precision, including negative values and the complete supported value ranges.
import pickle
import fasttime
before_epoch = fasttime.DateTime.from_unix_timestamp(0, -1)
restored = pickle.loads(pickle.dumps(before_epoch))
assert restored == before_epoch
assert restored.unix_timestamp_nanos() == -1
assert hash(restored) == hash(before_epoch)
duration = fasttime.Duration.nanoseconds(-1_000_000_001)
assert pickle.loads(pickle.dumps(duration)).total_nanos() == -1_000_000_001Reconstruction uses the public Duration.nanoseconds() and
DateTime.from_unix_timestamp() methods. The other fasttime types do not yet
support pickling. As with any pickle data, only deserialize trusted inputs.
A Gregorian calendar date (year, month, day).
# Constructor
date = fasttime.Date(year: int, month: int, day: int)
# Properties
date.year: int # Year (i32 range)
date.month: int # Month (1-12)
date.day: int # Day (1-31)
# Methods
date.weekday() -> Weekday # Get day of week
date.ordinal() -> int # Day of year (1-366)
date.add_days(days: int) -> Date # Add/subtract days
date.days_since_unix_epoch() -> int # Days since 1970-01-01
# Class methods
Date.from_days_since_unix_epoch(days: int) -> Date
Date.parse(s: str) -> Date # Parse "YYYY-MM-DD"A time of day with nanosecond precision.
# Constructor
time = fasttime.Time(hour: int, minute: int, second: int, nanosecond: int = 0)
# Properties
time.hour: int # Hour (0-23)
time.minute: int # Minute (0-59)
time.second: int # Second (0-59)
time.nanosecond: int # Nanosecond (0-999,999,999)
# Methods
time.seconds_since_midnight() -> int # Total seconds (ignoring nanos)
time.nanos_since_midnight() -> int # Total nanoseconds
# Class methods
Time.parse(s: str) -> Time # Parse "HH:MM:SS[.fffffffff]"A UTC date and time.
# Constructor
dt = fasttime.DateTime(date: Date, time: Time)
# Properties
dt.date: Date
dt.time: Time
# Methods
dt.unix_timestamp() -> int # Seconds since Unix epoch
dt.unix_timestamp_nanos() -> int # Nanoseconds since Unix epoch
dt.add_duration(dur: Duration) -> DateTime # Add a duration
dt.difference(other: DateTime) -> Duration # Calculate difference
# Class methods
DateTime.from_unix_timestamp(secs: int, nanos: int = 0) -> DateTime
DateTime.now_utc() -> DateTime # Current UTC time
DateTime.parse(s: str) -> DateTime # Parse "YYYY-MM-DDTHH:MM:SS[.fff]Z"A signed duration with nanosecond precision.
# Class methods (constructors)
Duration.seconds(secs: int) -> Duration
Duration.milliseconds(ms: int) -> Duration
Duration.microseconds(us: int) -> Duration
Duration.nanoseconds(ns: int) -> Duration
# Methods
dur.total_seconds() -> float # Total seconds as float
dur.total_nanos() -> int # Total nanoseconds as int
# Operators
dur1 + dur2 # Add durations
dur1 - dur2 # Subtract durations
-dur # Negate duration
dur1 < dur2 # Compare durationsA fixed offset from UTC.
# Class methods
UtcOffset.from_seconds(seconds: int) -> UtcOffset
UtcOffset.from_hours_minutes(sign_positive: bool, hours: int, minutes: int) -> UtcOffset
# Methods
offset.as_seconds() -> int # Total offset in seconds
offset.is_utc() -> bool # True if offset is zeroA datetime with a fixed UTC offset (RFC 3339 style).
# Class methods
OffsetDateTime.from_utc(utc: DateTime, offset: UtcOffset) -> OffsetDateTime
OffsetDateTime.from_local(date: Date, time: Time, offset: UtcOffset) -> OffsetDateTime
OffsetDateTime.parse(s: str) -> OffsetDateTime # Parse RFC 3339
# Properties
odt.utc: DateTime # UTC datetime
odt.offset: UtcOffset # Offset from UTC
# Methods
odt.to_local() -> DateTime # Convert to local datetime
odt.unix_timestamp() -> int # Seconds since Unix epoch
odt.unix_timestamp_nanos() -> int # Nanoseconds since Unix epoch
odt.add_duration(dur: Duration) -> OffsetDateTime # Add a duration
odt.difference(other: OffsetDateTime) -> Duration # Calculate differenceAn enumeration of weekdays (ISO order, Monday = 1).
# Constants
Weekday.MONDAY
Weekday.TUESDAY
Weekday.WEDNESDAY
Weekday.THURSDAY
Weekday.FRIDAY
Weekday.SATURDAY
Weekday.SUNDAY
# Methods
weekday.number_from_monday() -> int # 1-7See the python/examples/ directory for more examples:
basic_usage.py- Common operationsparsing.py- Parsing dates and timesdurations.py- Working with durationstimezones.py- Fixed offset timezonesunix_timestamps.py- Unix timestamp conversions
| Feature | fasttime | datetime (stdlib) | pendulum | arrow |
|---|---|---|---|---|
| Speed | ⚡ Very Fast (Rust) | Fast (C) | Moderate | Moderate |
| Nanosecond precision | ✅ | ❌ (microsecond) | ❌ (microsecond) | ❌ (microsecond) |
| UTC-focused | ✅ | Partial | ❌ | ❌ |
| RFC 3339 parsing | ✅ | ✅ | ✅ | ✅ |
| Timezone database | ❌ (fixed offset only) | ❌ | ✅ | ✅ |
| Dependencies | None (after build) | None | Many | Many |
| Memory footprint | Small | Small | Large | Large |
When to use fasttime:
- You need UTC timestamps and simple date/time operations
- You want nanosecond precision
- You prefer a minimal, fast library without heavy dependencies
- You're working with logs, metrics, or APIs using ISO 8601/RFC 3339
When to use other libraries:
- You need full timezone database support (use
pendulumorzoneinfo) - You need complex calendar/business day calculations
- You're already using the standard library and don't need extra precision
fasttime is built with Rust and uses highly optimized algorithms for date/time conversions:
- Days ↔ Date conversion: Uses Ben Joffe's constant-time algorithm (no division/modulo)
- Unix timestamp conversion: O(1) operations
- Parsing: Minimal allocations, direct byte processing
Typical operations complete in microseconds, making it suitable for high-throughput applications.
# Install maturin
pip install maturin
# Build the package
maturin develop
# Run tests
pytest python/tests/python python/examples/basic_usage.pyLicensed under the Apache License, Version 2.0. See LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.