from datetime import datetime, timedelta def _time_of_day_label(hour: int, *, for_today: bool) -> str: if 5 <= hour < 12: return "morning" if 12 <= hour < 17: return "afternoon" return "tonight" if for_today else "night" def describe_relative_time( timestamp_str: str, reference_time: datetime, *, prefer_day_part_for_today: bool = False, ) -> str: try: timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M") except ValueError: return "a long time ago" delta = reference_time - timestamp seconds = delta.total_seconds() if seconds < 0: return "just now" if not prefer_day_part_for_today: if seconds < 120: return "just now" if seconds < 15 * 60: return "a few minutes ago" if seconds < 90 * 60: return "an hour ago" if seconds < 3 * 60 * 60: return "a couple hours ago" day_diff = (reference_time.date() - timestamp.date()).days if day_diff == 0: return f"today {_time_of_day_label(timestamp.hour, for_today=True)}" if day_diff == 1: return f"yesterday {_time_of_day_label(timestamp.hour, for_today=False)}" if day_diff == 2: return "2 days ago" if day_diff == 3: return "3 days ago" if day_diff <= 6: return "a couple days ago" if day_diff <= 10: return "a week ago" if day_diff <= 20: return "a couple weeks ago" if day_diff <= 45: return "a month ago" if day_diff <= 75: return "a couple months ago" if day_diff <= 420: return "a year ago" return "a long time ago" class WorldClock: def __init__(self, start_year=1999, month=5, day=14, hour=18, minute=0): # We use a standard datetime object for easy math self.current_time = datetime(start_year, month, day, hour, minute) def advance_time(self, minutes=0, hours=0, days=0): self.current_time += timedelta(minutes=minutes, hours=hours, days=days) def get_time_str(self): # 1999-05-14 18:00 return self.current_time.strftime("%Y-%m-%d %H:%M") def get_vibe(self): """Helper to tell the LLM the 'feel' of the time.""" hour = self.current_time.hour if 5 <= hour < 12: return "Morning" if 12 <= hour < 17: return "Afternoon" if 17 <= hour < 21: return "Evening" return "Night" @classmethod def from_time_str(cls, time_str: str | None): if not time_str: return cls() parsed = datetime.strptime(time_str, "%Y-%m-%d %H:%M") return cls( start_year=parsed.year, month=parsed.month, day=parsed.day, hour=parsed.hour, minute=parsed.minute, )