Skip to content

Instantly share code, notes, and snippets.

@lukassup
Created August 7, 2016 20:10
Show Gist options
  • Save lukassup/20b7e2afe7461ab0eb80d135eeaf3716 to your computer and use it in GitHub Desktop.
Save lukassup/20b7e2afe7461ab0eb80d135eeaf3716 to your computer and use it in GitHub Desktop.
#!/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