"""Somewhat Looser ISO date format YYYY-MM-DD HH:mm:SS +HH:mm
ISO_date_loose -- YYYY-MM-DD format, with a month and day optional,
month or day may be specified without leading 0
ISO_time_loose -- HH:mm:SS format, with minutes and seconds optional
all numbers may be specified without leading 0
ISO_date_time_loose -- YYYY-MM-DD HH:mm:SS +HH:mm format,
with time optional and TimeZone offset optional,
same format for date and time as above
Interpreter:
MxInterpreter
Interprets the parse tree as mx.DateTime values
Date and DateTime -> DateTime objects
Time only -> RelativeDateTime
"""
try:
from mx import DateTime
haveMX = 1
except ImportError:
haveMX = 0
from simpleparse.parser import Parser
from simpleparse import common, objectgenerator
from simpleparse.common import chartypes, numbers
from simpleparse.dispatchprocessor import *
c = {}
declaration = """
<date_separator> := [-]
<time_separator> := ':'
offset_sign := [-+]
year := int
month := int
day := int
hour := int
minute := int
second := float/int
ISO_date_loose := year, (date_separator, month, (date_separator, day)?)?
ISO_time_loose := hour, (time_separator, minute, (time_separator, second)?)?
offset := offset_sign, offset_hour, time_separator?, offset_minute?
offset_hour := digit, digit
offset_minute := digit, digit
ISO_date_time_loose := ISO_date_loose, ([T ], ISO_time_loose)?, [ ]?, offset?
"""
_p = Parser( declaration )
for name in ["ISO_time_loose","ISO_date_time_loose", "ISO_date_loose"]:
c[ name ] = objectgenerator.LibraryElement(
generator = _p._generator,
production = name,
)
common.share( c )
if haveMX:
class MxInterpreter(DispatchProcessor):
"""Interpret a parsed ISO_date_time_loose in GMT/UTC time or localtime
"""
int = numbers.IntInterpreter()
offset_minute = offset_hour = year = month = day = hour = minute = int
float = numbers.FloatInterpreter()
second = float
def __init__(
self,
inputLocal = 1,
returnLocal = 1,
):
self.inputLocal = inputLocal
self.returnLocal = returnLocal
dateName = 'ISO_date_loose'
timeName = 'ISO_time_loose'
def ISO_date_time_loose( self, (tag, left, right, sublist), buffer):
"""Interpret the loose ISO date + time format"""
set = singleMap( sublist, self, buffer )
base, time, offset = (
set.get(self.dateName),
set.get(self.timeName) or DateTime.RelativeDateTime(hour=0,minute=0,second=0),
set.get( "offset" ),
)
base = base + time
offset = set.get( "offset" )
if offset is not None:
# an explicit timezone was entered, convert to gmt and return as appropriate...
gmt = base - offset
if self.returnLocal:
return gmt.localtime()
else:
return gmt
# was in the default input locale (either gmt or local)
if self.inputLocal and self.returnLocal:
return base
elif not self.inputLocal and not self.returnLocal:
return base
elif self.inputLocal and not self.returnLocal:
# return gmt from local...
return base.gmtime()
else:
return base.localtime()
def ISO_date_loose( self, (tag, left, right, sublist), buffer):
"""Interpret the loose ISO date format"""
set = singleMap( sublist, self, buffer )
return DateTime.DateTime(
set.get("year") or now().year,
set.get("month") or 1,
set.get("day") or 1,
)
def ISO_time_loose( self, (tag, left, right, sublist), buffer):
"""Interpret the loose ISO time format"""
set = singleMap( sublist, self, buffer )
return DateTime.RelativeDateTime(
hour = set.get("hour") or 0,
minute = set.get("minute") or 0,
second = set.get("second") or 0,
)
def offset( self, (tag, left, right, sublist), buffer):
"""Calculate the time zone offset as a date-time delta"""
set = singleMap( sublist, self, buffer )
direction = set.get('offset_sign',1)
hour = set.get( "offset_hour", 0)
minute = set.get( "offset_minute", 0)
delta = DateTime.DateTimeDelta( 0, hour*direction, minute*direction)
return delta
def offset_sign( self , (tag, left, right, sublist), buffer):
"""Interpret the offset sign as a multiplier"""
v = buffer [left: right]
if v in ' +':
return 1
else:
return -1
syntax highlighted by Code2HTML, v. 0.9.1