Created
August 7, 2016 20:10
-
-
Save lukassup/20b7e2afe7461ab0eb80d135eeaf3716 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
"""various date/time utilities | |
<datetime.datetime> parsing behavior | |
[year(-|/|.)month(-|/|.)day(_whitespace_)][[[hour]:minute]:second] | |
<datetime.timedelta> parsing behavior | |
[days(_whitespace_)][[[hours]:minutes]:seconds] | |
""" | |
import re | |
from collections import defaultdict | |
from datetime import datetime, timedelta | |
DATETIME_FMT = re.compile( | |
r"^((?P<year>\d+)[\-\./]" | |
"(?P<month>\d+)[\-./]" | |
"(?P<day>\d+)\s+)?" | |
"(((?P<hour>\d+)" | |
"(:(?P<minute>\d+))?)?" | |
"(:(?P<second>\d+))?)?$" | |
) | |
TIMEDELTA_FMT = re.compile( | |
r"^((?P<days>\d+)\s+)?" | |
"(((?P<hours>\d+)" | |
"(:(?P<minutes>\d+))?)?" | |
"(:(?P<seconds>\d+))?)?$" | |
) | |
REPLACE_FMT = DATETIME_FMT | |
def _time_parser(timestamp, pattern): | |
"""Parses a string to date/time components with a regular expression""" | |
parts = pattern.match(timestamp) | |
if parts: | |
time_components = defaultdict(int) | |
for (name, value) in parts.groupdict().items(): | |
if value: | |
time_components[name] = int(value) | |
return time_components | |
else: | |
raise NotImplementedError("A date of unknown format provided: " | |
"'{0}'".format(timestamp)) | |
def strpdatetime(timestamp): | |
"""Parse datetime from string""" | |
return datetime(**_time_parser(timestamp, DATETIME_FMT)) | |
def strptimedelta(timestamp): | |
"""Parse timedelta from string""" | |
return timedelta(**_time_parser(timestamp, TIMEDELTA_FMT)) | |
def at(time, timestamp): | |
"""Set time and/or date from a parsed timestamp""" | |
time_components = _time_parser(timestamp, REPLACE_FMT) | |
return time.replace(**time_components, microsecond=0) | |
def days_from_now(days): | |
"""Set time and/or date from a parsed timestamp""" | |
return datetime.now() + timedelta(days=days) | |
def months_from_now(months): | |
"""Gets a date N months from now""" | |
now = datetime.now() | |
y, m = divmod(now.month + months, 12) | |
y += now.year | |
if m == 0: | |
m = 12 | |
y -= 1 | |
return now.replace(year=y, month=m) | |
def years_from_now(years): | |
"""Gets a date N years from now""" | |
now = datetime.now() | |
return now.replace(year=now.year+years) | |
def today_at(timestamp): | |
"""Sets the time from a string for today's date""" | |
return at(datetime.now(), timestamp) | |
def tomorrow_at(timestamp): | |
"""Sets the time from a string for a date that's a day from now""" | |
return at(days_from_now(1), timestamp) | |
def yesterday_at(timestamp): | |
"""Sets the time from a string for a date that's a day before now""" | |
return at(days_from_now(-1), timestamp) | |
def next_week_at(timestamp): | |
"""Sets the time from a string for a date that's a week from now""" | |
return at(days_from_now(7), timestamp) | |
def previous_week_at(timestamp): | |
"""Sets the time from a string for a date that's a week before now""" | |
return at(days_from_now(-7), timestamp) | |
def next_month_at(timestamp): | |
"""Sets the time from a string for a date that's a month from now""" | |
return at(months_from_now(1), timestamp) | |
def previous_month_at(timestamp): | |
"""Sets the time from a string for a date that's a month before now""" | |
return at(months_from_now(-1), timestamp) | |
def next_year_at(timestamp): | |
"""Sets the time from a string for a date that's a year from now | |
Leap years work too | |
""" | |
return at(years_from_now(1), timestamp) | |
def previous_year_at(timestamp): | |
"""Sets the time from a string for a date that's a year before now | |
Leap years work too | |
""" | |
return at(years_from_now(-1), timestamp) | |
if __name__ == "__main__": | |
from sys import argv, exit | |
try: | |
print("Previous year at:", previous_year_at(argv[1])) | |
print("Previous month at:", previous_month_at(argv[1])) | |
print("Previous week at:", previous_week_at(argv[1])) | |
print("Yesterday at:", yesterday_at(argv[1])) | |
print("Today at:", today_at(argv[1])) | |
print("Tomorrow at:", tomorrow_at(argv[1])) | |
print("Next week at:", next_week_at(argv[1])) | |
print("Next month at:", next_month_at(argv[1])) | |
print("Next year at:", next_year_at(argv[1])) | |
except Exception as e: | |
raise e | |
exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment