"""
SmartDateCalculator
Generated by Eden via recursive self-improvement
2025-10-27 23:19:13.602842
"""

from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta

class DateIntelligence:
    """
    A class to handle smart date calculations and manipulations.
    
    This capability provides methods to add or subtract durations (days, hours, months, years)
    to a given date, calculate the difference between two dates, and format dates in various ways.
    """

    def __init__(self, date=None):
        """
        Initializes DateIntelligence with a given date or defaults to today's date if none is provided.
        
        Args:
            date (datetime.date): The date to work with. Defaults to None.
        """
        if date is None:
            self.date = datetime.today().date()
        else:
            self.date = date

    def add_days(self, days: int) -> 'DateIntelligence':
        """
        Adds a specified number of days to the current date.
        
        Args:
            days (int): The number of days to add. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        new_date = self.date + timedelta(days=days)
        return DateIntelligence(new_date)

    def subtract_days(self, days: int) -> 'DateIntelligence':
        """
        Subtracts a specified number of days from the current date.
        
        Args:
            days (int): The number of days to subtract. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        return self.add_days(-days)

    def add_months(self, months: int) -> 'DateIntelligence':
        """
        Adds a specified number of months to the current date.
        
        Args:
            months (int): The number of months to add. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        new_date = self.date + relativedelta(months=months)
        return DateIntelligence(new_date)

    def subtract_months(self, months: int) -> 'DateIntelligence':
        """
        Subtracts a specified number of months from the current date.
        
        Args:
            months (int): The number of months to subtract. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        return self.add_months(-months)

    def add_years(self, years: int) -> 'DateIntelligence':
        """
        Adds a specified number of years to the current date.
        
        Args:
            years (int): The number of years to add. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        new_date = self.date + relativedelta(years=years)
        return DateIntelligence(new_date)

    def subtract_years(self, years: int) -> 'DateIntelligence':
        """
        Subtracts a specified number of years from the current date.
        
        Args:
            years (int): The number of years to subtract. Can be positive or negative.
            
        Returns:
            DateIntelligence: A new instance with the updated date.
        """
        return self.add_years(-years)

    def difference_in_days(self, other_date) -> int:
        """
        Calculates the difference in days between this date and another date.
        
        Args:
            other_date (datetime.date): The date to compare with.
            
        Returns:
            int: The number of days between the two dates. Positive if self is later than other_date,
                negative otherwise.
        """
        return (self.date - other_date).days

    def format_date(self, fmt: str) -> str:
        """
        Formats the date according to the specified format string.
        
        Args:
            fmt (str): The format string to use for formatting. See Python's strftime documentation
                       for valid format codes.
                       
        Returns:
            str: The formatted date string.
        """
        return self.date.strftime(fmt)

# Example usage:
if __name__ == "__main__":
    # Add 7 days to today
    today = DateIntelligence()
    tomorrow = today.add_days(7)
    print("Today:", today.date)
    print("Tomorrow:", tomorrow.date)
    
    # Subtract 2 months from a specific date
    specific_date = DateIntelligence(datetime(2023, 10, 31))
    subtracted_date = specific_date.subtract_months(2)
    print("\nSpecific date:", specific_date.date)
    print("Subtracted 2 months:", subtracted_date.date)
    
    # Calculate difference in days between two dates
    date1 = DateIntelligence(datetime(2023, 9, 15))
    date2 = DateIntelligence(datetime(2024, 1, 1))
    print("\nDifference in days:", date1.difference_in_days(date2.date))
    
    # Format a date into ISO format
    formatted_date = date1.format_date("%Y-%m-%dT%H:%M:%S")
    print("Formatted date:", formatted_date)