Ok. I require a "very forgiving" data entry
of dates that does the very best it can without
throwing an error.  It is much easier, especially 
over the web to "fix-up" the data best as one
can on behalf of the user rather than being
strict about propigating errors... 

Anyway, the code below takes any old string
and tries to figure out the best date it 
possibly can (returning something palatable
by MySQL or Oracle).  It of course, passes
on a blank date as a None, which is translated
later in my code to NULL.  But every other
type of entry results in a date... may not be
what the user wanted, but they can fix it
if it is wrong.

I'm contributing this code to WebKit, preferrably
to be placed in WebUtils.Funcs (where they are
located on my site... for now).  It would please
me if you would all consider accepting this addition,
otherwise I'll find another "local" home for it.

Kind Regards,

Clark C. Evans

....

### Forgiving Date Handling
###   Contributed by Clark C. Evans, (c) 2001, Xgenda, Inc.  
###   Redistribution and use in source and binary
###   forms, with or without modification, are 
###   permitted without restriction.

s2d = { 'jan':1, 'feb':2, 'mar':3, 'apr':4,  'may':5, 'jun':6,
        'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12,
        'january':1, 'febuary':2, 'march':3, 'april':4, 'june':6,
        'july':7, 'august':8, 'september':9, 'october':10,
        'november':11, 'december':12 }
ldm = {1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
d2s = { 1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun',
        7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec' }

styleMySQL  = '%Y-%m-%d'
styleOracle = '%d-%b-%Y'

def dateString(val,style = styleMySQL):
    if not(val): return None
    val = dateTuple(val)
    if styleMySQL == style:
        return str(val[0]) + "-" + str(val[1]) + "-" + str(val[2])
    if styleOracle == style:
        return str(val[2]) + "-" + str(d2s[val[1]]) + "-" +
    str(val[0])
    raise Exception("Unknown Style")

def dateTuple(val):
    if not(val): return None
    def toNumber(val):
        try:
            return string.atoi(val)
        except:
            return None
    try:
        dy = None
        yr = None
        mo = None
        # regular expressions would be good here...
        val = string.replace(string.lower(val),'/',' ')
        val = string.replace(val,'-',' ')
        val = string.replace(val,',',' ')
        val = string.replace(val,'*',' ')
        val = string.split(val)
        if 3== len(val):
            a = toNumber(val[0])
            b = toNumber(val[1])
            c = toNumber(val[2])
            if a > 31:
                yr = a
                if b:  # 1999 6 23
                    mo = b
                    dy = c
                else:  # 1999 Jun 23
                    mo = s2d[val[1]]
                    dy = c
            elif a > 0:
                yr = c
                dy = a
                if b: # 23 6 1999
                    mo = b
                else: # 23 Jun 1999
                    mo = s2d[val[1]]
            else: # Jun 23, 2000
                dy = b
                yr = c
                mo = s2d[val[0]]
        elif 2 == len(val):
            a = toNumber(val[0])
            b = toNumber(val[1])
            if a > 31:
                yr = a
                dy = 1
                if b > 0: # 1999 6
                    mo = b
                else: # 1999 Jun
                    mo = s2d[val[1]]
            elif a > 0:
                if b > 31: # 6 1999
                    mo = a
                    yr = b
                    dy = 1
                elif b > 0: # 6 23
                    mo = a
                    dy = b
                else: # 23 Jun
                    dy = a
                    mo = s2d[val[1]]
            else:
                if b > 31: # Jun 2001
                    yr = b
                    dy = 1
                else:  # Jun 23
                    dy = b
                mo = s2d[val[0]]
        elif 1 == len(val):
            a = toNumber(val[0])
            if a > 31:
                dy = 1
                mo = 1
                yr = a
            elif a > 0:
                dy = a
            else:
                mo = s2d[val[0]]
                dy = 1
    finally:
        tm = time.localtime()
        if not(yr): yr = tm[0]
        if not(mo): mo = tm[1]
        if not(dy): dy = tm[2]
        if yr < 76: yr = yr + 2000
        if yr < 100: yr = yr + 1900
        if mo > 12 or mo < 1: mo = 1
        if dy < 1: dy = 1
        if dy > ldm[mo]:
            if 2 == mo:
                if not(yr%400) or ( not(yr%4) and yr%100 ): dy = 29
                else: dy = 28
            else: dy = ldm[mo]
        return (yr,mo,dy,0, 0, 0, 0, 0, 0)

_______________________________________________
Webware-discuss mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/webware-discuss

Reply via email to