96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
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):
|
|
"""
|
|
This function is NOT meant to be aware of timezones etc, you should
|
|
only use it to handle data stored in the database, in the format of the
|
|
output of the ".timestamp" property.
|
|
"""
|
|
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 "<Day[%s,user=%s]>" % (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
|