public
Description: An addition to django that allows better presentation of date strings in a local way.
Homepage: http://code.google.com/p/django-localdates/
Clone URL: git://github.com/orestis/django-localdates.git
Click here to lend your support to: django-localdates and make a donation at www.pledgie.com !
django-localdates / localdates / local_dateformat.py
100644 159 lines (118 sloc) 5.013 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
from django.utils.dateformat import TimeFormat, DateFormat
from django.utils.translation import ugettext as _
import re
 
local_re = re.compile(r'(\{\w{2}\})')
 
#to trigger translation
dummy_formats = (
    _('FULL_DATE'),
    _('ABBR_DATE'),
    _('ABBR2_DATE'),
    _('NUM_DATE'),
   
    _('FULL_DATETIME'),
    _('ABBR_DATETIME'),
    _('ABBR2_DATETIME'),
    _('NUM_DATETIME'),
    
    _('FULL_TIME'),
    
    _('FULL_YEARMONTH'),
    _('ABBR_YEARMONTH'),
    _('NUM_YEARMONTH'),
    
    _('FULL_MONTHDAY'),
    _('ABBR_MONTHDAY'),
    _('NUM_MONTHDAY'),
    )
 
# default to english
default_format_strings = {
    'FULL_DATE':'l, N j, Y',
    'ABBR_DATE':'F j, Y',
    'ABBR2_DATE':'M j, Y',
    'NUM_DATE':'n/j/Y',
 
    'FULL_DATETIME':'l, N j, Y, P',
    'ABBR_DATETIME':'F j, Y, P',
    'ABBR2_DATETIME':'M j, Y, P',
    'NUM_DATETIME':'n/j/Y, P',
    
    'FULL_TIME':'P',
    
    'FULL_YEARMONTH':'F Y',
    'ABBR_YEARMONTH':'M Y',
    'NUM_YEARMONTH':'n/Y',
    
    'FULL_MONTHDAY':'F j',
    'ABBR_MONTHDAY':'M j',
    'NUM_MONTHDAY':'n/j',
 
}
 
 
# this is after the django.utils.translation.trans_real.get_date_formats
# TODO take into consideration the settings date formats
def get_local_formats():
    from django.conf import settings
    formats = {}
    
    for format in default_format_strings:
        result = _(format)
        if result == format:
            result = default_format_strings[format]
        formats[format]=result
    
    return formats
 
 
#this constructs the regexp string like this: r"(\{FULL_DATE\}|\{ABBR_DATE\}|...)"
local_standard_string = r'('+(r'|'.join([r'\{%s\}'%key for key in get_local_formats()]))+r')'
 
local_standard_re = re.compile(local_standard_string)
 
local_trans_re = re.compile(r'(\{_\(.+?\)\})')
 
class LocalFormatter(object):
    def format(self, formatstr):
        # replace the translated strings
        trans_pieces = local_trans_re.findall(formatstr)
        for piece in trans_pieces:
            result = _(piece[3:-2])
            if result == piece[3:-2]:
                result = u''.join([u"\\%s" % c for c in result])
                
            formatstr = formatstr.replace(piece, result)
 
        # replace the standard strings with their expanded versions
        standard_pieces = local_standard_re.findall(formatstr)
        for piece in standard_pieces:
            formatstr = formatstr.replace(piece, get_local_formats()[piece[1:-1]])
        
        # put the local values in the format str
        local_pieces = local_re.findall(formatstr)
        for piece in local_pieces:
            try:
                result = unicode(getattr(self, piece[1:-1])())
                result = u''.join([u"\\%s" % c for c in result])
                formatstr = formatstr.replace(piece, result)
            except AttributeError:
                # the current local date format doesn't handle this format
                # we don't do anything
                pass
                          
        # use the standard behavior for the rest
        return self._format(self, formatstr)
 
from local_dates import MONTHS_POS, MONTHS_DIR
class DefaultLocalDateFormat(LocalFormatter, DateFormat):
    def __init__(self, *args, **kwargs):
        self._format = DateFormat.format
        super(DefaultLocalDateFormat, self).__init__(*args, **kwargs)
 
    
    def Fp(self):
        return MONTHS_POS[self.data.month]
 
    def Fd(self):
        return MONTHS_DIR[self.data.month]
    
class DefaultLocalTimeFormat(LocalFormatter, TimeFormat):
    def __init__(self, *args, **kwargs):
        self._format = TimeFormat.format
        super(DefaultLocalTimeFormat, self).__init__(*args, **kwargs)
    
def _format(value, format_string, locale, format_type='Date'):
    "Convenience function"
    if locale == None:
        df = DateFormat(value)
    else:
        # try to import the dateformat from the localflavor
        
        try:
            localflavor_module = __import__('django.contrib.localflavor.%s.dateformat'%locale[:2], {}, {}, [''])
            #print localflavor_module
            df_class = getattr(localflavor_module, 'Local%sFormat'%format_type)
            #print df_class
            df = df_class(value)
            
        except (ImportError, AttributeError), e:
            #print 'could not import localflavor module', e
            #use DefaultLocalDateFormat or DefaultLocalTimeFormat
            if format_type=='Date':
                df = DefaultLocalDateFormat(value)
            elif format_type=='Time':
                df = DefaultLocalTimeFormat(value)
        
 
        
    return df.format(format_string)
 
def format(value, format_string, locale=None):
    return _format(value, format_string, locale, 'Date')
 
def time_format(value, format_string, locale=None):
    return _format(value, format_string, locale, 'Time')