2013-10-20 12:09:44 +02:00
|
|
|
#!/usr/bin/python
|
2013-10-20 12:13:59 +02:00
|
|
|
# Time and Date Utilities (dklrt).
|
2013-10-20 12:09:44 +02:00
|
|
|
# (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)
|
2013-10-28 17:42:32 +01:00
|
|
|
RePeriod = '(\d+)([ymwdh])'
|
2013-10-20 12:09:44 +02:00
|
|
|
|
|
|
|
DateFormat = '%Y-%m-%d'
|
|
|
|
|
2013-10-28 17:42:32 +01:00
|
|
|
ReDateTimeSep = "[-/: ]";
|
|
|
|
DateTimeFormat = '%Y%m%d%H%M%S'
|
|
|
|
|
|
|
|
SecPerHour = 60
|
|
|
|
SecPerDay = 24 * SecPerHour * SecPerHour
|
2013-10-20 12:09:44 +02:00
|
|
|
|
|
|
|
def _Throw(Msg): Misc.Throw(Msg, ModuleName)
|
|
|
|
|
2013-10-28 17:42:32 +01:00
|
|
|
def DateTimeParse(DateTimeStr):
|
|
|
|
"""Converts a date(/time) string to seconds since the epoch.
|
|
|
|
Assumes zeroes for missing time components.
|
|
|
|
"""
|
|
|
|
Dts = re.sub(ReDateTimeSep, '', DateTimeStr);
|
|
|
|
if len(Dts) < 8:
|
2013-10-28 20:42:33 +01:00
|
|
|
_Throw('Bad Date/Time string: "%s"!' % DateTimeStr)
|
2013-10-28 17:42:32 +01:00
|
|
|
while len(Dts) < 14: Dts = Dts + "0";
|
|
|
|
return mktime(strptime(Dts, DateTimeFormat))
|
2013-10-20 12:09:44 +02:00
|
|
|
|
|
|
|
def DateToText(Seconds):
|
|
|
|
# Round seconds to integer first as we're truncating the time
|
|
|
|
# component.
|
|
|
|
return strftime(DateFormat, localtime(round(Seconds)))
|
|
|
|
|
|
|
|
def DateToday():
|
2013-10-28 17:42:32 +01:00
|
|
|
return DateTimeParse(DateToText(time()))
|
2013-10-20 12:09:44 +02:00
|
|
|
|
|
|
|
def DateAddPeriod(Seconds, Periodstr):
|
|
|
|
"""Adds the period to the Seconds (a date)."""
|
|
|
|
Match = re.match(RePeriod, Periodstr)
|
2013-10-28 20:42:33 +01:00
|
|
|
if not Match: _Throw("Bad Period String: %s!" % Periodstr)
|
2013-10-20 12:09:44 +02:00
|
|
|
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)
|
2013-10-28 17:42:32 +01:00
|
|
|
elif Unit == 'h': Rv = Rv + (Count * SecPerHour)
|
2013-10-20 12:09:44 +02:00
|
|
|
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())
|