Source code for khayyam.formatting.formatters
# -*- coding: utf-8 -*-
import re
from khayyam.formatting import constants as consts
from .directives import DATE_FORMAT_DIRECTIVES
__author__ = 'vahid'
[docs]class JalaliDateFormatter(BaseFormatter):
"""
Responsible to parse and formatting of a :py:class:`khayyam.JalaliDate` instance.
"""
_post_parsers = [
'persianday',
'persiandayzeropadded',
'persiandayofyear',
'persiandayofyearzeropadded',
'persianmonth',
'persianmonthzeropadded',
'persianyear',
'persianyearzeropadded',
'persianshortyear',
'persianshortyearzeropadded',
'localdateformat',
'monthabbr',
'monthabbr_ascii',
'monthname',
'monthnameascii',
'shortyear',
'dayofyear',
]
def __init__(self, format_string, directive_db=None):
if not directive_db:
directive_db = DATE_FORMAT_DIRECTIVES
self.format_string = format_string
self.directives = directive_db
self.directives_by_key = {d.key: d for d in self.directives}
self.directives_by_name = {d.name: d for d in self.directives}
self._parser_regex = self._create_parser_regex()
def _create_parser_regex(self):
regex = u'^'
index = 0
for m in re.finditer(consts.FORMAT_DIRECTIVE_REGEX, self.format_string):
directive_key = m.group()[1:]
if directive_key not in self.directives_by_key:
continue
directive = self.directives_by_key[directive_key]
if index < m.start():
regex += self.format_string[index:m.start()]
index = m.end()
if directive.key == u'%':
regex += u'%'
continue
regex += u'(?P<%(group_name)s>%(regexp)s)' % dict(
group_name=directive.key,
regexp=directive.regex
)
regex += self.format_string[index:]
regex += u'$'
return regex
@property
def parser_regex(self):
return self._parser_regex
def iter_format_directives(self):
for m in re.finditer(consts.FORMAT_DIRECTIVE_REGEX, self.format_string):
key = m.group()[1:]
if key in self.directives_by_key:
yield m, self.directives_by_key[key]
def format(self, jalali_date):
result = ''
index = 0
for match, directive in self.iter_format_directives():
if index < match.start():
result += self.format_string[index:match.start()]
result += directive.format(jalali_date)
index = match.end()
result += self.format_string[index:]
return result
@staticmethod
def filter_persian_digit(s):
for p, e in consts.PERSIAN_DIGIT_MAPPING:
s = s.replace(p[1], p[0])
return s
def _parse(self, date_string):
m = re.match(self.parser_regex, self.filter_persian_digit(date_string))
if not m:
raise ValueError(u"time data '%s' does not match format '%s' with generated regex: '%s'" % (
date_string, self.format_string, self.parser_regex))
result = {}
for directive_key, v in m.groupdict().items():
directive = self.directives_by_key[directive_key]
result[directive.name] = directive.type_(v)
return result
@property
def post_parsers(self):
return self._post_parsers
def _parse_post_processor(self, parse_result):
for directive_name in self.post_parsers:
if directive_name in parse_result:
self.directives_by_name[directive_name].post_parser(parse_result, self)
def parse(self, date_string):
result = self._parse(date_string)
self._parse_post_processor(result)
return result
[docs]class JalaliDatetimeFormatter(JalaliDateFormatter):
"""
Responsible to parse and formatting of a :py:class:`khayyam.JalaliDatetime` instance.
"""
_post_parsers = [
'persianday',
'persiandayzeropadded',
'persiandayofyear',
'persiandayofyearzeropadded',
'persianmonth',
'persianmonthzeropadded',
'persianyear',
'persianyearzeropadded',
'persianshortyear',
'persianshortyearzeropadded',
'persianmicrosecond',
'persianhour12',
'persianhour12zeropadded',
'persianhour24',
'persianhour24zeropadded',
'persianminute',
'persianminutezeropadded',
'persiansecond',
'persiansecondzeropadded',
'persianutcoffset',
'localdateformat',
'localshortdatetimeformat',
'localshortdatetimeformatascii',
'localdatetimeformat',
'localdatetimeformatascii',
'localtimeformat',
'monthabbr',
'monthabbr_ascii',
'monthname',
'monthnameascii',
'ampm',
'ampmascii',
'shortyear',
'dayofyear',
'utcoffset'
]
def __init__(self, format_string, directive_db=None):
if not directive_db:
from .directives import DATETIME_FORMAT_DIRECTIVES
directive_db = DATETIME_FORMAT_DIRECTIVES
super(JalaliDatetimeFormatter, self).__init__(format_string, directive_db=directive_db)