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.2.tar.gz (55.8 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.2-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flexible_datetime-1.1.2.tar.gz
  • Upload date:
  • Size: 55.8 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.2.tar.gz
Algorithm Hash digest
SHA256 691d1e27788edb8b104c2a26b391aee1c6fea1c17d7326ad304caf242dd1e5b9
MD5 a63858a9e27b345506691878e23d754e
BLAKE2b-256 8abbd0c3a4f9ef28f5abc3105d56915cc0a6dc6742ead641eb6da5367379791a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: flexible_datetime-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 22.0 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 49669dee3500d906b6379ff8254aa284064f223c0578d8e4813224572323d21d
MD5 67c4e9ac656a59dfa9ca2231cc91ac1c
BLAKE2b-256 69fa803fa6ab580dd54a1fba068f9e56065167f8c028edc358db3e73ba8836dd

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