dklrt/Time.py
2013-10-28 11:33:09 +00:00

85 lines
2.5 KiB
Python
Executable file

#!/usr/bin/python
# Time and Date Utilities (dklrt).
# (c) David Keegan 2011-08-06.
import sys, re
from time import *
import datetime
import Misc
ModuleName = __name__
ReDateSep = '[-/]'
ReDate = '\d{4}%s\d{1,2}%s\d{1,2}' % (ReDateSep, ReDateSep)
RePeriod = '(\d+)([ymwd])'
DateFormat = '%Y-%m-%d'
DateFormatH = DateFormat + ' %H';
DateFormatHm = DateFormatH + ':%M';
DateFormatHms = DateFormatHm + ':%S';
SecPerDay = 24 * 60 * 60
def _Throw(Msg): Misc.Throw(Msg, ModuleName)
def DateParse(Datestr):
"""Converts a date string to seconds since the epoch."""
Fs = DateFormat;
if len(Datestr) > 16 : Fs = DateFormatHms;
elif len(Datestr) > 13 : Fs = DateFormatHm;
elif len(Datestr) > 10 : Fs = DateFormatH;
return mktime(strptime(Datestr, Fs))
def DateToText(Seconds):
# Round seconds to integer first as we're truncating the time
# component.
return strftime(DateFormat, localtime(round(Seconds)))
def DateToday():
return DateParse(DateToText(time()))
def DateAddPeriod(Seconds, Periodstr):
"""Adds the period to the Seconds (a date)."""
Match = re.match(RePeriod, Periodstr)
if not Match: _Throw("Bad Period String: %s!", Periodstr)
Count = int(Match.group(1))
Unit = Match.group(2)
Rv = Seconds
if Unit == 'y': Rv = DateAddYears(Rv, Count)
elif Unit== 'm': Rv = DateAddMonths(Rv, Count)
elif Unit == 'w': Rv = Rv + (Count * SecPerDay * 7)
elif Unit == 'd': Rv = Rv + (Count * SecPerDay)
else: _Throw('Bad Period Unit: "%s"!' % Unit)
return Rv
def DateAddYears(Seconds, Count):
"""Shifts Seconds (a date) forward by Count years.
If Seconds is Feb 29, shifts to Feb 28, even if shifing to a
leap year.
"""
if not isinstance(Count, (int, long)):
_Throw("Count argument not an int!")
dtd = datetime.date.fromtimestamp(Seconds)
if not Count == 0:
if (dtd.month == 2) and (dtd.day == 29):
dtd = dtd.replace(day=28)
dtd = dtd.replace(year=(dtd.year + Count))
return mktime(dtd.timetuple())
def DateAddMonths(Seconds, Count):
"""Shifts Seconds (a date) forward by Count months.
If the day is >= 29, shifts to 28.
"""
if not isinstance(Count, (int, long)):
_Throw("Count argument not an int!")
dtd = datetime.date.fromtimestamp(Seconds)
if not Count == 0:
if dtd.day >= 29: dtd = dtd.replace(day=28)
Month = (dtd.month + Count) - 1
Years = Month / 12
dtd = dtd.replace(year=(dtd.year + Years))
Month = (Month % 12) + 1
dtd = dtd.replace(month=Month)
return mktime(dtd.timetuple())