from datetime import datetime, timedelta, timezone import pytz def _suffix(d): return 'th' if 11 <= d <= 13 else {1: 'st', 2: 'nd', 3: 'rd'}.get(d % 10, 'th') class Day: def __init__(self, year, month, day, user): self.user = user self._timestamp = datetime(year, month, day, tzinfo=timezone.utc) @staticmethod def from_str(string, user): return Day._from_timestamp(datetime.strptime(string, "%Y-%m-%d"), user) @staticmethod def _from_timestamp(timestamp, user): # not exposed because it is only an utilty function, not aware of the # user's time zone and start-of-day hour return Day(timestamp.year, timestamp.month, timestamp.day, user) def __eq__(self, other): if not isinstance(other, self.__class__): return False return self.year == other.year \ and self.month == other.month \ and self.day == other.day def __add__(self, other, oper="+"): if not isinstance(other, int): raise TypeError( 'Unsupported operands for "+". The right hand side needs to be a number.') else: return Day._from_timestamp(self.timestamp + timedelta(days=other), self.user) def __sub__(self, other): if not isinstance(other, int): raise TypeError( 'Unsupported operands for "-". The right hand side needs to be a number.') else: return Day._from_timestamp(self.timestamp + timedelta(days=-other), self.user) def __lt__(self, other): return self.timestamp < other.timestamp def __gt__(self, other): return self.timestamp > other.timestamp def __le__(self, other): return self < other or self == other def __ge__(self, other): return self > other or self == other def __repr__(self): return "" % (self.url, self.user) @property def year(self): return self._timestamp.year @property def month(self): return self._timestamp.month @property def day(self): return self._timestamp.day @property def timestamp(self): return self._timestamp @property def is_today(self): return self == Day.today(self.user) @property def is_future(self): return self > Day.today(self.user) @property def pretty(self): if self.is_today: return "Today" return self._timestamp.strftime("%B {S}, %Y").replace('{S}', str(self.day) + _suffix(self.day)) @property def url(self): return self._timestamp.strftime("%Y-%m-%d") @staticmethod def today(user): tz = pytz.timezone(user.timezone) now = datetime.now(tz) day = Day(now.year, now.month, now.day, user) if now.hour < user.start_of_day: day -= 1 return day