date.py :  » Network » Python-Wikipedia-Robot-Framework » pywikipedia » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » Python Wikipedia Robot Framework 
Python Wikipedia Robot Framework » pywikipedia » date.py
# -*- coding: utf-8  -*-
"""
This file is not runnable, but it only consists of various
lists which are required by some other programs.
"""
#
#  Rob W.W. Hooft, 2003
#  Daniel Herding, 2004
#  var Arnfjr Bjarmason, 2004
#  Andre Engels, 2005
#  Yuri Astrakhan, 2005-2006  FirstnameLastname@gmail.com (years/decades/centuries/millenniums  str <=> int  conversions)
#
# Distributed under the terms of the MIT license.
#
__version__='$Id: date.py 8215 2010-05-26 02:41:31Z amir $'

# used for date recognition
import types
import re
import wikipedia

#
# Different collections of well known formats
#
enMonthNames    = [ u'January', u'February', u'March', u'April', u'May', u'June', u'July', u'August', u'September', u'October', u'November', u'December' ]
dayMnthFmts     = [ 'Day_' + str(s) for s in enMonthNames ]     # e.g. 'Day_January'
yrMnthFmts      = [ 'Year_' + str(s) for s in enMonthNames ]    # e.g. 'Year_January'

adDateFormats   = [ 'YearAD', 'DecadeAD', 'CenturyAD', 'MillenniumAD' ]     # the order of this list is important
bcDateFormats   = [ 'YearBC', 'DecadeBC', 'CenturyBC', 'MillenniumBC' ]     # the order of this list is important
dateFormats     = bcDateFormats + adDateFormats

decadeFormats   = [ 'DecadeAD', 'DecadeBC' ]
centuryFormats  = [ 'CenturyAD', 'CenturyBC' ]
yearFormats     = [ 'YearAD', 'YearBC' ]
millFormats     = [ 'MillenniumAD', 'MillenniumBC' ]
snglValsFormats = [ 'CurrEvents' ]


# number of days in each month, required for interwiki.py with the -days argument
# @deprecated
# days_in_month = {
    # 1:  31,
    # 2:  29,
    # 3:  31,
    # 4:  30,
    # 5:  31,
    # 6:  30,
    # 7:  31,
    # 8:  31,
    # 9:  30,
    # 10: 31,
    # 11: 30,
    # 12: 31
# }

# For all languages the maximal value a year BC can have; before this date the
# language switches to decades or centuries
# @deprecated
# maxyearBC = {
        # 'ca':500,
        # 'de':400,
        # 'en':499,
        # 'nl':1000,
        # 'pl':776
        # }

# @deprecated
# maxyearAD = {
        # 'es':2005,
        # }

def multi( value, tuplst ):
    """This method is used when more than one pattern is used for the same entry.
       Example: 1st century, 2nd century, etc.
       The tuplst is a list of tupples. Each tupple must contain two functions:
       first to encode/decode a single value (e.g. simpleInt),
       second is a predicate function with an integer parameter that returns true or false.
       When the 2nd function evaluates to true, the 1st function is used.
    """
    if type(value) in _stringTypes:
        # Try all functions, and test result against predicates
        for func, pred in tuplst:
            try:
                res = func(value)
                if pred(res):
                    return res
            except:
                pass
    else:
        # Find a predicate that gives true for this int value, and run a function
        for func, pred in tuplst:
            if pred(value):
                return func(value)

    raise ValueError("could not find a matching function")


#
#
# Helper functions that aid with single value no corrections encoding/decoding.
# Various filters are item dependent.
#
#
def dh_noConv( value, pattern, limit ):
    """decoding helper for a single integer value, no conversion, no rounding"""
    return dh( value, pattern, encNoConv, decSinglVal, limit )

def dh_dayOfMnth( value, pattern ):
    """decoding helper for a single integer value <=31, no conversion, no rounding (used in days of month)"""
    return dh_noConv( value, pattern, formatLimits[dayMnthFmts[0]][0] ) # For now use January because it has all 31 days

def dh_mnthOfYear( value, pattern ):
    """decoding helper for a single integer value >=1000, no conversion, no rounding (used in month of the year)"""
    return dh_noConv( value, pattern, _formatLimit_MonthOfYear[0] )

def dh_decAD( value, pattern ):
    """decoding helper for a single integer value, no conversion, round to decimals (used in decades)"""
    return dh( value, pattern, encDec0, decSinglVal, formatLimits['DecadeAD'][0]  )

def dh_decBC( value, pattern ):
    """decoding helper for a single integer value, no conversion, round to decimals (used in decades)"""
    return dh( value, pattern, encDec0, decSinglVal, formatLimits['DecadeBC'][0]  )

def dh_yearBC( value, pattern ):
    """decoding helper for a year value, no conversion, no rounding, limits to 3000"""
    return dh_noConv( value, pattern, formatLimits['YearBC'][0] )

def dh_yearAD( value, pattern ):
    """decoding helper for a year value, no conversion, no rounding, limits to 3000"""
    return dh_noConv( value, pattern, formatLimits['YearAD'][0] )

def dh_simpleYearAD( value ):
    """decoding helper for a single integer value representing a year with no extra symbols"""
    return dh_yearAD( value, u'%d' )

def dh_number( value, pattern ):
    return dh_noConv( value, pattern, formatLimits['Number'][0] )
def dh_centuryAD( value, pattern ):
    return dh_noConv( value, pattern, formatLimits['CenturyAD'][0] )
def dh_centuryBC( value, pattern ):
    return dh_noConv( value, pattern, formatLimits['CenturyBC'][0] )
def dh_millenniumAD( value, pattern ):
    return dh_noConv( value, pattern, formatLimits['MillenniumAD'][0] )
def dh_millenniumBC( value, pattern ):
    return dh_noConv( value, pattern, formatLimits['MillenniumBC'][0] )


def decSinglVal( v ):
    return v[0]

def encNoConv( i ):
    return i

def encDec0( i ):
    return (i/10)*10            # round to the nearest decade, decade starts with a '0'-ending year

def encDec1( i ):
    return encDec0(i)+1         # round to the nearest decade, decade starts with a '1'-ending year

def slh( value, lst ):
    """This function helps in simple list value matching.
    !!!!! The index starts at 1, so 1st element has index 1, not 0 !!!!!
        Usually it will be used as a lambda call in a map:
            lambda v: slh( v, [u'January',u'February',...] )

        Usage scenarios:
            formats['MonthName']['en'](1) => u'January'
            formats['MonthName']['en'](u'January') => 1
            formats['MonthName']['en'](u'anything else') => raise ValueError
    """
    if type(value) in _stringTypes:
        return lst.index(value)+1
    else:
        return lst[value-1]

def dh_singVal( value, match ):
    return dh_constVal( value, 0, match )

def dh_constVal( value, ind, match ):
    """This function helps with matching a single value to a constant.
            formats['CurrEvents']['en'](ind) => u'Current Events'
            formats['CurrEvents']['en'](u'Current Events') => ind"""
    if type(value) in _stringTypes:
        if value == match:
            return ind
        else:
            raise ValueError()
    else:
        if value == ind:
            return match
        else:
            raise ValueError("unknown value %d" % value)

def alwaysTrue( x ):
    """This function always returns True - its used for multiple value selection function
       to accept all other values"""
    return True

def monthName(lang, ind):
    return formats['MonthName'][lang](ind)


# Helper for KN: digits representation
_knDigits = u''
_knDigitsToLocal = dict([(ord(unicode(i)), _knDigits[i]) for i in range(10)])
_knLocalToDigits = dict([(ord(_knDigits[i]), unicode(i)) for i in range(10)])

# Helper for Urdu/Persian languages
_faDigits = u''
_faDigitsToLocal = dict([(ord(unicode(i)), _faDigits[i]) for i in range(10)])
_faLocalToDigits = dict([(ord(_faDigits[i]), unicode(i)) for i in range(10)])

# Helper for HI:, MR:
_hiDigits = u''
_hiDigitsToLocal = dict([(ord(unicode(i)), _hiDigits[i]) for i in range(10)])
_hiLocalToDigits = dict([(ord(_hiDigits[i]), unicode(i)) for i in range(10)])

# Helper for BN:
_bnDigits = u''
_bnDigitsToLocal = dict([(ord(unicode(i)), _bnDigits[i]) for i in range(10)])
_bnLocalToDigits = dict([(ord(_bnDigits[i]), unicode(i)) for i in range(10)])

# Helper for GU:
_guDigits = u''
_guDigitsToLocal = dict([(ord(unicode(i)), _guDigits[i]) for i in range(10)])
_guLocalToDigits = dict([(ord(_guDigits[i]), unicode(i)) for i in range(10)])

def intToLocalDigitsStr( value, digitsToLocalDict ):
    # Encode an integer value into a textual form.
    return unicode(value).translate(digitsToLocalDict)

def localDigitsStrToInt( value, digitsToLocalDict, localToDigitsDict ):
    # First make sure there are no real digits in the string
    tmp = value.translate(digitsToLocalDict)         # Test
    if tmp == value:
        return int(value.translate(localToDigitsDict))    # Convert
    else:
        raise ValueError("string contains regular digits")

# Decimal digits used for various matchings
_decimalDigits = '0123456789'

# Helper for roman numerals number representation
_romanNumbers = ['-', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX',
             'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX',
             'XX', 'XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI', 'XXVII', 'XXVIII', 'XXVIX',
             'XXX']

def intToRomanNum(i):
    if i >= len(_romanNumbers):
        raise IndexError(u'Roman value %i is not defined' % i)
    return _romanNumbers[i]

def romanNumToInt(v):
    return _romanNumbers.index(v)

# Each tuple must 3 parts:  a list of all possible digits (symbols), encoder (from int to a u-string) and decoder (from u-string to an int)
_digitDecoders = {
    # %% is a %
    '%' : u'%',
    # %d is a decimal
    'd' : ( _decimalDigits, unicode, int ),
    # %R is a roman numeral. This allows for only the simpliest linear conversions based on a list of numbers
    'R' : ( u'IVX', intToRomanNum, romanNumToInt ),
    # %K is a number in KN::
    'K' : ( _knDigits, lambda v: intToLocalDigitsStr(v, _knDigitsToLocal), lambda v: localDigitsStrToInt(v, _knDigitsToLocal, _knLocalToDigits) ),
    # %F is a number in FA:
    'F' : ( _faDigits, lambda v: intToLocalDigitsStr(v, _faDigitsToLocal), lambda v: localDigitsStrToInt(v, _faDigitsToLocal, _faLocalToDigits) ),
    # %H is a number in HI:
    'H' : ( _hiDigits, lambda v: intToLocalDigitsStr(v, _hiDigitsToLocal), lambda v: localDigitsStrToInt(v, _hiDigitsToLocal, _hiLocalToDigits) ),
    # %B is a number in BN:
    'B' : ( _bnDigits, lambda v: intToLocalDigitsStr(v, _bnDigitsToLocal), lambda v: localDigitsStrToInt(v, _bnDigitsToLocal, _bnLocalToDigits) ),
    # %G is a number in GU:
    'G' : ( _guDigits, lambda v: intToLocalDigitsStr(v, _guDigitsToLocal), lambda v: localDigitsStrToInt(v, _guDigitsToLocal, _guLocalToDigits) ),
    # %T is a year in TH: -- all years are shifted: 2005 => '.. 2548'
    'T' : ( _decimalDigits, lambda v: unicode(v+543), lambda v: int(v)-543 ),
}

# Allows to search for '(%%)|(%d)|(%R)|...", and allows one digit 1-9  to set the size of zero-padding for numbers
_reParameters = re.compile(u'|'.join([ u'(%%[1-9]?%s)' % s for s in _digitDecoders.keys() ]))

# A map of   sitecode+pattern  to  (re matching object and corresponding decoders)
_escPtrnCache2 = {}

# Allow both unicode and single-byte strings
_stringTypes = [unicode, str]
_listTypes = [tuple, list]

def escapePattern2( pattern ):
    """Converts a string pattern into a regex expression and cache.
    Allows matching of any _digitDecoders inside the string.
    Returns a compiled regex object and a list of digit decoders"""

    if pattern not in _escPtrnCache2:
        newPattern = u'^' # begining of the string
        strPattern = u''
        decoders = []
        for s in _reParameters.split(pattern):
            if s is None:
                pass
            elif len(s) in [2, 3] and s[0] == '%' and s[-1] in _digitDecoders and (len(s) == 2 or s[1] in _decimalDigits):
                # Must match a "%2d" or "%d" style
                dec = _digitDecoders[s[-1]]
                if type(dec) in _stringTypes:
                    # Special case for strings that are replaced instead of decoded
                    if len(s) == 3: raise AssertionError("Invalid pattern %s: Cannot use zero padding size in %s!" % (pattern, s))
                    newPattern += re.escape( dec )
                    strPattern += s         # Keep the original text
                else:
                    if len(s) == 3:
                        newPattern += u'([%s]{%s})' % (dec[0], s[1])    # enforce mandatory field size
                        dec += (int(s[1]),)   # add the number of required digits as the last (4th) part of the tuple
                    else:
                        newPattern += u'([%s]+)' % dec[0]

                    decoders.append( dec )
                    strPattern += u'%s'     # All encoders produce a string   # this causes problem with the zero padding. Need to rethink
            else:
                newPattern += re.escape( s )
                strPattern += s

        newPattern += u'$' # end of the string
        compiledPattern = re.compile( newPattern )
        _escPtrnCache2[pattern] = (compiledPattern, strPattern, decoders)

    return _escPtrnCache2[pattern]


def dh( value, pattern, encf, decf, filter = None ):
    """This function helps in year parsing.
        Usually it will be used as a lambda call in a map:
            lambda v: dh( v, u'pattern string', encodingFunc, decodingFunc )

        encodingFunc:
            Converts from an integer parameter to another integer or a tuple of integers.
            Depending on the pattern, each integer will be converted to a proper string
            representation, and will be passed as a format argument to the pattern:
                        pattern % encodingFunc(value)
            This function is a complement of decodingFunc.

        decodingFunc:
            Converts a tuple/list of non-negative integers found in the original value string
            into a normalized value. The normalized value can be passed right back into dh()
            to produce the original string. This function is a complement of encodingFunc.
            dh() interprets %d as a decimal and %s as a roman numeral number.
    """

    compPattern, strPattern, decoders = escapePattern2(pattern)

    if type(value) in _stringTypes:
        m = compPattern.match(value)
        if m:
            # decode each found value using provided decoder
            values = [ decoders[i][2](m.group(i+1)) for i in range(len(decoders))]
            decValue = decf( values )

            if decValue in _stringTypes:
                raise AssertionError("Decoder must not return a string!")

            # recursive call to re-encode and see if we get the original (may through filter exception)
            if value == dh(decValue, pattern, encf, decf, filter):
                return decValue

        raise ValueError("reverse encoding didn't match")
    else:
        # Encode an integer value into a textual form.
        # This will be called from outside as well as recursivelly to verify parsed value
        if filter and not filter(value):
            raise ValueError("value %i is not allowed" % value)

        params = encf(value)

        if type(params) in _listTypes:
            if len(params) != len(decoders):
                raise AssertionError("parameter count (%d) does not match decoder count (%d)" % (len(params), len(decoders)))
            # convert integer parameters into their textual representation
            params = [ MakeParameter(decoders[i], params[i]) for i in range(len(params)) ]
            return strPattern % tuple(params)
        else:
            if 1 != len(decoders):
                raise AssertionError("A single parameter does not match %d decoders." % len(decoders))
            # convert integer parameter into its textual representation
            return strPattern % MakeParameter(decoders[0], params)

def MakeParameter( decoder, param ):
    newValue = decoder[1](param)
    if len(decoder) == 4 and len(newValue) < decoder[3]:
        # force parameter length by taking the first digit in the list and repeating it required number of times
        # This converts "205" into "0205" for "%4d"
        newValue = decoder[0][0] * (decoder[3]-len(newValue)) + newValue
    return newValue

#
# All years/decades/centuries/millenniums are designed in such a way
# as to allow for easy date to string and string to date conversion.
# For example, using any map with either an integer or a string will produce its oposite value:
#        Usage scenarios:
#            formats['DecadeAD']['en'](1980) => u'1980s'
#            formats['DecadeAD']['en'](u'1980s') => 1980
#            formats['DecadeAD']['en'](u'anything else') => raise ValueError (or some other exception?)
# This is useful when trying to decide if a certain article is a localized date or not, or generating dates.
# See dh() for additional information.
#
#
#          ***********   ATTENTION! ***********
#
#   You must test this table before submitting it to CVS by calling     date.test()  method
#
formats = {
    'MonthName': {
            'af' :      lambda v: slh( v, [u"Januarie", u"Februarie", u"Maart", u"April", u"Mei", u"Junie", u"Julie", u"Augustus", u"September", u"Oktober", u"November", u"Desember"] ),
            'als':      lambda v: slh( v, [u"Januar", u"Februar", u"Mrz", u"April", u"Mai", u"Juni", u"Juli", u"August", u"September", u"Oktober", u"November", u"Dezember"] ),
            'an' :      lambda v: slh( v, [u"chinero", u"frebero", u"marzo", u"abril", u"mayo", u"chunio", u"chulio", u"agosto", u"setiembre", u"otubre", u"nobiembre", u"abiento"] ),
            'ang':      lambda v: slh( v, [u"fterra Gola", u"Solmna", u"Hrmna", u"astermna", u"rimilcemna", u"Sremna", u"Mdmna", u"Wodmna", u"Hligmna", u"Winterfylle", u"Bltmna", u"Golmna"] ),
            'ar' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'ast':      lambda v: slh( v, [u"xineru", u"febreru", u"marzu", u"abril", u"mayu", u"xunu", u"xunetu", u"agostu", u"setiembre", u"ochobre", u"payares", u"avientu"] ),
            'be' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'bg' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'bn' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'br' :      lambda v: slh( v, [u"Genver", u"C'hwevrer", u"Meurzh", u"Ebrel", u"Mae", u"Mezheven", u"Gouere", u"Eost", u"Gwengolo", u"Here", u"Du", u"Kerzu"] ),
            'bs' :      lambda v: slh( v, [u"januar", u"februar", u"mart", u"april", u"maj", u"juni", u"juli", u"august", u"septembar", u"oktobar", u"novembar", u"decembar"] ),
            'ca' :      lambda v: slh( v, [u"gener", u"febrer", u"mar", u"abril", u"maig", u"juny", u"juliol", u"agost", u"setembre", u"octubre", u"novembre", u"desembre"] ),
            'ceb':      lambda v: slh( v, [u"Enero", u"Pebrero", u"Marso", u"Abril", u"Mayo", u"Hunyo", u"Hulyo", u"Agosto", u"Septiyembre", u"Oktubre", u"Nobiyembre", u"Disyembre"] ),
            'co' :      lambda v: slh( v, [u"ghjennaghju", u"frivaghju", u"marzu", u"aprile", u"maghju", u"ghjugnu", u"lugliu", u"aostu", u"settembre", u"uttrovi", u"nuvembri", u"decembre"] ),
            'cs' :      lambda v: slh( v, [u"leden", u"nor", u"bezen", u"duben", u"kvten", u"erven", u"ervenec", u"srpen", u"z", u"jen", u"listopad", u"prosinec"] ),
            'csb':      lambda v: slh( v, [u"stcznik", u"gromicznik", u"strumiannik", u"kwit", u"mj", u"czerwic", u"lpinc", u"zlnik", u"swnik", u"rujan", u"lstopadnik", u"gdnik"] ),
            'cv' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'cy' :      lambda v: slh( v, [u"Ionawr", u"Chwefror", u"Mawrth", u"Ebrill", u"Mai", u"Mehefin", u"Gorffennaf", u"Awst", u"Medi", u"Hydref", u"Tachwedd", u"Rhagfyr"] ),
            'da' :      lambda v: slh( v, [u"januar", u"februar", u"marts", u"april", u"maj", u"juni", u"juli", u"august", u"september", u"oktober", u"november", u"december"] ),
            'de' :      lambda v: slh( v, [u"Januar", u"Februar", u"Mrz", u"April", u"Mai", u"Juni", u"Juli", u"August", u"September", u"Oktober", u"November", u"Dezember"] ),
            'el' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'en' :      lambda v: slh( v, enMonthNames ),
            'eo' :      lambda v: slh( v, [u"Januaro", u"Februaro", u"Marto", u"Aprilo", u"Majo", u"Junio", u"Julio", u"Agusto", u"Septembro", u"Oktobro", u"Novembro", u"Decembro"] ),
            'es' :      lambda v: slh( v, [u"enero", u"febrero", u"marzo", u"abril", u"mayo", u"junio", u"julio", u"agosto", u"septiembre", u"octubre", u"noviembre", u"diciembre"] ),
            'et' :      lambda v: slh( v, [u"jaanuar", u"veebruar", u"mrts", u"aprill", u"mai", u"juuni", u"juuli", u"august", u"september", u"oktoober", u"november", u"detsember"] ),
            'eu' :      lambda v: slh( v, [u"Urtarril", u"Otsail", u"Martxo", u"Apiril", u"Maiatz", u"Ekain", u"Uztail", u"Abuztu", u"Irail", u"Urri", u"Azaro", u"Abendu"] ),
            'fa' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'fi' :      lambda v: slh( v, [u"tammikuu", u"helmikuu", u"maaliskuu", u"huhtikuu", u"toukokuu", u"keskuu", u"heinkuu", u"elokuu", u"syyskuu", u"lokakuu", u"marraskuu", u"joulukuu"] ),
            'fo' :      lambda v: slh( v, [u"januar", u"februar", u"mars", u"aprl", u"mai", u"juni", u"juli", u"august", u"september", u"oktober", u"november", u"desember"] ),
            'fr' :      lambda v: slh( v, [u"janvier", u"fvrier", u"mars (mois)", u"avril", u"mai", u"juin", u"juillet", u"aot", u"septembre", u"octobre", u"novembre", u"dcembre"] ),
            'fur':      lambda v: slh( v, [u"Zenr", u"Fevrr", u"Mar", u"Avrl", u"Mai", u"Jugn", u"Lui", u"Avost", u"Setembar", u"Otubar", u"Novembar", u"Dicembar"] ),
            'fy' :      lambda v: slh( v, [u"jannewaris", u"febrewaris", u"maart", u"april", u"maaie", u"juny", u"july", u"augustus", u"septimber", u"oktober", u"novimber", u"desimber"] ),
            'ga' :      lambda v: slh( v, [u"Eanir", u"Feabhra", u"Mrta", u"Aibren", u"Bealtaine", u"Meitheamh", u"Iil", u"Lnasa", u"Men Fmhair", u"Deireadh Fmhair", u"Samhain", u"Nollaig"] ),
            'gl' :      lambda v: slh( v, [u"xaneiro", u"febreiro", u"marzo", u"abril", u"maio", u"xuo", u"xullo", u"agosto", u"setembro", u"outubro", u"novembro", u"decembro"] ),
            'he' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'hi' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'hr' :      lambda v: slh( v, [u"sijeanj", u"veljaa", u"oujak", u"travanj", u"svibanj", u"lipanj", u"srpanj", u"kolovoz", u"rujan", u"listopad", u"studeni", u"prosinac"] ),
            'hu' :      lambda v: slh( v, [u"janur", u"februr", u"mrcius", u"prilis", u"mjus", u"jnius", u"jlius", u"augusztus", u"szeptember", u"oktber", u"november", u"december"] ),
            'ia' :      lambda v: slh( v, [u"januario", u"februario", u"martio", u"april", u"maio", u"junio", u"julio", u"augusto", u"septembre", u"octobre", u"novembre", u"decembre"] ),
            'id' :      lambda v: slh( v, [u"Januari", u"Februari", u"Maret", u"April", u"Mei", u"Juni", u"Juli", u"Agustus", u"September", u"Oktober", u"November", u"Desember"] ),
            'ie' :      lambda v: slh( v, [u"januar", u"februar", u"marte", u"april", u"may", u"junio", u"juli", u"august", u"septembre", u"octobre", u"novembre", u"decembre"] ),
            'io' :      lambda v: slh( v, [u"januaro", u"februaro", u"Marto", u"aprilo", u"mayo", u"junio", u"julio", u"agosto", u"septembro", u"oktobro", u"novembro", u"decembro"] ),
            'is' :      lambda v: slh( v, [u"janar", u"febrar", u"mars (mnuur)", u"aprl", u"ma", u"jn", u"jl", u"gst", u"september", u"oktber", u"nvember", u"desember"] ),
            'it' :      lambda v: slh( v, [u"gennaio", u"febbraio", u"marzo", u"aprile", u"maggio", u"giugno", u"luglio", u"agosto", u"settembre", u"ottobre", u"novembre", u"dicembre"] ),
            'ja' :      lambda v: slh( v, makeMonthList( u"%d" )),
            'jv' :      lambda v: slh( v, [u"Januari", u"Februari", u"Maret", u"April", u"Mei", u"Juni", u"Juli", u"Agustus", u"September", u"Oktober", u"November", u"Desember"] ),
            'ka' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'kn' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'ko' :      lambda v: slh( v, makeMonthList( u"%d" )),
            'ksh':      lambda v: slh( v, [u'Jannowaa', u'Febrowaa', u'M', u'Apprill', u'Meij', u'Juuni', u'Juuli', u'Auju', u'Sepptber', u'Oktoober', u'Novemmber', u'Dezemmber'] ),
            'ku' :      lambda v: slh( v, [u"rbendan", u"reem", u"adar", u"avrl", u"gulan", u"pper", u"trmeh", u"gelawj (meh)", u"rezber", u"kewr", u"sermawez", u"berfanbar"] ),
            'kw' :      lambda v: slh( v, [u"Mys Genver", u"Mys Whevrer", u"Mys Merth", u"Mys Ebrel", u"Mys Me", u"Mys Metheven", u"Mys Gortheren", u"Mys Est", u"Mys Gwyngala", u"Mys Hedra", u"Mys Du", u"Mys Kevardhu"] ),
            'la' :      lambda v: slh( v, [u"Ianuarius", u"Februarius", u"Martius", u"Aprilis", u"Maius", u"Iunius", u"Iulius", u"Augustus (mensis)", u"September", u"October", u"November", u"December"] ),
            'lb' :      lambda v: slh( v, [u"Januar", u"Februar", u"Merz", u"Abrll", u"Mee", u"Juni", u"Juli", u"August", u"September", u"Oktober", u"November", u"Dezember"] ),
            'li' :      lambda v: slh( v, [u"jannewarie", u"fibberwarie", u"miert", u"april", u"mei", u"juni", u"juli", u"augustus (maond)", u"september", u"oktober", u"november", u"december"] ),
            'lt' :      lambda v: slh( v, [u"Sausis", u"Vasaris", u"Kovas", u"Balandis", u"Gegu", u"Birelis", u"Liepa", u"Rugpjtis", u"Rugsjis", u"Spalis", u"Lapkritis", u"Gruodis"] ),
            'lv' :      lambda v: slh( v, [u"Janvris", u"Februris", u"Marts", u"Aprlis", u"Maijs", u"Jnijs", u"Jlijs", u"Augusts", u"Septembris", u"Oktobris", u"Novembris", u"Decembris"] ),
            'mhr':      lambda v: slh( v, [ u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'mi' :      lambda v: slh( v, [u"Kohi-ttea", u"Hui-tanguru", u"Pout-te-rangi", u"Paenga-whwh", u"Haratua", u"Pipiri", u"Hngongoi", u"Here-turi-kk", u"Mahuru", u"Whiringa--nuku", u"Whiringa--rangi", u"Hakihea"] ),
            'ml' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'mr' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'ms' :      lambda v: slh( v, [u"Januari", u"Februari", u"Mac", u"April", u"Mei", u"Jun", u"Julai", u"Ogos", u"September", u"Oktober", u"November", u"Disember"] ),
            'nap':      lambda v: slh( v, [u"Jennaro", u"Frevaro", u"Mrzo", u"Abbrile", u"Maggio", u"Gigno", u"Luglio", u"Asto", u"Settembre", u"Ottovre", u"Nuvembre", u"Dicembre"] ),
            'nds':      lambda v: slh( v, [u"Januar", u"Februar", u"Mrz", u"April", u"Mai", u"Juni", u"Juli", u"August", u"September", u"Oktober", u"November", u"Dezember"] ),
            'nl' :      lambda v: slh( v, [u"januari", u"februari", u"maart", u"april", u"mei", u"juni", u"juli", u"augustus (maand)", u"september", u"oktober", u"november", u"december"] ),
            'nn' :      lambda v: slh( v, [u"januar", u"februar", u"mnaden mars", u"april", u"mai", u"juni", u"juli", u"august", u"september", u"oktober", u"november", u"desember"] ),
            'no' :      lambda v: slh( v, [u"januar", u"februar", u"mars", u"april", u"mai", u"juni", u"juli", u"august", u"september", u"oktober", u"november", u"desember"] ),
            'oc' :      lambda v: slh( v, [u"genir", u"febrir", u"mar", u"abril", u"mai", u"junh", u"julhet", u"agost", u"setembre", u"octobre", u"novembre", u"decembre"] ),
            'os' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'pl' :      lambda v: slh( v, [u"stycze", u"luty", u"marzec", u"kwiecie", u"maj", u"czerwiec", u"lipiec", u"sierpie", u"wrzesie", u"padziernik", u"listopad", u"grudzie"] ),
            'pt' :      lambda v: slh( v, [u"Janeiro", u"Fevereiro", u"Maro", u"Abril", u"Maio", u"Junho", u"Julho", u"Agosto", u"Setembro", u"Outubro", u"Novembro", u"Dezembro"] ),
            'ro' :      lambda v: slh( v, [u"ianuarie", u"februarie", u"martie", u"aprilie", u"mai", u"iunie", u"iulie", u"august", u"septembrie", u"octombrie", u"noiembrie", u"decembrie"] ),
            'ru' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'sc' :      lambda v: slh( v, [u"Ghennarzu", u"Frearzu", u"Martzu", u"Abrile", u"Maju", u"Lmpadas", u"Triulas", u"Astu", u"Cabudanni", u"Santugane", u"Santadria", u"Nadale"] ),
            'scn':      lambda v: slh( v, [u"jinnaru", u"frivaru", u"marzu", u"aprili", u"maiu", u"giugnu", u"giugnettu", u"austu", u"sittmmiru", u"uttviru", u"nuvmmiru", u"dicmmiru"] ),
            'sco':      lambda v: slh( v, [u"Januar", u"Februar", u"Mairch", u"Aprile", u"Mey", u"Juin", u"Julie", u"August", u"September", u"October", u"November", u"December"] ),
            'se' :      lambda v: slh( v, [u"oajagimnnu", u"guovvamnnu", u"njukamnnu", u"cuoomnnu", u"miessemnnu", u"geassemnnu", u"suoidnemnnu", u"borgemnnu", u"akamnnu", u"golggotmnnu", u"skbmamnnu", u"juovlamnnu"] ),
            'simple':   lambda v: slh( v, [u"January", u"February", u"March", u"April", u"May", u"June", u"July", u"August", u"September", u"October", u"November", u"December"] ),
            'sk' :      lambda v: slh( v, [u"janur", u"februr", u"marec", u"aprl", u"mj", u"jn", u"jl", u"august", u"september", u"oktber", u"november", u"december"] ),
            'sl' :      lambda v: slh( v, [u"januar", u"februar", u"marec", u"april", u"maj", u"junij", u"julij", u"avgust", u"september", u"oktober", u"november", u"december"] ),
            'sq' :      lambda v: slh( v, [u"Janari", u"Shkurti", u"Marsi (muaj)", u"Prilli", u"Maji", u"Qershori", u"Korriku", u"Gushti", u"Shtatori", u"Tetori", u"Nntori", u"Dhjetori"] ),
            'sr' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'su' :      lambda v: slh( v, [u"Januari", u"Pbruari", u"Maret", u"April", u"Mi", u"Juni", u"Juli", u"Agustus", u"Sptmber", u"Oktober", u"Nopmber", u"Dsmber"] ),
            'sv' :      lambda v: slh( v, [u"januari", u"februari", u"mars", u"april", u"maj", u"juni", u"juli", u"augusti", u"september", u"oktober", u"november", u"december"] ),
            'ta' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'te' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'th' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'tl' :      lambda v: slh( v, [u"Enero", u"Pebrero", u"Marso", u"Abril", u"Mayo", u"Hunyo", u"Hulyo", u"Agosto", u"Setyembre", u"Oktubre", u"Nobyembre", u"Disyembre"] ),
            'tpi':      lambda v: slh( v, [u"Janueri", u"Februeri", u"Mas", u"Epril", u"Me", u"Jun", u"Julai", u"Ogas", u"Septemba", u"Oktoba", u"Novemba", u"Disemba"] ),
            'tr' :      lambda v: slh( v, [u"Ocak", u"ubat", u"Mart", u"Nisan", u"Mays", u"Haziran", u"Temmuz", u"Austos", u"Eyll", u"Ekim", u"Kasm", u"Aralk"] ),
            'tt' :      lambda v: slh( v, [u"nwar", u"Febrl", u"Mart", u"pril", u"May", u"Yn", u"Yl", u"August", u"Sentber", u"ktber", u"Nyber", u"Dekber"] ),
            'uk' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'ur' :      lambda v: slh( v, [u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u"", u""] ),
            'vec':      lambda v: slh( v, [u"genaro", u"febraro", u"marzso", u"aprie", u"majo", u"giugno", u"lujo", u"agosto", u"setenbre", u"otobre", u"novenbre", u"dienbre"] ),
            'vi' :      lambda v: slh( v, [u"thng mt", u"thng hai", u"thng ba", u"thng t", u"thng nm", u"thng su", u"thng by", u"thng tm", u"thng chn", u"thng mi", u"thng mi mt", u"thng 12"] ),
            'vo' :      lambda v: slh( v, [u"Yanul", u"Febul", u"Mzul", u"Prilul", u"Mayul", u"Yunul", u"Yulul", u"Gustul", u"Setul", u"Tobul", u"Novul", u"Dekul"] ),
            'wa' :      lambda v: slh( v, [u"djanv", u"fevr", u"Mss (moes)", u"avri", u"may", u"djun", u"djulete", u"awousse", u"setimbe", u"octbe", u"nvimbe", u"decimbe"] ),
            'zh' :      lambda v: slh( v, makeMonthList( u"%d" )),
            'zh-min-nan': lambda v: slh( v, [u"It-goeh", u"J-goeh", u"Sa-goeh", u"S-goeh", u"G-goeh", u"Lak-goeh", u"Chhit-goeh", u"Peh-goeh", u"Ku-goeh", u"Chap-goeh", u"Chap-it-goeh", u"Chap-j-goeh"] ),
    },

    'Number': {
        'ar' :      lambda v: dh_number( v, u'%d ()' ),
        'be' :      lambda v: dh_number( v, u'%d ()' ),
        'bg' :      lambda v: dh_number( v, u'%d ()' ),
        'bs' :      lambda v: dh_number( v, u'%d (broj)' ),
        'cs' :      lambda v: dh_number( v, u'%d (slo)' ),
        'da' :      lambda v: dh_number( v, u'%d (tal)' ),
        'en' :      lambda v: dh_number( v, u'%d (number)' ),
        'fa' :      lambda v: dh_number( v, u'%d ()' ),
        'fi' :      lambda v: dh_number( v, u'%d (luku)' ),
        'fr' :      lambda v: dh_number( v, u'%d (nombre)' ),
        'he' :      lambda v: dh_number( v, u'%d ()' ),
        'hu' :      lambda v: dh_number( v, u'%d (szm)' ),
        'ia' :      lambda v: dh_number( v, u'%d (numero)' ),
        'ja' :      lambda v: dh_number( v, u'%d' ),
        'ko' :      lambda v: dh_number( v, u'%d' ),
        'ksh':      lambda v: dh_number( v, u'%d (Zahl)' ),
        'la' :      lambda v: dh_number( v, u'%d' ),
        'lt' :      lambda v: dh_number( v, u'%d (skaiius)' ),
        'nds':      lambda v: dh_number( v, u'%d (Tall)' ),
        'nl' :      lambda v: dh_number( v, u'%d (getal)' ),
        'nn' :      lambda v: dh_number( v, u'Talet %d' ),
        'no' :      lambda v: dh_number( v, u'%d (tall)' ),
        'pl' :      lambda v: dh_number( v, u'%d (liczba)' ),
        'ro' :      lambda v: dh_number( v, u'%d (cifr)' ),
        'ru' :      lambda v: dh_number( v, u'%d ()' ),
        'sk' :      lambda v: dh_number( v, u'%d (slo)' ),
        'sl' :      lambda v: dh_number( v, u'%d (tevilo)' ),
        'sr' :      lambda v: dh_number( v, u'%d ()' ),
        'sv' :      lambda v: dh_number( v, u'%d (tal)' ),
        'th' :      lambda v: dh_number( v, u'%d' ),    # was %d ()
        'tl' :      lambda v: dh_number( v, u'%d (bilang)' ),
        'tr' :      lambda v: dh_number( v, u'%d (say)' ),
        'zh' :      lambda v: dh_number( v, u'%d' ),
    },

    'YearAD': {
        'af' :      dh_simpleYearAD,
        'als':      dh_simpleYearAD,
        'an' :      dh_simpleYearAD,
        'ang':      dh_simpleYearAD,
        'ar' :      dh_simpleYearAD,
        'ast':      dh_simpleYearAD,
        'az' :      dh_simpleYearAD,
        'be' :      dh_simpleYearAD,
        'bg' :      dh_simpleYearAD,
        'bn' :      lambda v: dh_yearAD( v, u'%B' ),
        'br' :      dh_simpleYearAD,
        'bs' :      dh_simpleYearAD,
        'ca' :      dh_simpleYearAD,
        'ceb':      dh_simpleYearAD,
        'cs' :      dh_simpleYearAD,
        'csb':      dh_simpleYearAD,
        'cv' :      dh_simpleYearAD,
        'cy' :      dh_simpleYearAD,
        'da' :      dh_simpleYearAD,
        'de' :      dh_simpleYearAD,
        'el' :      dh_simpleYearAD,
        'en' :      dh_simpleYearAD,
        'eo' :      dh_simpleYearAD,
        'es' :      dh_simpleYearAD,
        'et' :      dh_simpleYearAD,
        'eu' :      dh_simpleYearAD,
        'fa' :      lambda v: dh_yearAD( v, u'%F ()' ),
        'fi' :      dh_simpleYearAD,
        'fo' :      dh_simpleYearAD,
        'fr' :      dh_simpleYearAD,
        'fur':      dh_simpleYearAD,
        'fy' :      dh_simpleYearAD,
        'ga' :      dh_simpleYearAD,
        'gd' :      dh_simpleYearAD,
        'gl' :      dh_simpleYearAD,
        'gu' :      lambda v: dh_yearAD( v, u'%G' ),
        'he' :      dh_simpleYearAD,
        'hi' :      lambda v: dh_yearAD( v, u'%H' ),
        'hr' :      lambda v: dh_yearAD( v, u'%d.' ),
        'hu' :      dh_simpleYearAD,
        'hy' :      dh_simpleYearAD,
        'ia' :      dh_simpleYearAD,
        'id' :      dh_simpleYearAD,
        'ie' :      dh_simpleYearAD,
        'ilo':      dh_simpleYearAD,
        'io' :      dh_simpleYearAD,
        'is' :      dh_simpleYearAD,
        'it' :      dh_simpleYearAD,
        'ja' :      lambda v: dh_yearAD( v, u'%d' ),
        'jbo':      lambda v: dh_yearAD( v, u'%dmoi nanca' ),
        'ka' :      dh_simpleYearAD,
        'kn' :      lambda v: dh_yearAD( v, u'%K' ),
        'ko' :      lambda v: dh_yearAD( v, u'%d' ),
        'ksh':      lambda v: dh_yearAD( v, u'Joohr %d' ),
        'ku' :      dh_simpleYearAD,
        'kw' :      dh_simpleYearAD,
        'la' :      dh_simpleYearAD,
        'lb' :      dh_simpleYearAD,
        'li' :      dh_simpleYearAD,
        'lt' :      dh_simpleYearAD,
        'lv' :      dh_simpleYearAD,
        'mi' :      dh_simpleYearAD,
        'mhr':      dh_simpleYearAD,
        'mk' :      dh_simpleYearAD,
        'ml' :      dh_simpleYearAD,
        'mo' :      dh_simpleYearAD,
        'mr' :      lambda v: dh_yearAD( v, u'.. %H' ),
        'ms' :      dh_simpleYearAD,
        'na' :      dh_simpleYearAD,
        'nap':      dh_simpleYearAD,
        'nds':      dh_simpleYearAD,
        'nl' :      dh_simpleYearAD,
        'nn' :      dh_simpleYearAD,
        'no' :      dh_simpleYearAD,
        'oc' :      dh_simpleYearAD,
        'os' :      dh_simpleYearAD,
        'pl' :      dh_simpleYearAD,
        'pt' :      dh_simpleYearAD,
        'rm' :      dh_simpleYearAD,
        'ro' :      dh_simpleYearAD,
        'roa-rup' : dh_simpleYearAD,
        'ru' :      lambda v: dh_yearAD( v, u'%d ' ),
        'sco':      dh_simpleYearAD,
        'scn':      dh_simpleYearAD,
        'se' :      dh_simpleYearAD,
        'sh' :      dh_simpleYearAD,
        'simple' :  dh_simpleYearAD,
        'sk' :      dh_simpleYearAD,
        'sl' :      dh_simpleYearAD,
        'sm' :      dh_simpleYearAD,
        'sq' :      dh_simpleYearAD,
        'sr' :      dh_simpleYearAD,
        'sv' :      dh_simpleYearAD,
        'su' :      dh_simpleYearAD,
        'ta' :      dh_simpleYearAD,
        'te' :      dh_simpleYearAD,

        #2005 => '.. 2548'
        'th' :      lambda v: dh_yearAD( v, u'.. %T' ),
        'tl' :      dh_simpleYearAD,
        'tpi':      dh_simpleYearAD,
        'tr' :      dh_simpleYearAD,
        'tt' :      dh_simpleYearAD,
        'uk' :      dh_simpleYearAD,
        'ur' :      lambda v: dh_yearAD( v, u'%d' ),
        'uz' :      dh_simpleYearAD,
        'vec':      dh_simpleYearAD,
        'vi' :      dh_simpleYearAD,
        'vo' :      dh_simpleYearAD,
        'wa' :      dh_simpleYearAD,
        'zh' :      lambda v: dh_yearAD( v, u'%d' ),
        'zh-min-nan' :  lambda v: dh_yearAD( v, u'%d n' ),
    },

    'YearBC': {
        'af' :      lambda v: dh_yearBC( v, u'%d v.C.' ),
        'ast':      lambda v: dh_yearBC( v, u'%d edC' ),
        'be' :      lambda v: dh_yearBC( v, u'%d  ..' ),
        'bg' :      lambda v: dh_yearBC( v, u'%d . ...' ),
        'bs' :      lambda v: dh_yearBC( v, u'%d p.n.e.' ),
        'ca' :      lambda v: dh_yearBC( v, u'%d aC' ),
        'cs' :      lambda v: dh_yearBC( v, u'%d p. n. l.' ),
        'cy' :      lambda v: dh_yearBC( v, u'%d CC' ),
        'da' :      lambda v: dh_yearBC( v, u'%d f.Kr.' ),
        'de' :      lambda v: dh_yearBC( v, u'%d v. Chr.' ),
        'el' :      lambda v: dh_yearBC( v, u'%d ..' ),
        'en' :      lambda v: dh_yearBC( v, u'%d BC' ),
        'eo' :      lambda v: dh_yearBC( v, u'-%d' ),
        'es' :      lambda v: dh_yearBC( v, u'%d a. C.' ),
        'et' :      lambda v: dh_yearBC( v, u'%d eKr' ),
        'eu' :      lambda v: dh_yearBC( v, u'K. a. %d' ),
        'fa' :      lambda v: dh_yearBC( v, u'%d (  )' ),
        'fi' :      lambda v: dh_yearBC( v, u'%d eaa.' ),
        'fo' :      lambda v: dh_yearBC( v, u'%d f. Kr.' ),
        'fr' :      lambda v: dh_yearBC( v, u'-%d' ),
        'gl' :      lambda v: dh_yearBC( v, u'-%d' ),
        'he' :      lambda v: dh_yearBC( v, u'%d  ' ),
        'hr' :      lambda v: dh_yearBC( v, u'%d. pr. Kr.' ),
        'hu' :      lambda v: dh_yearBC( v, u'I. e. %d' ),
        'id' :      lambda v: dh_yearBC( v, u'%d SM' ),
        'io' :      lambda v: dh_yearBC( v, u'%d aK' ),
        'is' :      lambda v: dh_yearBC( v, u'%d f. Kr.' ),
        'it' :      lambda v: dh_yearBC( v, u'%d a.C.' ),
        'ka' :      lambda v: dh_yearBC( v, u'. . %d' ),
        'ko' :      lambda v: dh_yearBC( v, u' %d' ),
        'ksh':      lambda v: dh_yearBC( v,u'Joohr %d fr Krt'),
        'la' :      lambda v: dh_yearBC( v, u'%d a.C.n.' ),
        'lb' :      lambda v: dh_yearBC( v, u'-%d' ),
        'lt' :      lambda v: dh_yearBC( v, u'%d m. pr. m. e.'),
        'lv' :      lambda v: dh_yearBC( v, u'%d p.m..'),
        'mk' :      lambda v: dh_yearBC( v, u'%d ...'),
        'ms' :      lambda v: dh_yearBC( v, u'%d SM' ),
        'nap':      lambda v: dh_yearBC( v, u'%d AC' ),
        'nds':      lambda v: dh_yearBC( v, u'%d v. Chr.' ),
        'nl' :      lambda v: dh_yearBC( v, u'%d v.Chr.' ),
        'nn' :      lambda v: dh_yearBC( v, u'-%d' ),
        'no' :      lambda v: dh_yearBC( v, u'%d f.Kr.' ),
        'oc' :      lambda v: dh_yearBC( v, u'-%d' ),
        'pl' :      lambda v: dh_yearBC( v, u'%d p.n.e.' ),
        'pt' :      lambda v: dh_yearBC( v, u'%d a.C.' ),
        'ro' :      lambda v: dh_yearBC( v, u'%d .Hr.' ),
        'ru' :      lambda v: dh_yearBC( v, u'%d   . .' ),
        'scn':      lambda v: dh_yearBC( v, u'%d a.C.' ),
        'simple' :  lambda v: dh_yearBC( v, u'%d BC' ),
        'sk' :      lambda v: dh_yearBC( v, u'%d pred Kr.' ),
        'sl' :      lambda v: dh_yearBC( v, u'%d pr. n. t.' ),
        'sq' :      lambda v: dh_yearBC( v, u'%d p.e.s.' ),
        'sr' :      lambda v: dh_yearBC( v, u'%d. . . .' ),
        'sv' :      lambda v: dh_yearBC( v, u'%d f.Kr.' ),
        'sw' :      lambda v: dh_yearBC( v, u'%d KK' ),
        'ta' :      lambda v: dh_yearBC( v, u'. %d' ),
        'tr' :      lambda v: dh_yearBC( v, u'M.. %d' ),
        'tt' :      lambda v: dh_yearBC( v, u'MA %d' ),
        'uk' :      lambda v: dh_yearBC( v, u'%d  . .' ),
        'uz' :      lambda v: dh_yearBC( v, u'Mil. av. %d' ),
        'vec':      lambda v: dh_yearBC( v, u'%d a.C.' ),
        'vo' :      lambda v: dh_yearBC( v, u'%d b.K.' ),
        'zh' :      lambda v: dh_yearBC( v, u'%d' ),
    },

    'DecadeAD': {
        'als':      lambda v: dh_decAD( v, u'%der' ),
        'ar' :      lambda v: dh_decAD( v, u'%d ' ),
        'ast':      lambda v: dh_decAD( v, u'Aos %d' ),
        'ang':      lambda v: dh_decAD( v, u'%de' ),
        'ast':      lambda v: dh_decAD( v, u'Aos %d' ),
        'bg' :      lambda v: dh_decAD( v, u'%d-' ),
        'br' :      lambda v: dh_decAD( v, u'Bloavezhio %d' ),
        'bs' :      lambda v: dh_decAD( v, u'%dte' ),

        # Unknown what the pattern is, but 1970 is different
        'ca' :      lambda m: multi( m, [
            (lambda v: dh_decAD( v, u'Dcada de %d' ),  lambda p: p == 1970),
            (lambda v: dh_decAD( v, u'Dcada del %d' ), alwaysTrue)]),

         #1970s => '1970-1979'
        'cs' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'1-9'),                                              lambda p: p == 1),
            (lambda v: dh( v, u'%d-%d', lambda i: (encDec0(i),encDec0(i)+9), decSinglVal ),     alwaysTrue)]),

        'cy' :      lambda v: dh_decAD( v, u'%dau' ),
        'da' :      lambda v: dh_decAD( v, u"%d'erne" ),
        'de' :      lambda v: dh_decAD( v, u'%der' ),
        'el' :      lambda v: dh_decAD( v, u' %d' ),
        'en' :      lambda v: dh_decAD( v, u'%ds' ),
        'eo' :      lambda v: dh_decAD( v, u'%d-aj jaroj' ),
        'es' :      lambda v: dh_decAD( v, u'Aos %d' ),
        'et' :      lambda v: dh_decAD( v, u'%d. aastad' ),
        'fa' :      lambda v: dh_decAD( v, u' %d ()' ),

        # decades ending in 00 are spelled differently
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'Ensimminen vuosikymmen'),  lambda p: p == 0),
            (lambda v: dh_decAD( v, u'%d-luku' ),                       lambda p: (p % 100 != 0)),
            (lambda v: dh_decAD( v, u'%d-vuosikymmen' ),                alwaysTrue)]),

        'fo' :      lambda v: dh_decAD( v, u'%d-rini' ),
        'fr' :      lambda v: dh_decAD( v, u'Annes %d' ),
        'ga' :      lambda v: dh_decAD( v, u'%did' ),
        'gan':      lambda v: dh_decAD( v, u'%d' ),
        'he' :      lambda m: multi( m, [
            (lambda v: dh( v, u' %d', lambda i: encDec0(i)%100, lambda ii: 1900 + ii[0] ), lambda p: p >= 1900 and p < 2000),
            # This is a dummy value, just to avoid validation testing.
            (lambda v: dh_decAD( v, u'%dth decade' ), alwaysTrue)]),        # ********** ERROR!!!

        'hi' :      lambda v: dh_decAD( v, u'%H  ' ),

        #1970s => 1970-1979
        'hr' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'1-9'),                                                  lambda p: p == 1),
            (lambda v: dh( v, u'%d-%d', lambda i: (encDec0(i),encDec0(i)+9), lambda ii: ii[0] ),    alwaysTrue)]),

        'hu' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'0-s vek'), lambda p: p == 1),
            (lambda v: dh_decAD( v, u'%d-as vek' ),    lambda p: (p % 100 / 10) in [0,2,3,6,8]),
            (lambda v: dh_decAD( v, u'%d-es vek' ),    alwaysTrue)]),

        'io' :      lambda v: dh_decAD( v, u'%da yari' ),

        #1970s => '19711980'
        'is' :      lambda v: dh( v, u'%d%d',                   lambda i: (encDec1(i),encDec1(i)+9), lambda ii: ii[0]-1 ),
        'it' :      lambda v: dh_decAD( v, u'Anni %d' ),
        'ja' :      lambda v: dh_decAD( v, u'%d' ),
        'ka' :      lambda v: dh_decAD( v, u'%d-' ),
        'ko' :      lambda v: dh_decAD( v, u'%d' ),
        'ksh':      lambda v: dh_decAD( v, u'%d-er Joohre' ),

        #1970s => 'Decennium 198' (1971-1980)
        'la' :      lambda v: dh( v, u'Decennium %d',            lambda i: encDec1(i)/10+1, lambda ii: (ii[0]-1)*10 ),

        #1970s => 'XX amiaus 8-as deimtmetis' (1971-1980)
        'lt' :      lambda v: dh( v, u'%R amiaus %d-as deimtmetis',
                        lambda i: (encDec1(i)/100+1, encDec1(i)%100/10+1),
                        lambda v: (v[0]-1)*100 + (v[1]-1)*10 ),

        #1970s => 'Ngahurutanga 198' (1971-1980)
        'mi' :      lambda v: dh( v, u'Ngahurutanga %d',         lambda i: encDec0(i)/10+1, lambda ii: (ii[0]-1)*10 ),

        'mhr':      lambda v: dh_decAD( v, u'%d ' ),

        #1970s => '1970-1979'
        'nl' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'1-9'),                                              lambda p: p == 1),
            (lambda v: dh( v, u'%d-%d', lambda i: (encDec0(i),encDec0(i)+9), decSinglVal ),     alwaysTrue)]),

        'nn' :      lambda v: dh_decAD( v, u'%d0-ra' ),    # FIXME: not sure of this one
        'no' :      lambda v: dh_decAD( v, u'%d-rene' ),
        'os' :      lambda v: dh_decAD( v, u'%d-' ),

        #1970s => 'Lata 70. XX wieku' for anything except 1900-1919, 2000-2019, etc, in which case its 'Lata 1900-1909'
        'pl' :      lambda m: multi( m, [
            (lambda v: dh( v, u'Lata %d-%d', lambda i: (encDec0(i),encDec0(i)+9), decSinglVal ),
                    lambda p: p%100 >= 0 and p%100 < 20 ),
            (lambda v: dh( v, u'Lata %d. %R wieku', lambda i: (encDec0(i)%100, encDec0(i)/100+1 ), lambda ii: (ii[1]-1)*100 + ii[0] ),
                    alwaysTrue)]),

        'pt' :      lambda v: dh_decAD( v, u'Dcada de %d' ),
        'ro' :      lambda v: dh_decAD( v, u'Anii %d' ),
        'ro' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'Primul deceniu d.Hr.'), lambda p: p == 0),
            (lambda v: dh_decAD( v, u'Anii %d' ),                   alwaysTrue)]),
        'ru' :      lambda v: dh_decAD( v, u'%d-' ),
        'scn':      lambda v: dh_decAD( v, u'%dini' ),
        'simple' :  lambda v: dh_decAD( v, u'%ds' ),

        # 1970 => '70. roky 20. storoia'
        'sk' :      lambda v: dh( v, u'%d. roky %d. storoia',
                        lambda i: (encDec0(i)%100, encDec0(i)/100+1),
                        lambda ii: (ii[1]-1)*100 + ii[0] ),

        'sl' :      lambda v: dh_decAD( v, u'%d.' ),
        'sq' :      lambda v: dh_decAD( v, u'Vitet %d' ),
        'sr' :      lambda v: dh_decAD( v, u'%d' ),

        'sv' :      lambda m: multi( m, [
            (lambda v: dh_decAD( v, u'%d-talet (decennium)' ), lambda p: (p % 100 == 0)),
            (lambda v: dh_decAD( v, u'%d-talet' ),             alwaysTrue)]),

        'tt' :      lambda v: dh_decAD( v, u'%d. yllar' ),

        'uk' :      lambda m: multi( m, [
            (lambda v: dh_decAD( v, u'%d-' ), lambda p: p == 0 or (p % 100 == 40)),
            (lambda v: dh_decAD( v, u'%d-' ), lambda p: p % 1000 == 0),
            (lambda v: dh_decAD( v, u'%d-' ), alwaysTrue)]),
        'ur' :      lambda v: dh_decAD( v, u'%d' ),
        'wa' :      lambda v: dh_decAD( v, u'Anyes %d' ),
        'zh' :      lambda v: dh_decAD( v, u'%d' ),
        'zh-min-nan' : lambda v: dh_decAD( v, u'%d n-ti' ),
    },

    'DecadeBC': {
        'de' :      lambda v: dh_decBC( v, u'%der v. Chr.' ),
        'da' :      lambda v: dh_decBC( v, u"%d'erne f.Kr." ),
        'en' :      lambda v: dh_decBC( v, u'%ds BC' ),
        'es' :      lambda v: dh_decBC( v, u'Aos %d adC' ),
        'et' :      lambda v: dh_decBC( v, u'%d. aastad eKr' ),
        'eu' :      lambda v: dh_decBC( v, u'K. a. %dko hamarkada' ),

        # decades ending in 00 are spelled differently
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'Ensimminen vuosikymmen eaa.'),  lambda p: p == 0),
            (lambda v: dh_decBC( v, u'%d-luku eaa.' ),                       lambda p: (p % 100 != 0)),
            (lambda v: dh_decBC( v, u'%d-vuosikymmen eaa.' ),                alwaysTrue)]),

        'fr' :      lambda v: dh_decBC( v, u'Annes -%d' ),
        'he' :      lambda v: dh_decBC( v, u' %d  ' ),
        'hr' :      lambda v: dh_decBC( v, u'%dih p.n.e.' ),

        'hu' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'i.e. 0-s vek' ),      lambda p: p == 0),
            (lambda v: dh_decBC( v, u'i.e. %d-as vek' ),           lambda p: (p % 100 / 10) in [0,2,3,6,8]),
            (lambda v: dh_decBC( v, u'i.e. %d-es vek' ),           alwaysTrue)]),

        'it' :      lambda v: dh_decBC( v, u'Anni %d a.C.' ),

        'ka' :      lambda v: dh_decBC( v, u'. . %d-' ),
        'ksh':      lambda v: dh_decBC( v, u'%d-er Joohre fr Krt'), # uncertain if that's right. might go to redirect.

        # '19-10 v. Chr.'
        'nl' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'9-1 v.Chr.'),                                                  lambda p: p == 1),
            (lambda v: dh( v, u'%d-%d v.Chr.', lambda i: (encDec0(i)+9,encDec0(i)), lambda ii: ii[1] ),    alwaysTrue)]),

        'pt' :      lambda v: dh_decBC( v, u'Dcada de %d a.C.' ),

        'ro' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'Primul deceniu .Hr.'), lambda p: p == 0),
            (lambda v: dh_decBC( v, u'Anii %d .Hr.' ),             alwaysTrue)]),

        'ru' :      lambda v: dh_decBC( v, u'%d-  . .' ),
        'sl' :      lambda v: dh_decBC( v, u'%d. pr. n. t.' ),

        'sv' :      lambda m: multi( m, [
            (lambda v: dh_decBC( v, u'%d-talet f.Kr. (decennium)' ), lambda p: (p % 100 == 0)),
            (lambda v: dh_decBC( v, u'%d-talet f.Kr.' ),             alwaysTrue)]),

        'tt' :      lambda v: dh_decBC( v, u'MA %d. yllar' ),
        'uk' :      lambda m: multi( m, [
            (lambda v: dh_decBC( v, u'%d-  ..' ), lambda p: p == 0 or (p % 100 == 40)),
            (lambda v: dh_decBC( v, u'%d-  ..' ), alwaysTrue)]),
        'zh' :      lambda v: dh_decBC( v, u'%d' ),
    },

    'CenturyAD': {
        'af' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%dste eeu' ),             lambda p: p in [1,8] or (p >= 20)),
            (lambda v: dh_centuryAD( v, u'%dde eeu' ),  alwaysTrue)]),
        'als':      lambda v: dh_centuryAD( v, u'%d. Jahrhundert' ),
        'ang':      lambda v: dh_centuryAD( v, u'%de garhundred' ),
        'ar' :      lambda v: dh_centuryAD( v, u' %d' ),
        'ast':      lambda v: dh_centuryAD( v, u'Sieglu %R' ),
        'be' :      lambda v: dh_centuryAD( v, u'%d ' ),
        'bg' :      lambda v: dh_centuryAD( v, u'%d ' ),
        'br' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ia kantved'),          lambda p: p == 1),
            (lambda v: dh_constVal( v, 2, u'Eil kantved'),          lambda p: p == 2),
            (lambda v: dh_centuryAD( v, u'%Re kantved' ),           lambda p: p in [2,3]),
            (lambda v: dh_centuryAD( v, u'%Rvet kantved' ),         alwaysTrue)]),
        'bs' :      lambda v: dh_centuryAD( v, u'%d. vijek' ),
        'ca' :      lambda v: dh_centuryAD( v, u'Segle %R' ),
        'cs' :      lambda v: dh_centuryAD( v, u'%d. stolet' ),
        'cv' :      lambda v: dh_centuryAD( v, u'%R ' ),
        'cy' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%deg ganrif' ),           lambda p: p in [17,19]),
            (lambda v: dh_centuryAD( v, u'%dain ganrif' ),          lambda p: p == 21),
            (lambda v: dh_centuryAD( v, u'%dfed ganrif' ),          alwaysTrue)]),
        'da' :      lambda v: dh_centuryAD( v, u'%d00-tallet' ),
        'de' :      lambda v: dh_centuryAD( v, u'%d. Jahrhundert' ),
        'el' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%d ' ),           lambda p: p == 20),
            (lambda v: dh_centuryAD( v, u'%d ' ),           alwaysTrue)]),
        'en' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%dst century' ),          lambda p: p == 1 or (p > 20 and p%10 == 1)),
            (lambda v: dh_centuryAD( v, u'%dnd century' ),          lambda p: p == 2 or (p > 20 and p%10 == 2)),
            (lambda v: dh_centuryAD( v, u'%drd century' ),          lambda p: p == 3 or (p > 20 and p%10 == 3)),
            (lambda v: dh_centuryAD( v, u'%dth century' ),          alwaysTrue)]),
        'eo' :      lambda v: dh_centuryAD( v, u'%d-a jarcento' ),
        'es' :      lambda v: dh_centuryAD( v, u'Siglo %R' ),
        'et' :      lambda v: dh_centuryAD( v, u'%d. sajand' ),
        'eu' :      lambda v: dh_centuryAD( v, u'%R. mendea' ),  # %R. mende
        'fa' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 20, u'  ()'),     lambda p: p == 20),
            # This is a dummy value, just to avoid validation testing.   Later, it should be replaced with a proper 'fa' titles
            (lambda v: dh_centuryAD( v, u' %d ()' ), alwaysTrue)]),        # ********** ERROR!!!
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ensimminen vuosisata'),  lambda p: p == 1),
            (lambda v: dh( v, u'%d00-luku', lambda i: i-1, lambda ii: ii[0]+1 ),     alwaysTrue)]),
        'fo' :      lambda v: dh_centuryAD( v, u'%d. ld' ),
        'fr' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%Rer sicle' ),           lambda p: p == 1),
            (lambda v: dh_centuryAD( v, u'%Re sicle' ),            alwaysTrue)]),
        'fy' :      lambda v: dh_centuryAD( v, u'%de ieu' ),
        'ga' :      lambda v: dh_centuryAD( v, u'%d haois' ),
        'gl' :      lambda v: dh_centuryAD( v, u'Sculo %R' ),
        'he' :      lambda v: dh_centuryAD( v, u' %d' ),
        'hi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 20, u' '),            lambda p: p == 20),
            # This is a dummy value, just to avoid validation testing.   Later, it should be replaced with a proper 'fa' titles
            (lambda v: dh_centuryAD( v, u'%dth century' ), alwaysTrue)]),        # ********** ERROR!!!
        'hr' :      lambda v: dh_centuryAD( v, u'%d. stoljee' ),
        'hu' :      lambda v: dh_centuryAD( v, u'%d. szzad' ),
        'id' :      lambda v: dh_centuryAD( v, u'Abad ke-%d' ),
        'io' :      lambda v: dh_centuryAD( v, u'%dma yar-cento' ),
        'it' :      lambda v: dh_centuryAD( v, u'%R secolo' ),
        'is' :      lambda v: dh_centuryAD( v, u'%d. ldin' ),
        'ja' :      lambda v: dh_centuryAD( v, u'%d' ),
        'jv' :      lambda v: dh_centuryAD( v, u'Abad kaping %d' ),
        'ka' :      lambda v: dh_centuryAD( v, u'%R ' ),
        'ko' :      lambda v: dh_centuryAD( v, u'%d' ),
        'ku' :      lambda v: dh_centuryAD( v, u"Sedsala %d'an" ),
        'kw' :      lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%dsa kansblydhen' ),  lambda p: p <= 3),
            (lambda v: dh_centuryAD( v, u'%da kansblydhen' ),   lambda p: p == 4),
            (lambda v: dh_centuryAD( v, u'%des kansblydhen' ),  lambda p: p == 5),
            (lambda v: dh_centuryAD( v, u'%dns kansblydhen' ),  lambda p: p >= 20),
            (lambda v: dh_centuryAD( v, u'%dves kansblydhen' ), alwaysTrue)]),
        'ksh':      lambda v: dh_centuryAD( v, u'%d. Joohunndot'), 
        'la' :      lambda v: dh_centuryAD( v, u'Saeculum %d' ),
        'lb' :      lambda v: dh_centuryAD( v, u'%d. Joerhonnert' ),

        # Limburgish (li) have individual names for each century
        'li' :      lambda v: slh( v, [u'Ierste iew', u'Twiede iew', u'Derde iew', u'Veerde iew', u'Viefde iew', u'Zesde iew', u'Zevende iew', u'Achste iew', u'Negende iew', u'Tiende iew', u'Elfde iew', u'Twelfde iew', u'Dertiende iew', u'Veertiende iew', u'Vieftiende iew', u'Zestiende iew', u'Zeventiende iew', u'Achtiende iew', u'Negentiende iew', u'Twintegste iew', u'Einentwintegste iew', u'Twientwintegste iew',] ),

        'lt' :      lambda v: dh_centuryAD( v, u'%R amius' ),
        'lv' :      lambda v: dh_centuryAD( v, u'%d. gadsimts' ),
        'mi' :      lambda v: dh_centuryAD( v, u'Tua %d rau tau' ),
        'mk' :      lambda v: dh_centuryAD( v, u'%d ' ),
        'nds':      lambda v: dh_centuryAD( v, u'%d. Johrhunnert' ),
        'nl' :      lambda v: dh_centuryAD( v, u'%de eeuw' ),
        'nn' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'1. rhundret'),                         lambda p: p == 1),
            (lambda v: dh( v, u'%d00-talet', lambda i: i-1, lambda ii: ii[0]+1 ),   alwaysTrue)]),
        'no' :      lambda v: dh_centuryAD( v, u'%d. rhundre' ),
        'os' :      lambda v: dh_centuryAD( v, u'%R ' ),
        'pl' :      lambda v: dh_centuryAD( v, u'%R wiek' ),
        'pt' :      lambda v: dh_centuryAD( v, u'Sculo %R' ),
        'ro' :      lambda v: dh_centuryAD( v, u'Secolul %R' ),
        'ru' :      lambda v: dh_centuryAD( v, u'%R ' ),
        'scn':      lambda v: dh_centuryAD( v, u'Sculu %R' ),
        'simple' :  lambda m: multi( m, [
            (lambda v: dh_centuryAD( v, u'%dst century' ), lambda p: p == 1 or (p > 20 and p%10 == 1)),
            (lambda v: dh_centuryAD( v, u'%dnd century' ), lambda p: p == 2 or (p > 20 and p%10 == 2)),
            (lambda v: dh_centuryAD( v, u'%drd century' ), lambda p: p == 3 or (p > 20 and p%10 == 3)),
            (lambda v: dh_centuryAD( v, u'%dth century' ), alwaysTrue)]),
        'sk' :      lambda v: dh_centuryAD( v, u'%d. storoie' ),
        'sl' :      lambda v: dh_centuryAD( v, u'%d. stoletje' ),
        'sr' :      lambda v: dh_centuryAD( v, u'%d. ' ),
        'sq' :      lambda v: dh_centuryAD( v, u'Shekulli %R' ),
        'sv' :      lambda v: dh( v, u'%d00-talet',                   lambda i: i-1, lambda ii: ii[0]+1 ),
        'su' :      lambda v: dh_centuryAD( v, u'Abad ka-%d' ),
        'th' :      lambda v: dh_centuryAD( v, u' %d' ),
        'tr' :      lambda v: dh_centuryAD( v, u'%d. yzyl' ),
        'tt' :      lambda v: dh_centuryAD( v, u'%d. yz' ),
        'uk' :      lambda v: dh_centuryAD( v, u'%d ' ),
        'ur' :      lambda v: dh_centuryAD( v, u'%2d00' ),
        'vi' :      lambda v: dh_centuryAD( v, u'Th k %d' ),
        'wa' :      lambda v: dh_centuryAD( v, u'%dinme sieke' ),
        'zh' :      lambda v: dh_centuryAD( v, u'%d' ),
        'zh-min-nan' : lambda v: dh_centuryAD( v, u'%d s-k' ),
    },

    'CenturyBC': {
        'af' :      lambda m: multi( m, [
            (lambda v: dh_centuryBC( v, u'%dste eeu v.C.' ),            lambda p: p in [1,8] or (p >= 20)),
            (lambda v: dh_centuryBC( v, u'%dde eeu v.C.' ),             alwaysTrue)]),
        'bg' :      lambda v: dh_centuryBC( v, u'%d  ...' ),
        'br' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ia kantved kt JK'),        lambda p: p == 1),
            (lambda v: dh_constVal( v, 2, u'Eil kantved kt JK'),        lambda p: p == 2),
            (lambda v: dh_centuryBC( v, u'%Re kantved kt JK'),          lambda p: p in [2,3]),
            (lambda v: dh_centuryBC( v, u'%Rvet kantved kt JK'),        alwaysTrue)]),
        'ca' :      lambda v: dh_centuryBC( v, u'Segle %R aC' ),
        'cs' :      lambda v: dh_centuryBC( v, u'%d. stolet p. n. l.' ),
        'da' :      lambda v: dh_centuryBC( v, u'%d. rhundrede f.Kr.' ),
        'de' :      lambda v: dh_centuryBC( v, u'%d. Jahrhundert v. Chr.' ),
        'el' :      lambda v: dh_centuryBC( v, u'%d  ..' ),
        'en' :      lambda m: multi( m, [
            (lambda v: dh_centuryBC( v, u'%dst century BC' ),           lambda p: p == 1 or (p > 20 and p%10 == 1)),
            (lambda v: dh_centuryBC( v, u'%dnd century BC' ),           lambda p: p == 2 or (p > 20 and p%10 == 2)),
            (lambda v: dh_centuryBC( v, u'%drd century BC' ),           lambda p: p == 3 or (p > 20 and p%10 == 3)),
            (lambda v: dh_centuryBC( v, u'%dth century BC' ),           alwaysTrue)]),
        'eo' :      lambda v: dh_centuryBC( v, u'%d-a jarcento a.K.' ),
        'es' :      lambda v: dh_centuryBC( v, u'Siglo %R adC' ),
        'et' :      lambda v: dh_centuryBC( v, u'%d. aastatuhat eKr' ),
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ensimminen vuosisata eaa.'),               lambda p: p == 1),
            (lambda v: dh( v, u'%d00-luku eaa.', lambda i: i-1, lambda ii: ii[0]+1 ),   alwaysTrue)]),
        'fr' :      lambda m: multi( m, [
            (lambda v: dh_centuryBC( v, u'%Rer sicle av. J.-C.' ),                     lambda p: p == 1),
            (lambda v: dh_centuryBC( v, u'%Re sicle av. J.-C.' ),                      alwaysTrue)]),
        'he' :      lambda v: dh_centuryBC( v, u' %d  ' ),
        'hr' :      lambda v: dh_centuryBC( v, u'%d. stoljee p.n.e.' ),
        'id' :      lambda v: dh_centuryBC( v, u'Abad ke-%d SM' ),
        'io' :      lambda v: dh_centuryBC( v, u'%dma yar-cento aK' ),
        'it' :      lambda v: dh_centuryBC( v, u'%R secolo AC' ),
        'ja' :      lambda v: dh_centuryBC( v, u'%d' ),
        'ka' :      lambda v: dh_centuryBC( v, u'. . %R ' ),
        'ko' :      lambda v: dh_centuryBC( v, u' %d' ),
        'ksh':      lambda v: dh_centuryBC( v, u'%d. Joohunndot fr Kret'), # uncertain if that's right. might go to redirect.
        'la' :      lambda v: dh_centuryBC( v, u'Saeculum %d a.C.n.' ),
        'lb' :      lambda v: dh_centuryBC( v, u'%d. Joerhonnert v. Chr.' ),
        'nl' :      lambda v: dh_centuryBC( v, u'%de eeuw v.Chr.' ),
        'nn' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'1. rhundret fvt.'),                        lambda p: p == 1),
            (lambda v: dh( v, u'%d00-talet fvt.', lambda i: i-1, lambda ii: ii[0]+1 ),  alwaysTrue)]),
        'no' :      lambda v: dh_centuryBC( v, u'%d. rhundre f.Kr.' ),
        'pl' :      lambda v: dh_centuryBC( v, u'%R wiek p.n.e.' ),
        'pt' :      lambda v: dh_centuryBC( v, u'Sculo %R a.C.' ),
        'ro' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Secolul I .Hr.'),                          lambda p: p == 1),
            (lambda v: dh_centuryBC( v, u'Secolul al %R-lea .Hr.' ),                   alwaysTrue)]),
        'ru' :      lambda v: dh_centuryBC( v, u'%R   . .' ),
        'scn':      lambda v: dh_centuryBC( v, u'Sculu %R a.C.' ),
        'sk' :      lambda v: dh_centuryBC( v, u'%d. storoie pred Kr.' ),
        'sl' :      lambda v: dh_centuryBC( v, u'%d. stoletje pr. n. t.' ),
        'sq' :      lambda v: dh_centuryBC( v, u'Shekulli %R p.e.s.' ),
        'sr' :      lambda v: dh_centuryBC( v, u'%d.  .' ),
        'sv' :      lambda v: dh( v, u'%d00-talet f.Kr.', lambda i: i-1, lambda ii: ii[0]+1 ),
        'tr' :      lambda v: dh_centuryBC( v, u'M %d. yzyl' ),
        'tt' :      lambda v: dh_centuryBC( v, u'MA %d. yz' ),
        'uk' :      lambda v: dh_centuryBC( v, u'%d   ..' ),
        'zh' :      lambda m: multi( m, [
            (lambda v: dh_centuryBC( v, u'%d' ),                                 lambda p: p < 4),
            (lambda v: dh_centuryBC( v, u'%d' ),                                 alwaysTrue)]),
    },

    'CenturyAD_Cat':{
        'cs' :      lambda v: dh_centuryAD( v, u'%d. stolet' ),
        'da' :      lambda v: dh_centuryAD( v, u'%d. rhundrede' ),
        'no' :      lambda v: dh( v, u'%d-tallet', lambda i: (i-1)*100, lambda ii: ii[0]/100+1 ),
        'ksh':      lambda v: dh_constVal( v, 1, u'Joohunndot' ),
    },

    'CenturyBC_Cat':{
        'cs' :      lambda v: dh_centuryBC( v, u'%d. stolet p. n. l.' ),
        'de' :      lambda v: dh_centuryBC( v, u'Jahr (%d. Jh. v. Chr.)' ),
        'no' :      lambda v: dh( v, u'%d-tallet f.Kr.', lambda i: (i-1)*100, lambda ii: ii[0]/100+1 ),
        'ksh':      lambda v: dh_constVal( v, 1, u'Joohunndot' ),
    },

    'MillenniumAD': {
        'bg' :      lambda v: dh_millenniumAD( v, u'%d ' ),
        'ca' :      lambda v: dh_millenniumAD( v, u'Millenni %R' ),
        'cs' :      lambda v: dh_millenniumAD( v, u'%d. tiscilet' ),
        'de' :      lambda v: dh_millenniumAD( v, u'%d. Jahrtausend' ),
        'el' :      lambda v: dh_millenniumAD( v, u'%d ' ),
        'en' :      lambda m: multi( m, [
            (lambda v: dh_millenniumAD( v, u'%dst millennium' ),                lambda p: p == 1 or (p > 20 and p%10 == 1)),
            (lambda v: dh_millenniumAD( v, u'%dnd millennium' ),                lambda p: p == 2 or (p > 20 and p%10 == 2)),
            (lambda v: dh_millenniumAD( v, u'%drd millennium' ),                lambda p: p == 3 or (p > 20 and p%10 == 3)),
            (lambda v: dh_millenniumAD( v, u'%dth millennium' ),                alwaysTrue)]),
        'es' :      lambda v: dh_millenniumAD( v, u'%R milenio' ),

        'fa' :      lambda v: dh_millenniumAD( v, u' %R ()' ),
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ensimminen vuosituhat'),                       lambda p: p == 1),
            (lambda v: dh_constVal( v, 2, u'Toinen vuosituhat'),                       lambda p: p == 2),
            (lambda v: dh_constVal( v, 3, u'Kolmas vuosituhat'),                       lambda p: p == 3),
            (lambda v: dh_constVal( v, 4, u'Neljs vuosituhat'),                       lambda p: p == 4),
            (lambda v: dh_constVal( v, 5, u'Viides vuosituhat'),                       lambda p: p == 5),
            (lambda v: dh( v, u'%d000-vuosituhat', lambda i: i-1, lambda ii: ii[0]+1 ),     alwaysTrue)]),

        'fr' :      lambda m: multi( m, [
            (lambda v: dh_millenniumAD( v, u'%Rer millnaire' ),                lambda p: p == 1),
            (lambda v: dh_millenniumAD( v, u'%Re millnaire' ),                 alwaysTrue)]),
        'he' :      lambda m: multi( m, [
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 1),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 2),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 3),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 4),
            (lambda v: dh_millenniumAD( v, u'  %d ' ),                lambda p: p == 5),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 6),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 7),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 8),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 9),
            (lambda v: dh_millenniumAD( v, u'  %d' ),                lambda p: p == 10),
            (lambda v: dh_millenniumAD( v, u' %d' ),                alwaysTrue)]),
        'hu' :      lambda v: dh_millenniumAD( v, u'%d. vezred' ),
        'it' :      lambda v: dh_millenniumAD( v, u'%R millennio' ),
        'ja' :      lambda v: dh_millenniumAD( v, u'%d' ),
        'ka' :      lambda v: dh_millenniumAD( v, u'%R ' ),
        'ksh':      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Eete Johdousend'),                lambda p: p == 1),
            (lambda v: dh_constVal( v, 2, u'Zweijte Johdousend'),              lambda p: p == 2),
            (lambda v: dh_constVal( v, 3, u'Drette Johdousend'),               lambda p: p == 3),
            (lambda v: dh_constVal( v, 4, u'Veete Johdousend'),                lambda p: p == 4),
            (lambda v: dh_constVal( v, 5, u'Ffte Johdousend'),                lambda p: p == 5),
            (lambda v: dh_milleniumAD( v, u'%d. Johdousend'),      alwaysTrue)]),
        'lb' :      lambda v: dh_millenniumAD( v, u'%d. Joerdausend' ),
        'mhr':      lambda v: dh_millenniumAD( v, u'%R.   ' ),
        'lt' :      lambda v: dh_millenniumAD( v, u'%d tkstantmetis' ),
        'pt' :      lambda v: slh( v, [u'Primeiro milnio d.C.', u'Segundo milnio d.C.', u'Terceiro milnio d.C.', u'Quarto milnio d.C.'] ),
        'ro' :      lambda v: slh( v, [u'Mileniul I', u'Mileniul al II-lea', u'Mileniul III'] ),
        'ru' :      lambda v: dh_millenniumAD( v, u'%d ' ),
        'sk' :      lambda v: dh_millenniumAD( v, u'%d. tiscroie' ),
        'sl' :      lambda v: dh_millenniumAD( v, u'%d. tisoletje' ),
        'sv' :      lambda v: dh( v, u'%d000-talet (millennium)', lambda i: i-1, lambda ii: ii[0]+1 ),
        'tt' :      lambda v: dh_millenniumAD( v, u'%d. meyllq' ),
        'ur' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 0, u'0000'),                          lambda p: p == 0),
            (lambda v: dh_millenniumAD( v, u'%d000' ),                       alwaysTrue)]),
    },

    'MillenniumBC': {
        'bg' :      lambda v: dh_millenniumBC( v, u'%d  ...' ),
        'ca' :      lambda v: dh_millenniumBC( v, u'Millenni %R aC' ),
        'cs' :      lambda v: dh_millenniumBC( v, u'%d. tiscilet p. n. l.' ),
        'da' :      lambda v: dh_millenniumBC( v, u'%d. rtusinde f.Kr.' ),
        'de' :      lambda v: dh_millenniumBC( v, u'%d. Jahrtausend v. Chr.' ),
        'el' :      lambda v: dh_millenniumBC( v, u'%d  ..' ),
        'en' :      lambda v: dh_millenniumBC( v, u'%dst millennium BC' ),
        'es' :      lambda v: dh_millenniumBC( v, u'%R milenio adC' ),
        'fi' :      lambda m: multi( m, [
            (lambda v: dh_constVal( v, 1, u'Ensimminen vuosituhat eaa.'),                   lambda p: p == 1),
            (lambda v: dh( v, u'%d000-vuosituhat eaa.', lambda i: i-1, lambda ii: ii[0]+1 ), alwaysTrue)]),
        'fr' :      lambda v: dh_millenniumBC( v, u'%Rer millnaire av. J.-C.' ),
        'he' :      lambda m: multi( m, [
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 1),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 2),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 3),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 4),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 5),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 6),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 7),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 8),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 9),
            (lambda v: dh_millenniumAD( v, u'  %d  ' ),                lambda p: p == 10),
            (lambda v: dh_millenniumAD( v, u' %d  ' ),                alwaysTrue)]),
        'hu' :      lambda v: dh_millenniumBC( v, u'I. e. %d. vezred' ),
        'it' :      lambda v: dh_millenniumBC( v, u'%R millennio AC' ),
        'ja' :      lambda v: dh_millenniumBC( v, u'%d' ),
        'ka' :      lambda v: dh_millenniumBC( v, u'. . %R ' ),
        'lb' :      lambda v: dh_millenniumBC( v, u'%d. Joerdausend v. Chr.' ),
        'nl' :      lambda v: dh_millenniumBC( v, u'%de millennium v.Chr.' ),
        'pt' :      lambda v: slh( v, [u'Primeiro milnio a.C.', u'Segundo milnio a.C.', u'Terceiro milnio a.C.', u'Quarto milnio a.C.'] ),
        'ro' :      lambda v: dh_millenniumBC( v, u'Mileniul %R .Hr.' ),
        'ru' :      lambda v: dh_millenniumBC( v, u'%d   . .' ),
        'sv' :      lambda v: dh( v, u'%d000-talet f.Kr. (millennium)',     lambda i: i-1, lambda ii: ii[0]+1 ),
        'tt' :      lambda v: dh_millenniumBC( v, u'MA %d. meyllq' ),
        'zh' :      lambda v: dh_millenniumBC( v, u'%d' ),
    },

    'Cat_Year_MusicAlbums': {
        'cs' :      lambda v: dh_yearAD( v, u'Alba roku %d' ),
        'en' :      lambda v: dh_yearAD( v, u'%d albums' ),
        'fa' :      lambda v: dh_yearAD( v, u' %d ()'),
        'fi' :      lambda v: dh_yearAD( v, u'Vuoden %d albumit' ),
        'fr' :      lambda v: dh_yearAD( v, u'Album musical sorti en %d' ),
        'he' :      lambda v: dh_yearAD( v, u' %d' ),
        'pl' :      lambda v: dh_yearAD( v, u'Albumy muzyczne wydane w roku %d' ),
        'sl' :      lambda v: dh_yearAD( v, u'Albumi iz %d' ),
        'sv' :      lambda v: dh_yearAD( v, u'%d rs musikalbum' ),
    },

    'CurrEvents': {
        'an' :      lambda v: dh_singVal( v, u'Autualid' ),
        'ang':      lambda v: dh_singVal( v, u'Efenealde belimpas' ),
        'ar' :      lambda v: dh_singVal( v, u' ' ),
        'be' :      lambda v: dh_singVal( v, u' ' ),
        'bg' :      lambda v: dh_singVal( v, u' ' ),
        'ca' :      lambda v: dh_singVal( v, u'Viquipdia:Actualitat' ),
        'cs' :      lambda v: dh_singVal( v, u'Portl:Aktuality' ),
        'da' :      lambda v: dh_singVal( v, u'Aktuelle begivenheder' ),
        'de' :      lambda v: dh_singVal( v, u'Aktuelle Ereignisse' ),
        'el' :      lambda v: dh_singVal( v, u' ' ),
        'en' :      lambda v: dh_singVal( v, u'Current events' ),
        'eo' :      lambda v: dh_singVal( v, u'Aktualaoj' ),
        'es' :      lambda v: dh_singVal( v, u'Actualidad' ),
        'et' :      lambda v: dh_singVal( v, u'Current events' ),
        'fa' :      lambda v: dh_singVal( v, u' '),
        'fi' :      lambda v: dh_singVal( v, u'Ajankohtaista' ),
        'fr' :      lambda v: dh_singVal( v, u'Actualits' ),
        'gl' :      lambda v: dh_singVal( v, u'Novas' ),
        'he' :      lambda v: dh_singVal( v, u'' ),
        'hu' :      lambda v: dh_singVal( v, u'Friss esemnyek' ),
        'id' :      lambda v: dh_singVal( v, u'Wikipedia:Peristiwa terkini' ),
        'io' :      lambda v: dh_singVal( v, u'Current events' ),
        'it' :      lambda v: dh_singVal( v, u'Attualit' ),
        'ja' :      lambda v: dh_singVal( v, u'' ),
        'ka' :      lambda v: dh_singVal( v, u' ' ),
        'ko' :      lambda v: dh_singVal( v, u' ' ),
        'ksh':      lambda v: dh_singVal( v, u'Et Neuste' ),
        'ku' :      lambda v: dh_singVal( v, u'Byern rojane' ),
        'la' :      lambda v: dh_singVal( v, u'Novissima' ),
        'lb' :      lambda v: dh_singVal( v, u'Aktualitit' ),
        'la' :      lambda v: dh_singVal( v, u"Nuntii" ),
        'li' :      lambda v: dh_singVal( v, u"In 't nuujs" ),
        'mn' :      lambda v: dh_singVal( v, u'' ),
        'nl' :      lambda v: dh_singVal( v, u'In het nieuws' ),
        'no' :      lambda v: dh_singVal( v, u'Aktuelt' ),
        'os' :      lambda v: dh_singVal( v, u'Xabar' ),
        'pl' :      lambda v: dh_singVal( v, u'Biece wydarzenia' ),
        'pt' :      lambda v: dh_singVal( v, u'Eventos atuais' ),
        'ro' :      lambda v: dh_singVal( v, u'Actualiti' ),
        'ru' :      lambda v: dh_singVal( v, u' ' ),
        'scn':      lambda v: dh_singVal( v, u'Nutizz' ),
        'simple':   lambda v: dh_singVal( v, u'World news' ),
        'sk' :      lambda v: dh_singVal( v, u'Aktuality' ),
        'sl' :      lambda v: dh_singVal( v, u'Trenutni dogodki' ),
        'sr' :      lambda v: dh_singVal( v, u':' ),
        'sv' :      lambda v: dh_singVal( v, u'Aktuella hndelser' ),
        'su' :      lambda v: dh_singVal( v, u'Keur lumangsung' ),
        'ta' :      lambda v: dh_singVal( v, u' ' ),
        'th' :      lambda v: dh_singVal( v, u'' ),
        'tl' :      lambda v: dh_singVal( v, u'Kasalukuyang pangyayari' ),
        'tr' :      lambda v: dh_singVal( v, u'Gncel olaylar' ),
        'uk' :      lambda v: dh_singVal( v, u' ' ),
        'ur' :      lambda v: dh_singVal( v, u' ' ),
        'vi' :      lambda v: dh_singVal( v, u'Thi s' ),
        'wa' :      lambda v: dh_singVal( v, u'Wikinoveles' ),
        'yo' :      lambda v: dh_singVal( v, u'Current events' ),
        'zh' :      lambda v: dh_singVal( v, u'' ),
        'zh-min-nan': lambda v: dh_singVal( v, u'Sin-bn s-ki' ),
    },
}

#
# Add auto-generated empty dictionaries for DayOfMonth and MonthOfYear articles
#
for dayOfMonth in dayMnthFmts:
    formats[dayOfMonth] = {}
for monthOfYear in yrMnthFmts:
    formats[monthOfYear] = {}

def addFmt( lang, isMnthOfYear, patterns ):
    """Add 12 month formats for a specific type ('January','Feb..), for a given language.
    The function must accept one parameter for the ->int or ->string conversions, just like
    everywhere else in the formats map.
    The patterns parameter is a list of 12 elements to be used for each month.
    """
    if len(patterns) != 12:
        raise AssertionError(u'pattern %s does not have 12 elements' % lang )

    for i in range(12):
        if patterns[i] is not None:
            if isMnthOfYear:
                formats[yrMnthFmts[i]][lang] = eval(u'lambda v: dh_mnthOfYear( v, u"%s" )' % patterns[i])
            else:
                formats[dayMnthFmts[i]][lang] = eval(u'lambda v: dh_dayOfMnth( v, u"%s" )' % patterns[i])

def makeMonthList( pattern ):
    return [ pattern % m for m in range(1,13) ]

def makeMonthNamedList( lang, pattern, makeUpperCase = None ):
    """Creates a list of 12 elements based on the name of the month.
    The language-dependent month name is used as a formating argument to the pattern.
    The pattern must be have one %s that will be replaced by the localized month name.
    Use %%d for any other parameters that should be preserved.
    """
    if makeUpperCase is None:
        f = lambda s: s
    elif makeUpperCase == True:
        f = lambda s: s[0].upper() + s[1:]
    elif makeUpperCase == False:
        f = lambda s: s[0].lower() + s[1:]

    return [ pattern % f(monthName(lang, m)) for m in range(1,13) ]

def addFmt2( lang, isMnthOfYear, pattern, makeUpperCase = None ):
    addFmt( lang, isMnthOfYear, makeMonthNamedList( lang, pattern, makeUpperCase ))


#
# Add day of the month formats to the formatting table:   "en:May 15"
#
addFmt2('af', False, u"%%d %s", True )
addFmt2('als',False, u"%%d. %s", True )
addFmt ('an', False,       [ u"%d de chinero", u"%d de frebero", u"%d de marzo", u"%d d'abril", u"%d de mayo", u"%d de chunio", u"%d de chulio", u"%d d'agosto", u"%d de setiembre", u"%d d'otubre", u"%d de nobiembre", u"%d d'abiento" ])
#addFmt ('ang',False,       [ u"%d fterra Gola", u"%d Solmna", u"%d Hrmna", u"%d astermna", u"%d rimilcemna", u"%d Sremna", u"%d Mdmna", u"%d Wodmna", u"%d Hligmna", u"%d Winterfylle", u"%d Bltmna", u"%d Golmna" ])
addFmt2('ang',False, u"%%d %s", True )
addFmt ('ar', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt ('ast',False,       [ u"%d de xineru", u"%d de febreru", u"%d de marzu", u"%d d'abril", u"%d de mayu", u"%d de xunu", u"%d de xunetu", u"%d d'agostu", u"%d de setiembre", u"%d d'ochobre", u"%d de payares", u"%d d'avientu" ])
addFmt ('be', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('bg', False, u"%%d %s", False )
#addFmt2('br', False, u"%%d %s", True ) # See bellow for br initialization
addFmt2('bn', False, u"%s %%B" )
addFmt2('bs', False, u"%%d. %s", False )
addFmt ('ca', False,       [ u"%d de gener", u"%d de febrer", u"%d de mar", u"%d d'abril", u"%d de maig", u"%d de juny", u"%d de juliol", u"%d d'agost", u"%d de setembre", u"%d d'octubre", u"%d de novembre", u"%d de desembre" ])
addFmt2('ceb',False, u"%s %%d", True )
addFmt ('co', False,       [ u"%d di ghjennaghju", u"%d di frivaghju", u"%d di marzu", u"%d d'aprile", u"%d di maghju", u"%d di ghjugnu", u"%d di lugliu", u"%d d'aostu", u"%d di settembre", u"%d d'uttrovi", u"%d di nuvembri", u"%d di decembre" ])
addFmt2('cs', False, u"%%d. %s", False )
addFmt2('csb',False, u"%%d %sa", False )
addFmt2('cv', False, u"%s, %%d", True )
addFmt2('cy', False, u"%%d %s", True )
addFmt2('da', False, u"%%d. %s", False )
addFmt2('de', False, u"%%d. %s", True )
addFmt ('el', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('en', False, u"%s %%d", True )
addFmt2('eo', False, u"%%d-a de %s", False )
addFmt2('es', False, u"%%d de %s", False )
addFmt2('et', False, u"%%d. %s", False )
addFmt2('eu', False, u"%saren %%d", True )
addFmt ('fa', False, [u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('fi', False, u"%%d. %sta", False )
addFmt2('fo', False, u"%%d. %s", False )
addFmt ('fr', False,       [ u"%d janvier", u"%d fvrier", u"%d mars", u"%d avril", u"%d mai", u"%d juin", u"%d juillet", u"%d aot", u"%d septembre", u"%d octobre", u"%d novembre", u"%d dcembre" ])
addFmt2('fur',False, u"%%d di %s", True )
addFmt2('fy', False, u"%%d %s", False )
addFmt ('ga', False,       [ u"%d Eanir", u"%d Feabhra", u"%d Mrta", u"%d Aibren", u"%d Bealtaine", u"%d Meitheamh", u"%d Iil", u"%d Lnasa", u"%d Men Fmhair", u"%d Deireadh Fmhair", u"%d Samhain", u"%d M na Nollag" ])
addFmt2('gl', False, u"%%d de %s", False )
addFmt2('he', False, u"%%d %s" )      # [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt ('hr', False,       [ u"%d. sijenja", u"%d. veljae", u"%d. oujka", u"%d. travnja", u"%d. svibnja", u"%d. lipnja", u"%d. srpnja", u"%d. kolovoza", u"%d. rujna", u"%d. listopada", u"%d. studenog", u"%d. prosinca" ])
addFmt2('hu', False, u"%s %%d", True )
addFmt2('ia', False, u"%%d de %s", False )
addFmt2('id', False, u"%%d %s", True )
addFmt2('ie', False, u"%%d %s", False )
addFmt2('io', False, u"%%d di %s", False )
addFmt ('is', False,       [ u"%d. janar", u"%d. febrar", u"%d. mars", u"%d. aprl", u"%d. ma", u"%d. jn", u"%d. jl", u"%d. gst", u"%d. september", u"%d. oktber", u"%d. nvember", u"%d. desember" ])
addFmt2('it', False, u"%%d %s", False )
addFmt ('ja', False,       makeMonthList( u"%d%%d" ))
addFmt2('jv', False, u"%%d %s", True )
addFmt2('ka', False, u"%%d %s" )
addFmt ('ko', False,       makeMonthList( u"%d %%d" ))
addFmt ('ku', False,       [ u"%d' rbendan", u"%d' reemiy", u"%d' adar", u"%d' avrl", u"%d' gulan", u"%d' pper", u"%d' trmeh", u"%d' gelawj", u"%d' rezber", u"%d' kewr", u"%d' sermawez", u"%d' berfanbar" ])
addFmt ('la', False,       [ u"%d Ianuarii", u"%d Februarii", u"%d Martii", u"%d Aprilis", u"%d Maii", u"%d Iunii", u"%d Iulii", u"%d Augusti", u"%d Septembris", u"%d Octobris", u"%d Novembris", u"%d Decembris" ])
addFmt2('lb', False, u"%%d. %s", True )
addFmt ('li', False,       [ u"%d januari", u"%d februari", u"%d miert", u"%d april", u"%d mei", u"%d juni", u"%d juli", u"%d augustus", u"%d september", u"%d oktober", u"%d november", u"%d december" ])
addFmt ('lt', False,       [ u"Sausio %d", u"Vasario %d", u"Kovo %d", u"Balandio %d", u"Gegus %d", u"Birelio %d", u"Liepos %d", u"Rugpjio %d", u"Rugsjo %d", u"Spalio %d", u"Lapkriio %d", u"Gruodio %d" ])
addFmt2('lv', False, u"%%d. %s", False )
addFmt2('mhr',False, u"%%d %s", False )
addFmt ('mk', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('ml', False, u"%s %%d" )
addFmt2('ms', False, u"%%d %s", True )
addFmt2('nap',False, u"%%d 'e %s", False )
addFmt2('nds',False, u"%%d. %s", True )
addFmt ('nl', False,       [ u"%%d %s" % v for v in [ u"januari", u"februari", u"maart", u"april", u"mei", u"juni", u"juli", u"augustus", u"september", u"oktober", u"november", u"december" ]])
addFmt ('nn', False,       [ u"%%d. %s" % v for v in [u"januar", u"februar", u"mars", u"april", u"mai", u"juni", u"juli", u"august", u"september", u"oktober", u"november", u"desember"]])
addFmt2('no', False, u"%%d. %s", False )
addFmt ('oc', False,       [ u"%d de genir", u"%d de febrir", u"%d de mar", u"%d d'abril", u"%d de mai", u"%d de junh", u"%d de julhet", u"%d d'agost", u"%d de setembre", u"%d d'octobre", u"%d de novembre", u"%d de decembre" ])
addFmt ('os', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", None, u"%d ", None, u"%d ", None, u"%d ", u"%d " ])
addFmt ('pl', False,       [ u"%d stycznia", u"%d lutego", u"%d marca", u"%d kwietnia", u"%d maja", u"%d czerwca", u"%d lipca", u"%d sierpnia", u"%d wrzenia", u"%d padziernika", u"%d listopada", u"%d grudnia" ])
addFmt2('pt', False, u"%%d de %s", True )
addFmt2('ro', False, u"%%d %s", False )
addFmt ('ru', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('sco',False, u"%%d %s", True )
addFmt2('scn',False, u"%%d di %s", False )
addFmt ('se', False,       [ u"oajagimnu %d.", u"guovvamnu %d.", u"njukamnu %d.", u"cuoomnu %d.", u"miessemnu %d.", u"geassemnu %d.", u"suoidnemnu %d.", u"borgemnu %d.", u"akamnu %d.", u"golggotmnu %d.", u"skbmamnu %d.", u"juovlamnu %d." ])
addFmt ('sh', False,       makeMonthList( u"%%d.%d." ))
addFmt2('simple', False, u"%s %%d", True )
addFmt2('sk', False, u"%%d. %s", False )
addFmt2('sl', False, u"%%d. %s", False )
addFmt ('sq', False,       [ u"%d Janar", u"%d Shkurt", u"%d Mars", u"%d Prill", u"%d Maj", u"%d Qershor", u"%d Korrik", u"%d Gusht", u"%d Shtator", u"%d Tetor", u"%d Nntor", u"%d Dhjetor" ])
addFmt2('sr', False, u"%%d. %s", False )
addFmt2('su', False, u"%%d %s", True )
addFmt2('sv', False, u"%%d %s", False )
addFmt2('ta', False, u"%s %%d" )
addFmt2('te', False, u"%s %%d" )
addFmt2('th', False, u"%%d %s" )    # %%T
addFmt2('tl', False, u"%s %%d" )
addFmt2('tr', False, u"%%d %s", True )
addFmt2('tt', False, u"%%d. %s", True )
addFmt ('uk', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt ('ur', False,       [ u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d ", u"%d " ])
addFmt2('vec',False, u"%%d de %s", False )
addFmt ('vi', False,       makeMonthList( u"%%d thng %d" ))
addFmt2('vo', False, u"%s %%d", False )
addFmt ('zh', False,       makeMonthList( u"%d%%d" ))

# Walloon names depend on the day number, thus we must generate various different patterns
waMonthNames = [ u"djanv", u"fevr", u"mss", u"avri", u"may", u"djun", u"djulete", u"awousse", u"setimbe", u"octbe", u"nvimbe", u"decimbe" ]

# For month names begining with a consonant...
for i in [0,1,2,4,5,6,8,10,11]:
    formats[dayMnthFmts[i]]['wa'] = eval(
        (u'lambda m: multi( m, [' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d d\' %s" ), lambda p: p == 1),' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d d\' %s" ),  lambda p: p in [2,3,20,22,23]),' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d di %s" ),   alwaysTrue)])') % (waMonthNames[i], waMonthNames[i], waMonthNames[i]))
# For month names begining with a vowel...
for i in [3,7,9]:
    formats[dayMnthFmts[i]]['wa'] = eval(
        (u'lambda m: multi( m, [' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d d\' %s" ), lambda p: p == 1),' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d d\' %s" ),  alwaysTrue)])') % (waMonthNames[i], waMonthNames[i]))

# Brazil uses "1a" for the 1st of every month, and number without suffix for all other days
brMonthNames = makeMonthNamedList( 'br', u"%s", True )
for i in range(0,12):
    formats[dayMnthFmts[i]]['br'] = eval(
        (u'lambda m: multi( m, [' +
            u'(lambda v: dh_dayOfMnth( v, u"%%da %s" ), lambda p: p == 1),' +
            u'(lambda v: dh_dayOfMnth( v, u"%%d %s" ),   alwaysTrue)])') % (brMonthNames[i], brMonthNames[i]))


#
# Month of the Year: "en:May 1976"
#
addFmt2('af', True, u"%s %%d", True )
addFmt2('ar', True, u"%s %%d" )
addFmt2('ang',True, u"%s %%d", True )
addFmt2('cs', True, u"%s %%d" )
addFmt2('de', True, u"%s %%d", True )
addFmt ('el', True,     [ u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d", u" %d" ])
addFmt2('en', True, u"%s %%d", True )
addFmt2('eo', True, u"%s de %%d" )
addFmt2('es', True, u"%s de %%d", True )
addFmt2('et', True, u"%s %%d", True )
addFmt2('fi', True, u"%s %%d", True )
addFmt ('fr', True,     [ u"Janvier %d", u"Fvrier %d", u"Mars %d", u"Avril %d", u"Mai %d", u"Juin %d", u"Juillet %d", u"Aot %d", u"Septembre %d", u"Octobre %d", u"Novembre %d", u"Dcembre %d" ])
addFmt2('he', True, u"%s %%d", True )
addFmt2('it', True, u"Attualit/Anno %%d - %s", True )
addFmt ('ja', True,     [ u"%%d%d" % mm for mm in range(1,13)])
addFmt2('ka', True, u"%s, %%d" )
addFmt ('ko', True,     [ u"%d 1", u"%d 2", u"%d 3", u"%d 4", u"%d 5", u"%d 6", u"%d 7", u"%d 8", u"%d 9", u"%d 10", u"%d 11", u"%d 12" ])
addFmt ('li', True,     [ u"januari %d", u"februari %d", u"miert %d", u"april %d", u"mei %d", u"juni %d", u"juli %d", u"augustus %d", u"september %d", u"oktober %d", u"november %d", u"december %d" ])
addFmt ('nl', True,     [ u"Januari %d", u"Februari %d", u"Maart %d", u"April %d", u"Mei %d", u"Juni %d", u"Juli %d", u"Augustus %d", u"September %d", u"Oktober %d", u"November %d", u"December %d" ])
addFmt2('pl', True, u"%s %%d", True )
addFmt ('scn',True,     [ None, None, u"Marzu %d", None, None, None, None, None, None, None, None, None ])
addFmt2('simple', True, u"%s %%d", True )
addFmt2('sk', True, u"%s %%d" )
addFmt2('sv', True, u"%s %%d", True )
addFmt2('th', True, u"%s .. %%T" )
addFmt2('tl', True, u"%s %%d" )
addFmt2('tt', True, u"%s, %%d", True )
addFmt ('ur', True,     [ u"%d01", u"%d02", u"%d03", u"%d04", u"%d05", u"%d06", u"%d07", u"%d08", u"%d09", u"%d10", u"%d11", u"%d12" ])
addFmt2('uk', True, u"%s %%d", True )
addFmt ('vi', True,     makeMonthList( u"Thng %d nm %%d" ))
addFmt ('zh', True,     makeMonthList( u"%%d%d" ))
addFmt ('zh-min-nan',True,  makeMonthList( u"%%d n %d goeh" ))


#
#
# This table defines the limits for each type of format data.
# Each item is a tuple with a predicate function (returns True if the value falls within acceptable limits, False otherwise),
# In addition, tuple contains start, end, and step values that will be used to test the formats table for internal consistency.
#
formatLimits = {
    'MonthName'         : (lambda v: 1 <=v and v < 13,                 1, 13),
    'Number'            : (lambda v: 0 <=v and v < 1000000,            0, 1001),

    'YearAD'            : (lambda v: 0 <=v and v < 2501,               0, 2501),
    'YearBC'            : (lambda v: 0 <=v and v < 4001,               0, 501),   # zh: has years as old as 1700
    'DecadeAD'          : (lambda v: 0 <=v and v < 2501,               0, 2501),  # At some point need to re-add  "and v%10==0" to the limitation
    'DecadeBC'          : (lambda v: 0 <=v and v < 4001,               0, 501),   # zh: has decades as old as 1700
    'CenturyAD'         : (lambda v: 1 <=v and v < 41,                 1, 23),    # Some centuries use Roman numerals or a given list - do not exceed them in testing
    'CenturyBC'         : (lambda v: 1 <=v and v < 91,                 1, 23),    # Some centuries use Roman numerals or a given list - do not exceed them in testing
    'MillenniumAD'      : (lambda v: 1 <=v and v < 6,                  1, 4),     # For milleniums, only test first 3 AD Milleniums,
    'MillenniumBC'      : (lambda v: 1 <=v and v < 20,                 1, 2),     # And only 1 BC Millenium
    'CenturyAD_Cat'     : (lambda v: 1 <=v and v < 41,                 1, 23),    # Some centuries use Roman numerals or a given list - do not exceed them in testing
    'CenturyBC_Cat'     : (lambda v: 1 <=v and v < 41,                 1, 23),    # Some centuries use Roman numerals or a given list - do not exceed them in testing
    'Cat_Year_MusicAlbums'  : (lambda v: 1950 <= v and v < 2021,        1950, 2021),
    'CurrEvents'            : (lambda v: 0 <= v and v < 1,              0, 1),
}

# All month of year articles are in the same format
_formatLimit_MonthOfYear =  (lambda v: 1 <= 1900 and v < 2051,      1900, 2051)
for month in yrMnthFmts:
    formatLimits[month] = _formatLimit_MonthOfYear

_formatLimit_DayOfMonth31 = (lambda v: 1 <= v and v < 32,           1, 32)
_formatLimit_DayOfMonth30 = (lambda v: 1 <= v and v < 31,           1, 31)
_formatLimit_DayOfMonth29 = (lambda v: 1 <= v and v < 30,           1, 30)
for monthId in range(12):
    if (monthId + 1) in [1, 3, 5, 7, 8, 10, 12]:
        formatLimits[dayMnthFmts[monthId]] = _formatLimit_DayOfMonth31      # 31 days a month
    elif (monthId+1) == 2: # February
        formatLimits[dayMnthFmts[monthId]] = _formatLimit_DayOfMonth29      # 29 days a month
    else:
        formatLimits[dayMnthFmts[monthId]] = _formatLimit_DayOfMonth30      # 30 days a month

def getNumberOfDaysInMonth(month):
    """Returns the number of days in a given month, 1 being January, etc."""
    return formatLimits[dayMnthFmts[month-1]][2]-1


def getAutoFormat( lang, title, ignoreFirstLetterCase = True ):
    """Returns (dictName,value), where value can be a year, date, etc, and dictName is 'YearBC', 'December', etc."""
    for dictName, dict in formats.iteritems():
        try:
            year = dict[ lang ]( title )
            return (dictName,year)
        except:
            pass

    # sometimes the title may begin with an upper case while its listed as lower case, or the other way around
    # change case of the first character to the opposite, and try again
    if ignoreFirstLetterCase:
        try:
            if title[0].isupper():
                title = title[0].lower() + title[1:]
            else:
                title = title[0].upper() + title[1:]

            return getAutoFormat(lang, title, ignoreFirstLetterCase = False)
        except:
            pass

    return (None,None)

class FormatDate(object):
    def __init__(self, site):
        self.site = site

    def __call__(self, m, d):
        return formats['Day_' + enMonthNames[m-1]][self.site.lang](d)


def formatYear(lang, year):
    if year < 0:
        return formats['YearBC'][lang](-year)
    else:
        return formats['YearAD'][lang](year)

#
#
#  Map testing methods
#
#

def printMonthArray( lang, pattern, capitalize ):
    """
    """
    for s in makeMonthNamedList( lang, pattern, capitalize ):
        wikipedia.output( s )


def testMapEntry( formatName, showAll = True, value = None ):
    """This is a test function, to be used interactivelly to test the validity of the above maps.
    To test, run this function with the map name, value to be tested, and the final value expected.
    Usage example:
        run python interpreter
        >>> import date
        >>> date.testMapEntry( 'DecadeAD', 1992, 1990 )
        >>> date.testMapEntry( 'CenturyAD', 20, 20 )
    """

    step = 1
    if formatName in decadeFormats: step = 10
    predicate,start,stop = formatLimits[formatName]
    if value is not None:
        start, stop = value, value+1
    if showAll:
        wikipedia.output(u"Processing %s with limits from %d to %d and step %d" % (formatName, start,stop-1,step))

    for code, convFunc in formats[formatName].iteritems():
#        import time
#        startClock = time.clock()
        for value in range(start, stop, step):
            try:
                if not predicate(value):
                    raise AssertionError("     Not a valid value for this format.")
                newValue = convFunc(convFunc(value))
                if newValue != value:
                    raise AssertionError("     %s != %s: assert failed, values didn't match" % (newValue, value))
                if showAll:
                    wikipedia.output(u"date.formats['%s']['%s'](%d): '%s' -> %d" % (formatName, code, value, convFunc(value), newValue))
            except:
                wikipedia.output(u"********** Error in date.formats['%s']['%s'](%d)" % (formatName, code, value))
                raise
#        wikipedia.output( u"%s\t%s\t%f" % (formatName, code, time.clock() - startClock) )

def test(quick = False, showAll = False):
    """This is a test function, to be used interactively to test entire
    format conversion map at once

    Usage example:
        run python interpreter
        >>> import date
        >>> date.test()

    """
    for formatName in formats.keys():

        if quick:
            testMapEntry( formatName, showAll, formatLimits[formatName][1] )     # Only test the first value in the test range
        else:
            testMapEntry( formatName, showAll )     # Extensive test!        # Test decade rounding
            wikipedia.output(u"'%s' complete." % formatName)

    if quick:
        #wikipedia.output(u'Date module quick consistency test passed')
        pass
    else:
        wikipedia.output(u'Date module has been fully tested')


#
#
# Do a quick test upon module loading!
# Make sure the date file is correct
#
#
test(quick=True)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.