Module control.typ.datetime
The datetime type.
Expand source code
"""The datetime type."""
import re
from datetime import datetime as dt
from config import Config as C, Names as N
from control.utils import now, E
from control.html import HtmlElements as H
from control.typ.base import TypeBase
CW = C.web
QQ = H.icon(CW.unknown[N.generic])
Qq = H.icon(CW.unknown[N.generic], asChar=True)
dtTrim = re.compile(r"""[^0-9 T/:.-]+""")
dtSep = re.compile(r"""[ T/:.-]+""")
def getDefaultDate():
today = now()
return (
today.year,
today.month,
today.day,
today.hour,
today.minute,
today.second,
)
DATETIME_FORMAT = """{:>04}-{:>02}-{:>02} {:>02}:{:>02}:{:>02}"""
def genDatetimePattern():
s = """[ /:.-]"""
t = """[T /:.-]"""
yr = """([12][0-9][0-9][0-9])"""
mth = """((0[1-9])|(1[0-2])|[1-9])"""
d = """((0[1-9])|([12][0-9])|(3[01])|[1-9])"""
hr = """(([0-5][0-9])|[0-9])"""
m = hr
sec = hr
return (
"""^"""
f"""{yr}?({s}{mth})?({s}{d})?({t}{hr})?({s}{m})?({s}{sec})?"""
"""Z?"""
"""$"""
)
DATETIME_PATTERN = genDatetimePattern()
class Datetime(TypeBase):
"""Type class for date-time values"""
rawType = dt
widgetType = N.text
pattern = DATETIME_PATTERN
def partition(self, strVal):
"""Split a datetime string into 3 date components and 3 time components.
!!! note
The fraction part of seconds is ignored.
!!! warning
If there are missing components, they will be taken from the default date,
which is `now`.
Parameters
----------
strVal: string
"""
normalVal = dtTrim.sub(E, strVal)
if not normalVal:
return None
normalParts = [int(p) for p in dtSep.split(normalVal)]
if len(normalParts) == 0:
return None
if not 1900 <= normalParts[0] <= 2100:
return None
defaultDate = getDefaultDate()
if len(normalParts) > 6:
normalParts = normalParts[0:6]
if len(normalParts) < 6:
normalParts = [
normalParts[i] if i < len(normalParts) else defaultDate[i]
for i in range(6)
]
try:
dt(*normalParts) # only for checking
except Exception:
normalParts = defaultDate
return normalParts
def normalize(self, strVal):
normalParts = self.partition(strVal)
if normalParts is None:
return E
return DATETIME_FORMAT.format(*normalParts)
def fromStr(self, editVal):
if not editVal:
return None
if editVal == N.now:
return now()
normalParts = self.partition(editVal)
if normalParts is None:
return None
cast = self.rawType
return cast(*normalParts)
def toDisplay(self, val, markup=True):
if val is None:
return None if markup is None else QQ if markup else Qq
valBare = self.normalize(val.isoformat())
return H.span(valBare) if markup else valBare
def toEdit(self, val):
return E if val is None else self.normalize(val.isoformat())
def toOrig(self, val):
if val is None:
return None
return self.normalize(val.isoformat())
Functions
def genDatetimePattern()
-
Expand source code
def genDatetimePattern(): s = """[ /:.-]""" t = """[T /:.-]""" yr = """([12][0-9][0-9][0-9])""" mth = """((0[1-9])|(1[0-2])|[1-9])""" d = """((0[1-9])|([12][0-9])|(3[01])|[1-9])""" hr = """(([0-5][0-9])|[0-9])""" m = hr sec = hr return ( """^""" f"""{yr}?({s}{mth})?({s}{d})?({t}{hr})?({s}{m})?({s}{sec})?""" """Z?""" """$""" )
def getDefaultDate()
-
Expand source code
def getDefaultDate(): today = now() return ( today.year, today.month, today.day, today.hour, today.minute, today.second, )
Classes
class Datetime
-
Type class for date-time values
Expand source code
class Datetime(TypeBase): """Type class for date-time values""" rawType = dt widgetType = N.text pattern = DATETIME_PATTERN def partition(self, strVal): """Split a datetime string into 3 date components and 3 time components. !!! note The fraction part of seconds is ignored. !!! warning If there are missing components, they will be taken from the default date, which is `now`. Parameters ---------- strVal: string """ normalVal = dtTrim.sub(E, strVal) if not normalVal: return None normalParts = [int(p) for p in dtSep.split(normalVal)] if len(normalParts) == 0: return None if not 1900 <= normalParts[0] <= 2100: return None defaultDate = getDefaultDate() if len(normalParts) > 6: normalParts = normalParts[0:6] if len(normalParts) < 6: normalParts = [ normalParts[i] if i < len(normalParts) else defaultDate[i] for i in range(6) ] try: dt(*normalParts) # only for checking except Exception: normalParts = defaultDate return normalParts def normalize(self, strVal): normalParts = self.partition(strVal) if normalParts is None: return E return DATETIME_FORMAT.format(*normalParts) def fromStr(self, editVal): if not editVal: return None if editVal == N.now: return now() normalParts = self.partition(editVal) if normalParts is None: return None cast = self.rawType return cast(*normalParts) def toDisplay(self, val, markup=True): if val is None: return None if markup is None else QQ if markup else Qq valBare = self.normalize(val.isoformat()) return H.span(valBare) if markup else valBare def toEdit(self, val): return E if val is None else self.normalize(val.isoformat()) def toOrig(self, val): if val is None: return None return self.normalize(val.isoformat())
Ancestors
Class variables
var pattern
var rawType
-
datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints.
var widgetType
Methods
def partition(self, strVal)
-
Split a datetime string into 3 date components and 3 time components.
Note
The fraction part of seconds is ignored.
Warning
If there are missing components, they will be taken from the default date, which is
now
.Parameters
strVal
:string
Expand source code
def partition(self, strVal): """Split a datetime string into 3 date components and 3 time components. !!! note The fraction part of seconds is ignored. !!! warning If there are missing components, they will be taken from the default date, which is `now`. Parameters ---------- strVal: string """ normalVal = dtTrim.sub(E, strVal) if not normalVal: return None normalParts = [int(p) for p in dtSep.split(normalVal)] if len(normalParts) == 0: return None if not 1900 <= normalParts[0] <= 2100: return None defaultDate = getDefaultDate() if len(normalParts) > 6: normalParts = normalParts[0:6] if len(normalParts) < 6: normalParts = [ normalParts[i] if i < len(normalParts) else defaultDate[i] for i in range(6) ] try: dt(*normalParts) # only for checking except Exception: normalParts = defaultDate return normalParts
Inherited members