from datetime import datetime, timedelta import re class OurTime: def __init__(self, dt: datetime = None): self._dt = dt if dt else datetime.min def __str__(self) -> str: return self.str() def str(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%Y-%m-%d %H:%M') def day(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%Y-%m-%d') def key(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%Y_%m_%d_%H_%M_%S') def md(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%Y-%m-%d %H:%M:%S') def unix(self) -> int: if self._dt == datetime.min: return 0 return int(self._dt.timestamp()) def empty(self) -> bool: return self._dt == datetime.min def dayhour(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%Y-%m-%d-%H') def time(self): # This is a simplified representation, as VLang's time() returns a time object. # Here, we return self to allow chaining format_ss(). return self def format_ss(self) -> str: if self._dt == datetime.min: return "" return self._dt.strftime('%H:%M:%S') def warp(self, expression: str): if self._dt == datetime.min: return parts = expression.split() for part in parts: match = re.match(r'([+-]?\d+)([smhdwMQY])', part) if not match: continue value = int(match.group(1)) unit = match.group(2) if unit == 's': self._dt += timedelta(seconds=value) elif unit == 'm': self._dt += timedelta(minutes=value) elif unit == 'h': self._dt += timedelta(hours=value) elif unit == 'd': self._dt += timedelta(days=value) elif unit == 'w': self._dt += timedelta(weeks=value) elif unit == 'M': # Approximate months, for more accuracy, a proper dateutil.relativedelta would be needed self._dt += timedelta(days=value * 30) elif unit == 'Q': self._dt += timedelta(days=value * 90) elif unit == 'Y': self._dt += timedelta(days=value * 365) def now() -> OurTime: return OurTime(datetime.now()) def new(time_str: str) -> OurTime: if not time_str: return OurTime() formats = [ '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d %H', '%Y-%m-%d', '%d-%m-%Y %H:%M:%S', '%d-%m-%Y %H:%M', '%d-%m-%Y %H', '%d-%m-%Y', '%H:%M:%S', # For time() and format_ss() usage ] for fmt in formats: try: dt = datetime.strptime(time_str, fmt) return OurTime(dt) except ValueError: pass # Handle relative time expressions try: # Create a dummy OurTime object to use its warp method temp_time = now() temp_time.warp(time_str) return temp_time except Exception: pass raise ValueError(f"Could not parse time string: {time_str}") def new_from_epoch(epoch: int) -> OurTime: return OurTime(datetime.fromtimestamp(epoch))