Skip to main content

Flexible datetime handling for Python

Project description

Flexible Datetime

A Python library providing flexible datetime creation and handling with masked comparison capabilities, built on Arrow and Pydantic.

Features

Parse dates and times from:

  • ISO format strings
  • Partial dates ("2023-06", "2023")
  • Natural language ("June 15th, 2023", "next thursday")
  • Component dictionaries ({"year": 2023, "month": 6})
  • Python datetime/date objects
  • Arrow objects
  • Compact duration strings (2w1d, 1y 1mo 1d, 2h30m)
  • Component masking for selective comparisons
  • Multiple serialization formats

Installation

pip install flexible-datetime

Usage

from flexible_datetime import flex_datetime, flex_delta

# Parse various formats
ft = flex_datetime("2023-06")                      # Partial date
ft = flex_datetime({"year": 2023, "month": 6})     # From components
ft = flex_datetime("next thursday at 2pm")         # Natural language
ft = flex_datetime("2023-06-15T14:30:45")          # ISO format

print(ft) 
# Output: 2023-06-15T14:30:45

# Parse flexible durations
delta = flex_delta("2w1d")
delta = flex_delta("1y 1mo 1d")
delta = flex_delta(hours=2, minutes=30)

print(delta)
# Output: 2h30m

Output Formats

ft = flex_datetime("2023-06-15")          # ISO format

# Choose output formats
print(ft) # default: Serialize as shortest possible datetime format.                      
# Output: 2023-06-15
print(ft.to_str("flex")) # JSON with mask           
# Output: {'dt': '2023-06-15T00:00:00+00:00', 'mask': '0001111'}

print(ft.to_str("datetime")) # Full ISO format
# Output: 2023-06-15T00:00:00+00:00
print(ft.to_str("components")) # Component dict
# Output {'year': 2023, 'month': 6, 'day': 15}

Component Masking

Mask specific components for flexible comparisons:

# Mask specific components
ft = flex_datetime("2023-06-15T14:30")
ft.apply_mask(hour=True, minute=True)  # Mask time components
print(ft)                              # "2023-06-15"

# Clear all masks
ft.clear_mask()

# Use only specific components
ft.use_only("year", "month")           # Only use year and month
print(ft)                              # "2023-06"

# Use masking for flexible comparisons
ft1 = flex_datetime("2023-01-15")
ft2 = flex_datetime("2024-01-15")
ft1.apply_mask(year=True) # Mask the year
ft2.apply_mask(year=True) # Mask the year
print(ft1 == ft2) # True - years are masked

Component Access

Access individual components directly:

ft = flex_datetime("2023-06-15T14:30")
print(ft.year)                          # 2023
print(ft.month)                         # 6
print(ft.day)                           # 15
print(ft.hour)                          # 14
print(ft.minute)                        # 30

Flexible Durations

flex_delta supports compact duration parsing and calendar-aware arithmetic.

from datetime import date, datetime

from flexible_datetime import FlexDateTime, flex_datetime, flex_delta

delta = flex_delta("1y 1mo 1d")
print(delta)                            # "1y1mo1d"
print(delta.to_components())            # {"years": 1, "months": 1, "days": 1}

fixed = flex_delta("2w1d3h15m")
print(fixed.to_timedelta())             # datetime.timedelta(days=15, seconds=11700)

calendar = flex_delta("1mo")
print(calendar.to_relativedelta())      # relativedelta(months=+1)

print(date(2024, 1, 31) + flex_delta("1mo"))
# 2024-02-29

print(datetime(2024, 1, 1, 8, 30) + flex_delta("2w1d"))
# 2024-01-16 08:30:00

print(flex_datetime("2024-03") - flex_delta("1mo"))
# 2024-02

print(FlexDateTime("2024-01") + flex_delta("1mo"))
# 2024-02

Supported short units:

  • y: years
  • mo: months
  • w: weeks
  • d: days
  • h: hours
  • m: minutes
  • s: seconds
  • us: microseconds

Notes:

  • m means minutes, while mo means months.
  • Spaced and comma-separated forms are accepted: 1y 1mo 1d, 1y, 1mo, 1d.
  • to_timedelta() only works for fixed units. Durations containing years or months should use to_relativedelta() or direct arithmetic with a date/datetime.

Output Format Specific Classes

The library provides specialized classes for when you know you'll consistently need a specific output format:

from flexible_datetime import dict_datetime, iso_datetime, mask_datetime, short_datetime

# Component format - outputs as dictionary of datetime components
ct = dict_datetime("2023-06-15T14:30")
print(ct)  
# {"year": 2023, "month": 6, "day": 15, "hour": 14, "minute": 30}

# Minimal format - outputs shortest possible datetime representation
mt = short_datetime("2023-06-15T14:30")
print(mt)  
# "2023-06-15T14:30"

# ISO format - outputs full ISO8601 datetime
it = iso_datetime("2023-06-15T14:30")
print(it)  
# "2023-06-15T14:30:00+00:00"

# Masked format - outputs datetime with mask information
ft = mask_datetime("2023-06")
print(ft)  
# {"dt": "2023-06-01T00:00:00+00:00", "mask": "0011111"}

Each class inherits all functionality from flex_datetime but provides a consistent output format:

  • dict_datetime: Best for when you need to access individual components programmatically
  • short_datetime: Best for human-readable output showing only specified components
  • iso_datetime: Best for standardized datetime strings and interoperability
  • mask_datetime: Best for scenarios where mask information needs to be preserved

All methods and features (masking, comparison, component access) work the same way:

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flexible_datetime-1.1.1.tar.gz (52.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flexible_datetime-1.1.1-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

File details

Details for the file flexible_datetime-1.1.1.tar.gz.

File metadata

  • Download URL: flexible_datetime-1.1.1.tar.gz
  • Upload date:
  • Size: 52.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for flexible_datetime-1.1.1.tar.gz
Algorithm Hash digest
SHA256 0be1be40c93e6fb1998fe77c85b23e2f4f0d46e65fbebc463b89b8ae2b465ad6
MD5 2cb4a5631cea6f82d8f3d6ba36564286
BLAKE2b-256 b57c360dde97aba952315d5a3312ad3017dd6d8daec224c351fb0561fe04369e

See more details on using hashes here.

File details

Details for the file flexible_datetime-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: flexible_datetime-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 19.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for flexible_datetime-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 25244916ab8eadc503f9279e23343af6af8630fcc270bec1fb547453afee510b
MD5 b1ff72fb4e208bfa4fa15566c24a2400
BLAKE2b-256 42b196499afa2cd55e1e713ddf06cee0dd8dffd47f829ab1007be632560b034c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page