dklrt/Time.py

89 lines
2.6 KiB
Python
Raw Normal View History

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())