-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from kraken-tech/implementation
Implementation
- Loading branch information
Showing
10 changed files
with
1,809 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,25 @@ | ||
""" | ||
TODO Add a description of the package here. | ||
Tools for working with timezone-aware datetimes. | ||
""" | ||
|
||
from ._clock import Clock | ||
from ._converter import TimezoneConverter | ||
from ._dates import ( | ||
DateNotFound, | ||
closest_upcoming_match, | ||
get_contiguous_periods, | ||
is_last_day_of_month, | ||
iter_dates, | ||
latest_date_for_day, | ||
) | ||
|
||
__all__ = ( | ||
"Clock", | ||
"DateNotFound", | ||
"TimezoneConverter", | ||
"closest_upcoming_match", | ||
"get_contiguous_periods", | ||
"is_last_day_of_month", | ||
"iter_dates", | ||
"latest_date_for_day", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import datetime | ||
import zoneinfo | ||
|
||
from dateutil import relativedelta | ||
|
||
|
||
class Clock: | ||
"""Get the current date/time in a specific timezone.""" | ||
|
||
def __init__(self, timezone: str) -> None: | ||
self.tzinfo = zoneinfo.ZoneInfo(timezone) | ||
|
||
# Current time/date | ||
|
||
def now(self) -> datetime.datetime: | ||
return datetime.datetime.now(tz=self.tzinfo) | ||
|
||
def today(self) -> datetime.date: | ||
return self.now().date() | ||
|
||
# Relative times/dates | ||
|
||
def yesterday(self) -> datetime.date: | ||
return self.days_in_the_past(1) | ||
|
||
def tomorrow(self) -> datetime.date: | ||
return self.days_in_the_future(1) | ||
|
||
def days_in_the_past(self, days: int) -> datetime.date: | ||
return self.today() - datetime.timedelta(days=days) | ||
|
||
def days_in_the_future(self, days: int) -> datetime.date: | ||
return self.today() + datetime.timedelta(days=days) | ||
|
||
def months_in_the_past(self, months: int) -> datetime.date: | ||
"""Get the date some number of months ago. | ||
If the target month does not have enough days, the closest day will be | ||
returned (e.g. 3 months before July 31st is April 30th, not April | ||
31st). | ||
""" | ||
return self.today() - relativedelta.relativedelta(months=months) | ||
|
||
def months_in_the_future(self, months: int) -> datetime.date: | ||
"""Get the date some number of months in the future. | ||
If the target month does not have enough days, the closest day will be | ||
returned (e.g. 4 months after July 31st is November 30th, not November | ||
31st). | ||
""" | ||
return self.today() + relativedelta.relativedelta(months=months) | ||
|
||
def is_in_the_past( | ||
self, candidate: datetime.datetime | datetime.date | ||
) -> bool: | ||
"""Check whether a date/time is before the current date/time.""" | ||
if isinstance(candidate, datetime.datetime): | ||
return candidate < self.now() | ||
else: | ||
return candidate < self.today() | ||
|
||
def is_in_the_future( | ||
self, candidate: datetime.datetime | datetime.date | ||
) -> bool: | ||
"""Check whether a date/time is after the current date/time.""" | ||
if isinstance(candidate, datetime.datetime): | ||
return self.now() < candidate | ||
else: | ||
return self.today() < candidate |
Oops, something went wrong.