CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pendulum

Python datetimes made easy with timezone-aware datetime manipulation and human-readable formatting

Pending
Overview
Eval results
Files

duration-intervals.mddocs/

Duration and Intervals

Time span calculations with support for years and months. The Duration class extends Python's timedelta with year and month support, while Interval represents the time span between two specific DateTime objects.

Capabilities

Duration Creation

Functions for creating Duration instances with comprehensive time unit support.

def duration(
    days: float = 0,
    seconds: float = 0,
    microseconds: float = 0,
    milliseconds: float = 0,
    minutes: float = 0,
    hours: float = 0,
    weeks: float = 0,
    years: float = 0,
    months: float = 0
) -> Duration:
    """
    Create Duration instance.
    
    Parameters:
    - days: Number of days
    - seconds: Number of seconds
    - microseconds: Number of microseconds
    - milliseconds: Number of milliseconds
    - minutes: Number of minutes
    - hours: Number of hours
    - weeks: Number of weeks
    - years: Number of years (unique to Pendulum)
    - months: Number of months (unique to Pendulum)
    
    Returns:
    Duration: New Duration instance
    """

Duration Class

The Duration class with its constructor and methods.

class Duration:
    def __init__(
        self,
        days: float = 0,
        seconds: float = 0,
        microseconds: float = 0,
        milliseconds: float = 0,
        minutes: float = 0,
        hours: float = 0,
        weeks: float = 0,
        years: float = 0,
        months: float = 0
    ):
        """Create Duration with specified time components"""
    
    def total_seconds(self) -> float:
        """
        Total duration in seconds.
        
        Returns:
        float: Total seconds (excluding years/months)
        """
    
    def total_minutes(self) -> float:
        """
        Total duration in minutes.
        
        Returns:
        float: Total minutes
        """
    
    def total_hours(self) -> float:
        """
        Total duration in hours.
        
        Returns:
        float: Total hours
        """
    
    def total_days(self) -> float:
        """
        Total duration in days.
        
        Returns:
        float: Total days
        """
    
    def total_weeks(self) -> float:
        """
        Total duration in weeks.
        
        Returns:
        float: Total weeks
        """
    
    def in_weeks(self) -> int:
        """
        Duration as integer weeks.
        
        Returns:
        int: Number of complete weeks
        """
    
    def in_days(self) -> int:
        """
        Duration as integer days.
        
        Returns:
        int: Number of complete days
        """
    
    def in_hours(self) -> int:
        """
        Duration as integer hours.
        
        Returns:
        int: Number of complete hours
        """
    
    def in_minutes(self) -> int:
        """
        Duration as integer minutes.
        
        Returns:
        int: Number of complete minutes
        """
    
    def in_seconds(self) -> int:
        """
        Duration as integer seconds.
        
        Returns:
        int: Number of complete seconds
        """
    
    def in_words(self, locale: str | None = None, separator: str = " ") -> str:
        """
        Human-readable duration description.
        
        Parameters:
        - locale: Locale for formatting
        - separator: Separator between components
        
        Returns:
        str: Human-readable duration (e.g., "1 year 2 months 3 days")
        """
    
    def as_timedelta(self):
        """
        Convert to standard timedelta.
        
        Note: Years and months are converted to approximate days.
        
        Returns:
        timedelta: Standard timedelta object
        """

Duration Properties

Properties available on Duration instances.

class Duration:
    @property
    def years(self) -> int:
        """Number of years in duration"""
    
    @property
    def months(self) -> int:
        """Number of months in duration"""
    
    @property
    def weeks(self) -> int:
        """Number of weeks in duration"""
    
    @property
    def days(self) -> int:
        """Total days (including converted years/months)"""
    
    @property
    def remaining_days(self) -> int:
        """Days not included in weeks calculation"""
    
    @property
    def hours(self) -> int:
        """Hours component (0-23)"""
    
    @property
    def minutes(self) -> int:
        """Minutes component (0-59)"""
    
    @property
    def seconds(self) -> int:
        """Total seconds in duration"""
    
    @property
    def remaining_seconds(self) -> int:
        """Seconds component not included in larger units (0-59)"""
    
    @property
    def microseconds(self) -> int:
        """Microseconds component"""
    
    @property
    def invert(self) -> bool:
        """Whether duration is negative"""

Interval Creation

Functions for creating Interval instances between DateTime objects.

def interval(start: DateTime, end: DateTime, absolute: bool = False) -> Interval:
    """
    Create Interval between two DateTime objects.
    
    Parameters:
    - start: Start DateTime
    - end: End DateTime
    - absolute: Whether to make interval absolute (always positive)
    
    Returns:
    Interval: Time interval between the DateTimes
    """

Interval Class

The Interval class representing time spans between specific points.

class Interval(Duration):
    """
    Interval inherits all Duration methods and properties.
    Represents the time span between two DateTime objects.
    """
    
    def __init__(self, start: DateTime, end: DateTime, absolute: bool = False):
        """Create Interval between DateTimes"""
    
    @property
    def start(self) -> DateTime:
        """Start DateTime of interval"""
    
    @property
    def end(self) -> DateTime:
        """End DateTime of interval"""
    
    @property
    def years(self) -> int:
        """Years in interval"""
    
    @property
    def months(self) -> int:
        """Months in interval"""
    
    @property
    def weeks(self) -> int:
        """Weeks in interval"""
    
    @property
    def days(self) -> int:
        """Days in interval"""

Usage Examples

Creating and Using Durations

import pendulum

# Create durations
dur1 = pendulum.duration(hours=2, minutes=30)
dur2 = pendulum.duration(years=1, months=6, days=15)
dur3 = pendulum.duration(weeks=2, days=3, hours=4)

# Access components
print(f"Years: {dur2.years}")        # 1
print(f"Months: {dur2.months}")      # 6  
print(f"Days: {dur2.days}")          # 15 + ~365 + ~182 = ~562
print(f"Hours: {dur1.hours}")        # 2
print(f"Minutes: {dur1.minutes}")    # 30

# Total calculations
print(f"Total hours: {dur1.total_hours()}")      # 2.5
print(f"Total seconds: {dur1.total_seconds()}")  # 9000.0

# Integer conversions
print(f"In hours: {dur1.in_hours()}")      # 2
print(f"In minutes: {dur1.in_minutes()}")  # 150

# Human-readable format
print(dur2.in_words())  # "1 year 6 months 15 days"
print(dur1.in_words())  # "2 hours 30 minutes"

# Convert to standard timedelta
td = dur1.as_timedelta()
print(type(td))  # <class 'datetime.timedelta'>

Using Durations with DateTimes

import pendulum

dt = pendulum.now()

# Add/subtract durations
future = dt + pendulum.duration(years=1, months=2)
past = dt - pendulum.duration(weeks=3, days=2)

# Duration arithmetic with DateTime methods
future2 = dt.add(years=1, months=2, days=5)
past2 = dt.subtract(hours=6, minutes=30)

# Complex duration
complex_dur = pendulum.duration(
    years=2,
    months=3, 
    weeks=1,
    days=4,
    hours=5,
    minutes=30,
    seconds=45
)

result = dt + complex_dur
print(f"Added duration: {result}")
print(f"Duration in words: {complex_dur.in_words()}")

Working with Intervals

import pendulum

# Create interval between two dates
start = pendulum.datetime(2024, 1, 1)
end = pendulum.datetime(2025, 6, 15)
interval = pendulum.interval(start, end)

# Access interval properties
print(f"Years: {interval.years}")
print(f"Months: {interval.months}")
print(f"Days: {interval.days}")

# Interval inherits Duration methods
print(f"Total days: {interval.total_days()}")
print(f"In words: {interval.in_words()}")

# Create interval from DateTime.diff()
dt1 = pendulum.now()
dt2 = dt1.add(months=3, days=10)
diff_interval = dt1.diff(dt2)  # Returns Interval

print(f"Difference: {diff_interval.in_words()}")

# Absolute intervals
past_dt = pendulum.now().subtract(days=30)
future_dt = pendulum.now().add(days=30)

# Normal interval (negative)
normal = pendulum.interval(future_dt, past_dt)
print(f"Normal: {normal.total_days()}")  # -60

# Absolute interval (positive)
absolute = pendulum.interval(future_dt, past_dt, absolute=True)
print(f"Absolute: {absolute.total_days()}")  # 60

Duration Comparisons and Operations

import pendulum

dur1 = pendulum.duration(hours=2)
dur2 = pendulum.duration(minutes=120)
dur3 = pendulum.duration(hours=3)

# Duration comparison
print(dur1 == dur2)  # True (both are 2 hours)
print(dur1 < dur3)   # True
print(dur1 > dur3)   # False

# Duration arithmetic
combined = dur1 + dur3  # 5 hours
difference = dur3 - dur1  # 1 hour

# Multiplication and division
doubled = dur1 * 2      # 4 hours
half = dur1 / 2         # 1 hour

print(f"Combined: {combined.in_words()}")
print(f"Difference: {difference.in_words()}")
print(f"Doubled: {doubled.in_words()}")
print(f"Half: {half.in_words()}")

Negative Durations

import pendulum

# Create negative duration
neg_dur = pendulum.duration(hours=-2, minutes=-30)
print(f"Negative duration: {neg_dur.invert}")  # True
print(f"In words: {neg_dur.in_words()}")

# Use with DateTime
dt = pendulum.now()
past_time = dt + neg_dur  # Same as dt.subtract(hours=2, minutes=30)

# Interval creating negative duration
start = pendulum.now()
end = start.subtract(hours=5)
negative_interval = pendulum.interval(start, end)
print(f"Negative interval: {negative_interval.invert}")

Converting Between Duration Types

import pendulum
import datetime

# Pendulum Duration to standard timedelta
pd_dur = pendulum.duration(days=5, hours=3, minutes=30)
std_td = pd_dur.as_timedelta()

# Use standard timedelta with Pendulum DateTimes
dt = pendulum.now()
future = dt + std_td

# Note: Years and months are converted to approximate days
complex_dur = pendulum.duration(years=1, months=2, days=5)
# This conversion is approximate since months/years vary in length
approx_td = complex_dur.as_timedelta()

print(f"Original: {complex_dur.in_words()}")
print(f"As timedelta days: {approx_td.days}")

Install with Tessl CLI

npx tessl i tessl/pypi-pendulum

docs

date-time-components.md

datetime-operations.md

duration-intervals.md

formatting-localization.md

index.md

testing-utilities.md

timezone-management.md

tile.json