annotate babel/dates.py @ 215:d37628e752c4

Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
author cmlenz
date Fri, 13 Jul 2007 22:22:03 +0000
parents 90bf48c74714
children 1f3c3924b1b5
rev   line source
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
2 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2007 Edgewall Software
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
4 # All rights reserved.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
5 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
9 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
13
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
14 """Locale dependent formatting and parsing of dates and times.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
15
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
16 The default locale for the functions in this module is determined by the
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
17 following environment variables, in that order:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
18
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
19 * ``LC_TIME``,
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
20 * ``LC_ALL``, and
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
21 * ``LANG``
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
22 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
23
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
24 from datetime import date, datetime, time, timedelta, tzinfo
38
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
25 import re
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
26
72
4dcdb1d367ec More explicit module-level function names in `babel.core`. Added `Locale.negotiate` class method.
cmlenz
parents: 46
diff changeset
27 from babel.core import default_locale, Locale
39
3b314a78015d Move function for determining the system default locale to `babel.core`, and make it available as a class method on `Locale`.
cmlenz
parents: 38
diff changeset
28 from babel.util import UTC
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
29
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
30 __all__ = ['format_date', 'format_datetime', 'format_time', 'parse_date',
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
31 'parse_datetime', 'parse_time']
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
32 __docformat__ = 'restructuredtext en'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
33
72
4dcdb1d367ec More explicit module-level function names in `babel.core`. Added `Locale.negotiate` class method.
cmlenz
parents: 46
diff changeset
34 LC_TIME = default_locale('LC_TIME')
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
35
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
36 # Aliases for use in scopes where the modules are shadowed by local variables
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
37 date_ = date
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
38 datetime_ = datetime
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
39 time_ = time
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
40
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
41 def get_period_names(locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
42 """Return the names for day periods (AM/PM) used by the locale.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
43
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
44 >>> get_period_names(locale='en_US')['am']
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
45 u'AM'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
46
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
47 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
48 :return: the dictionary of period names
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
49 :rtype: `dict`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
50 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
51 return Locale.parse(locale).periods
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
52
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
53 def get_day_names(width='wide', context='format', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
54 """Return the day names used by the locale for the specified format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
55
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
56 >>> get_day_names('wide', locale='en_US')[1]
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
57 u'Tuesday'
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
58 >>> get_day_names('abbreviated', locale='es')[1]
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
59 u'mar'
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
60 >>> get_day_names('narrow', context='stand-alone', locale='de_DE')[1]
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
61 u'D'
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
62
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
63 :param width: the width to use, one of "wide", "abbreviated", or "narrow"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
64 :param context: the context, either "format" or "stand-alone"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
65 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
66 :return: the dictionary of day names
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
67 :rtype: `dict`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
68 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
69 return Locale.parse(locale).days[context][width]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
70
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
71 def get_month_names(width='wide', context='format', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
72 """Return the month names used by the locale for the specified format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
73
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
74 >>> get_month_names('wide', locale='en_US')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
75 u'January'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
76 >>> get_month_names('abbreviated', locale='es')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
77 u'ene'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
78 >>> get_month_names('narrow', context='stand-alone', locale='de_DE')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
79 u'J'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
80
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
81 :param width: the width to use, one of "wide", "abbreviated", or "narrow"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
82 :param context: the context, either "format" or "stand-alone"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
83 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
84 :return: the dictionary of month names
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
85 :rtype: `dict`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
86 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
87 return Locale.parse(locale).months[context][width]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
88
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
89 def get_quarter_names(width='wide', context='format', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
90 """Return the quarter names used by the locale for the specified format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
91
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
92 >>> get_quarter_names('wide', locale='en_US')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
93 u'1st quarter'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
94 >>> get_quarter_names('abbreviated', locale='de_DE')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
95 u'Q1'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
96
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
97 :param width: the width to use, one of "wide", "abbreviated", or "narrow"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
98 :param context: the context, either "format" or "stand-alone"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
99 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
100 :return: the dictionary of quarter names
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
101 :rtype: `dict`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
102 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
103 return Locale.parse(locale).quarters[context][width]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
104
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
105 def get_era_names(width='wide', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
106 """Return the era names used by the locale for the specified format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
107
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
108 >>> get_era_names('wide', locale='en_US')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
109 u'Anno Domini'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
110 >>> get_era_names('abbreviated', locale='de_DE')[1]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
111 u'n. Chr.'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
112
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
113 :param width: the width to use, either "wide" or "abbreviated"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
114 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
115 :return: the dictionary of era names
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
116 :rtype: `dict`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
117 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
118 return Locale.parse(locale).eras[width]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
119
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
120 def get_date_format(format='medium', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
121 """Return the date formatting patterns used by the locale for the specified
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
122 format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
123
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
124 >>> get_date_format(locale='en_US')
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
125 <DateTimePattern u'MMM d, yyyy'>
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
126 >>> get_date_format('full', locale='de_DE')
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
127 <DateTimePattern u'EEEE, d. MMMM yyyy'>
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
128
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
129 :param format: the format to use, one of "full", "long", "medium", or
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
130 "short"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
131 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
132 :return: the date format pattern
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
133 :rtype: `DateTimePattern`
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
134 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
135 return Locale.parse(locale).date_formats[format]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
136
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
137 def get_datetime_format(format='medium', locale=LC_TIME):
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
138 """Return the datetime formatting patterns used by the locale for the
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
139 specified format.
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
140
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
141 >>> get_datetime_format(locale='en_US')
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
142 u'{1} {0}'
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
143
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
144 :param format: the format to use, one of "full", "long", "medium", or
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
145 "short"
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
146 :param locale: the `Locale` object, or a locale string
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
147 :return: the datetime format pattern
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
148 :rtype: `unicode`
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
149 """
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
150 patterns = Locale.parse(locale).datetime_formats
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
151 if format not in patterns:
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
152 format = None
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
153 return patterns[format]
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
154
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
155 def get_time_format(format='medium', locale=LC_TIME):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
156 """Return the time formatting patterns used by the locale for the specified
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
157 format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
158
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
159 >>> get_time_format(locale='en_US')
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
160 <DateTimePattern u'h:mm:ss a'>
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
161 >>> get_time_format('full', locale='de_DE')
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
162 <DateTimePattern u"H:mm' Uhr 'z">
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
163
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
164 :param format: the format to use, one of "full", "long", "medium", or
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
165 "short"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
166 :param locale: the `Locale` object, or a locale string
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
167 :return: the time format pattern
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
168 :rtype: `DateTimePattern`
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
169 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
170 return Locale.parse(locale).time_formats[format]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
171
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
172 def format_date(date=None, format='medium', locale=LC_TIME):
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
173 """Return a date formatted according to the given pattern.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
174
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
175 >>> d = date(2007, 04, 01)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
176 >>> format_date(d, locale='en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
177 u'Apr 1, 2007'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
178 >>> format_date(d, format='full', locale='de_DE')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
179 u'Sonntag, 1. April 2007'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
180
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
181 If you don't want to use the locale default formats, you can specify a
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
182 custom date pattern:
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
183
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
184 >>> format_date(d, "EEE, MMM d, ''yy", locale='en')
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
185 u"Sun, Apr 1, '07"
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
186
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
187 :param date: the ``date`` or ``datetime`` object; if `None`, the current
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
188 date is used
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
189 :param format: one of "full", "long", "medium", or "short", or a custom
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
190 date/time pattern
19
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
191 :param locale: a `Locale` object or a locale identifier
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
192 :rtype: `unicode`
19
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
193
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
194 :note: If the pattern contains time fields, an `AttributeError` will be
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
195 raised when trying to apply the formatting. This is also true if
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
196 the value of ``date`` parameter is actually a ``datetime`` object,
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
197 as this function automatically converts that to a ``date``.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
198 """
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
199 if date is None:
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
200 date = date_.today()
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
201 elif isinstance(date, datetime):
18
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
202 date = date.date()
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
203
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
204 locale = Locale.parse(locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
205 if format in ('full', 'long', 'medium', 'short'):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
206 format = get_date_format(format, locale=locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
207 pattern = parse_pattern(format)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
208 return parse_pattern(format).apply(date, locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
209
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
210 def format_datetime(datetime=None, format='medium', tzinfo=None,
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
211 locale=LC_TIME):
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
212 """Return a date formatted according to the given pattern.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
213
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
214 >>> dt = datetime(2007, 04, 01, 15, 30)
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
215 >>> format_datetime(dt, locale='en_US')
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
216 u'Apr 1, 2007 3:30:00 PM'
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
217
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
218 For any pattern requiring the display of the time-zone, the third-party
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
219 ``pytz`` package is needed to explicitly specify the time-zone:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
220
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
221 >>> from pytz import timezone
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
222 >>> format_datetime(dt, 'full', tzinfo=timezone('Europe/Berlin'),
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
223 ... locale='de_DE')
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
224 u'Sonntag, 1. April 2007 17:30 Uhr MESZ'
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
225 >>> format_datetime(dt, "yyyy.MM.dd G 'at' HH:mm:ss zzz",
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
226 ... tzinfo=timezone('US/Eastern'), locale='en')
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
227 u'2007.04.01 AD at 11:30:00 EDT'
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
228
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
229 :param datetime: the `datetime` object; if `None`, the current date and
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
230 time is used
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
231 :param format: one of "full", "long", "medium", or "short", or a custom
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
232 date/time pattern
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
233 :param tzinfo: the timezone to apply to the time for display
19
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
234 :param locale: a `Locale` object or a locale identifier
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
235 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
236 """
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
237 if datetime is None:
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
238 datetime = datetime_.now()
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
239 elif isinstance(datetime, (int, long)):
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
240 datetime = datetime.fromtimestamp(datetime)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
241 elif isinstance(datetime, time):
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
242 datetime = datetime_.combine(date.today(), datetime)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
243 if datetime.tzinfo is None:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
244 datetime = datetime.replace(tzinfo=UTC)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
245 if tzinfo is not None:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
246 datetime = datetime.astimezone(tzinfo)
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
247 if hasattr(tzinfo, 'normalize'): # pytz
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
248 datetime = tzinfo.normalize(datetime)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
249
18
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
250 locale = Locale.parse(locale)
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
251 if format in ('full', 'long', 'medium', 'short'):
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
252 return get_datetime_format(format, locale=locale) \
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
253 .replace('{0}', format_time(datetime, format, tzinfo=None,
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
254 locale=locale)) \
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
255 .replace('{1}', format_date(datetime, format, locale=locale))
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
256 else:
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
257 return parse_pattern(format).apply(datetime, locale)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
258
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
259 def format_time(time=None, format='medium', tzinfo=None, locale=LC_TIME):
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
260 """Return a time formatted according to the given pattern.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
261
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
262 >>> t = time(15, 30)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
263 >>> format_time(t, locale='en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
264 u'3:30:00 PM'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
265 >>> format_time(t, format='short', locale='de_DE')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
266 u'15:30'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
267
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
268 If you don't want to use the locale default formats, you can specify a
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
269 custom time pattern:
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
270
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
271 >>> format_time(t, "hh 'o''clock' a", locale='en')
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
272 u"03 o'clock PM"
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
273
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
274 For any pattern requiring the display of the time-zone, the third-party
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
275 ``pytz`` package is needed to explicitly specify the time-zone:
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
276
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
277 >>> from pytz import timezone
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
278 >>> t = time(15, 30)
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
279 >>> format_time(t, format='full', tzinfo=timezone('Europe/Berlin'),
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
280 ... locale='de_DE')
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
281 u'17:30 Uhr MESZ'
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
282 >>> format_time(t, "hh 'o''clock' a, zzzz", tzinfo=timezone('US/Eastern'),
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
283 ... locale='en')
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
284 u"11 o'clock AM, Eastern Daylight Time"
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
285
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
286 :param time: the ``time`` or ``datetime`` object; if `None`, the current
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
287 time is used
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
288 :param format: one of "full", "long", "medium", or "short", or a custom
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
289 date/time pattern
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
290 :param tzinfo: the time-zone to apply to the time for display
19
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
291 :param locale: a `Locale` object or a locale identifier
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
292 :rtype: `unicode`
19
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
293
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
294 :note: If the pattern contains date fields, an `AttributeError` will be
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
295 raised when trying to apply the formatting. This is also true if
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
296 the value of ``time`` parameter is actually a ``datetime`` object,
c0c92d11f1ab Moved some datetime tests from doctest to unittest, to avoid breaking docutils/epydoc doctest block detection.
cmlenz
parents: 18
diff changeset
297 as this function automatically converts that to a ``time``.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
298 """
33
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
299 if time is None:
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
300 time = datetime.now().time()
0740b6d31799 * Import datetime patterns from CLDR.
cmlenz
parents: 29
diff changeset
301 elif isinstance(time, (int, long)):
18
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
302 time = datetime.fromtimestamp(time).time()
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
303 elif isinstance(time, datetime):
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
304 time = time.timetz()
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
305 if time.tzinfo is None:
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
306 time = time.replace(tzinfo=UTC)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
307 if tzinfo is not None:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
308 dt = datetime.combine(date.today(), time).astimezone(tzinfo)
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
309 if hasattr(tzinfo, 'normalize'): # pytz
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
310 dt = tzinfo.normalize(dt)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
311 time = dt.timetz()
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
312
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
313 locale = Locale.parse(locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
314 if format in ('full', 'long', 'medium', 'short'):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
315 format = get_time_format(format, locale=locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
316 return parse_pattern(format).apply(time, locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
317
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
318 def parse_date(string, locale=LC_TIME):
38
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
319 """Parse a date from a string.
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
320
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
321 This function uses the date format for the locale as a hint to determine
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
322 the order in which the date fields appear in the string.
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
323
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
324 >>> parse_date('4/1/04', locale='en_US')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
325 datetime.date(2004, 4, 1)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
326 >>> parse_date('01.04.2004', locale='de_DE')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
327 datetime.date(2004, 4, 1)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
328
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
329 :param string: the string containing the date
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
330 :param locale: a `Locale` object or a locale identifier
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
331 :return: the parsed date
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
332 :rtype: `date`
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
333 """
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
334 # TODO: try ISO format first?
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
335 format = get_date_format(locale=locale).pattern.lower()
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
336 year_idx = format.index('y')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
337 month_idx = format.index('m')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
338 if month_idx < 0:
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
339 month_idx = format.index('l')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
340 day_idx = format.index('d')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
341
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
342 indexes = [(year_idx, 'Y'), (month_idx, 'M'), (day_idx, 'D')]
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
343 indexes.sort()
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
344 indexes = dict([(item[1], idx) for idx, item in enumerate(indexes)])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
345
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
346 # FIXME: this currently only supports numbers, but should also support month
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
347 # names, both in the requested locale, and english
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
348
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
349 numbers = re.findall('(\d+)', string)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
350 year = numbers[indexes['Y']]
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
351 if len(year) == 2:
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
352 year = 2000 + int(year)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
353 else:
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
354 year = int(year)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
355 month = int(numbers[indexes['M']])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
356 day = int(numbers[indexes['D']])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
357 if month > 12:
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
358 month, day = day, month
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
359 return date(year, month, day)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
360
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
361 def parse_datetime(string, locale=LC_TIME):
46
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
362 """Parse a date and time from a string.
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
363
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
364 This function uses the date and time formats for the locale as a hint to
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
365 determine the order in which the time fields appear in the string.
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
366
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
367 :param string: the string containing the date and time
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
368 :param locale: a `Locale` object or a locale identifier
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
369 :return: the parsed date/time
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
370 :rtype: `datetime`
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
371 """
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
372 raise NotImplementedError
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
373
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
374 def parse_time(string, locale=LC_TIME):
46
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
375 """Parse a time from a string.
38
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
376
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
377 This function uses the time format for the locale as a hint to determine
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
378 the order in which the time fields appear in the string.
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
379
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
380 >>> parse_time('15:30:00', locale='en_US')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
381 datetime.time(15, 30)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
382
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
383 :param string: the string containing the time
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
384 :param locale: a `Locale` object or a locale identifier
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
385 :return: the parsed time
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
386 :rtype: `time`
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
387 """
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
388 # TODO: try ISO format first?
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
389 format = get_time_format(locale=locale).pattern.lower()
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
390 hour_idx = format.index('h')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
391 if hour_idx < 0:
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
392 hour_idx = format.index('k')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
393 min_idx = format.index('m')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
394 sec_idx = format.index('s')
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
395
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
396 indexes = [(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')]
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
397 indexes.sort()
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
398 indexes = dict([(item[1], idx) for idx, item in enumerate(indexes)])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
399
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
400 # FIXME: support 12 hour clock, and 0-based hour specification
46
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
401 # and seconds should be optional, maybe minutes too
306445fbd3ea Minor docstring fixes.
cmlenz
parents: 39
diff changeset
402 # oh, and time-zones, of course
38
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
403
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
404 numbers = re.findall('(\d+)', string)
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
405 hour = int(numbers[indexes['H']])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
406 minute = int(numbers[indexes['M']])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
407 second = int(numbers[indexes['S']])
a22b7656e9ae Started implementation of datetime parsing, using a very basic approach for now.
cmlenz
parents: 34
diff changeset
408 return time(hour, minute, second)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
409
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
410
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
411 class DateTimePattern(object):
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
412
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
413 def __init__(self, pattern, format):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
414 self.pattern = pattern
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
415 self.format = format
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
416
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
417 def __repr__(self):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
418 return '<%s %r>' % (type(self).__name__, self.pattern)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
419
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
420 def __unicode__(self):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
421 return self.pattern
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
422
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
423 def __mod__(self, other):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
424 assert type(other) is DateTimeFormat
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
425 return self.format % other
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
426
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
427 def apply(self, datetime, locale):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
428 return self % DateTimeFormat(datetime, locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
429
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
430
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
431 class DateTimeFormat(object):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
432
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
433 def __init__(self, value, locale):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
434 assert isinstance(value, (date, datetime, time))
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
435 if isinstance(value, (datetime, time)) and value.tzinfo is None:
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
436 value = value.replace(tzinfo=UTC)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
437 self.value = value
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
438 self.locale = Locale.parse(locale)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
439
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
440 def __getitem__(self, name):
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
441 char = name[0]
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
442 num = len(name)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
443 if char == 'G':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
444 return self.format_era(char, num)
215
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
445 elif char in ('y', 'Y', 'u'):
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
446 return self.format_year(char, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
447 elif char in ('Q', 'q'):
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
448 return self.format_quarter(char, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
449 elif char in ('M', 'L'):
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
450 return self.format_month(char, num)
215
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
451 elif char in ('w', 'W'):
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
452 return self.format_week(char, num)
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
453 elif char == 'd':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
454 return self.format(self.value.day, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
455 elif char in ('E', 'e', 'c'):
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
456 return self.format_weekday(char, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
457 elif char == 'a':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
458 return self.format_period(char)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
459 elif char == 'h':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
460 return self.format(self.value.hour % 12, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
461 elif char == 'H':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
462 return self.format(self.value.hour, num)
18
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
463 elif char == 'K':
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
464 return self.format(self.value.hour % 12 - 1, num)
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
465 elif char == 'k':
77a68f88f6bc Started documentation for date formatting, plus some code tweaks in that area.
cmlenz
parents: 16
diff changeset
466 return self.format(self.value.hour + 1, num)
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
467 elif char == 'm':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
468 return self.format(self.value.minute, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
469 elif char == 's':
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
470 return self.format(self.value.second, num)
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
471 elif char in ('z', 'Z', 'v'):
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
472 return self.format_timezone(char, num)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
473 else:
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
474 raise KeyError('Unsupported date/time field %r' % char)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
475
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
476 def format_era(self, char, num):
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
477 width = {3: 'abbreviated', 4: 'wide', 5: 'narrow'}[max(3, num)]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
478 era = int(self.value.year >= 0)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
479 return get_era_names(width, self.locale)[era]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
480
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
481 def format_year(self, char, num):
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
482 if char.islower():
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
483 value = self.value.year
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
484 else:
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
485 value = self.value.isocalendar()[0]
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
486 year = self.format(value, num)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
487 if num == 2:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
488 year = year[-2:]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
489 return year
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
490
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
491 def format_month(self, char, num):
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
492 if num <= 2:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
493 return ('%%0%dd' % num) % self.value.month
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
494 width = {3: 'abbreviated', 4: 'wide', 5: 'narrow'}[num]
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
495 context = {3: 'format', 4: 'format', 5: 'stand-alone'}[num]
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
496 return get_month_names(width, context, self.locale)[self.value.month]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
497
215
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
498 def format_week(self, char, num):
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
499 # FIXME: this should really be based on the first_week_day and
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
500 # min_week_days locale data
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
501 if char.islower():
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
502 return self.value.strftime('%W')
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
503 else:
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
504 return '%d' % ((self.value.day + 6 - self.value.weekday()) / 7 + 1)
d37628e752c4 Dummy/stub implementation for week-in-year and week-in-month date format fields. Also, treat extended year the same as the regular year field, not even ICU seems to handle it specially.
cmlenz
parents: 129
diff changeset
505
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
506 def format_weekday(self, char, num):
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
507 if num < 3:
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
508 if char.islower():
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
509 value = 7 - self.locale.first_week_day + self.value.weekday()
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
510 return self.format(value % 7 + 1, num)
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
511 num = 3
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
512 weekday = self.value.weekday()
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
513 width = {3: 'abbreviated', 4: 'wide', 5: 'narrow'}[num]
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
514 context = {3: 'format', 4: 'format', 5: 'stand-alone'}[num]
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
515 return get_day_names(width, context, self.locale)[weekday]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
516
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
517 def format_period(self, char):
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
518 period = {0: 'am', 1: 'pm'}[int(self.value.hour > 12)]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
519 return get_period_names(locale=self.locale)[period]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
520
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
521 def format_timezone(self, char, num):
129
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
522 if char in ('z', 'v'):
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
523 if hasattr(self.value.tzinfo, 'zone'):
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
524 zone = self.value.tzinfo.zone
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
525 else:
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
526 zone = self.value.tzinfo.tzname(self.value)
129
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
527
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
528 # Get the canonical time-zone code
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
529 zone = self.locale.zone_aliases.get(zone, zone)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
530
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
531 # Try explicitly translated zone names first
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
532 display = self.locale.time_zones.get(zone)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
533 if display:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
534 if 'long' in display:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
535 width = {3: 'short', 4: 'long'}[max(3, num)]
129
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
536 if char == 'v':
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
537 dst = 'generic'
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
538 else:
90bf48c74714 Implement wall-time time-zone display.
cmlenz
parents: 101
diff changeset
539 dst = self.value.dst() and 'daylight' or 'standard'
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
540 return display[width][dst]
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
541 elif 'city' in display:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
542 return display['city']
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
543
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
544 else:
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
545 return zone.split('/', 1)[1]
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
546
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
547 elif char == 'Z':
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
548 offset = self.value.utcoffset()
34
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
549 seconds = offset.days * 24 * 60 * 60 + offset.seconds
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
550 hours, seconds = divmod(seconds, 3600)
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
551 pattern = {3: '%+03d%02d', 4: 'GMT %+03d:%02d'}[max(3, num)]
3666f3d3df15 Extended time-zone support.
cmlenz
parents: 33
diff changeset
552 return pattern % (hours, seconds // 60)
29
da1c9610e751 More work on timezones.
cmlenz
parents: 19
diff changeset
553
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
554 def format(self, value, length):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
555 return ('%%0%dd' % length) % value
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
556
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
557
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
558 PATTERN_CHARS = {
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
559 'G': [1, 2, 3, 4, 5], # era
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
560 'y': None, 'Y': None, 'u': None, # year
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
561 'Q': [1, 2, 3, 4], 'q': [1, 2, 3, 4], # quarter
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
562 'M': [1, 2, 3, 4, 5], 'L': [1, 2, 3, 4, 5], # month
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
563 'w': [1, 2], 'W': [1], # week
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
564 'd': [1, 2], 'D': [1, 2, 3], 'F': [1], 'g': None, # day
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
565 'E': [1, 2, 3, 4, 5], 'e': [1, 2, 3, 4, 5], 'c': [1, 3, 4, 5], # week day
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
566 'a': [1], # period
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
567 'h': [1, 2], 'H': [1, 2], 'K': [1, 2], 'k': [1, 2], # hour
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
568 'm': [1, 2], # minute
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
569 's': [1, 2], 'S': None, 'A': None, # second
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
570 'z': [1, 2, 3, 4], 'Z': [1, 2, 3, 4], 'v': [1, 4] # zone
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
571 }
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
572
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
573 def parse_pattern(pattern):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
574 """Parse date, time, and datetime format patterns.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
575
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
576 >>> parse_pattern("MMMMd").format
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
577 u'%(MMMM)s%(d)s'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
578 >>> parse_pattern("MMM d, yyyy").format
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
579 u'%(MMM)s %(d)s, %(yyyy)s'
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
580
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
581 Pattern can contain literal strings in single quotes:
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
582
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
583 >>> parse_pattern("H:mm' Uhr 'z").format
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
584 u'%(H)s:%(mm)s Uhr %(z)s'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
585
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
586 An actual single quote can be used by using two adjacent single quote
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
587 characters:
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
588
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
589 >>> parse_pattern("hh' o''clock'").format
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
590 u"%(hh)s o'clock"
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
591
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
592 :param pattern: the formatting pattern to parse
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
593 """
12
a2c54ef107c2 * Removed pkg_resources/setuptools requirement from various places.
cmlenz
parents: 8
diff changeset
594 if type(pattern) is DateTimePattern:
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
595 return pattern
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
596
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
597 result = []
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
598 quotebuf = None
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
599 charbuf = []
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
600 fieldchar = ['']
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
601 fieldnum = [0]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
602
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
603 def append_chars():
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
604 result.append(''.join(charbuf).replace('%', '%%'))
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
605 del charbuf[:]
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
606
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
607 def append_field():
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
608 limit = PATTERN_CHARS[fieldchar[0]]
15
76985c08a339 Minor date formatting improvements.
cmlenz
parents: 12
diff changeset
609 if limit and fieldnum[0] not in limit:
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
610 raise ValueError('Invalid length for field: %r'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
611 % (fieldchar[0] * fieldnum[0]))
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
612 result.append('%%(%s)s' % (fieldchar[0] * fieldnum[0]))
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
613 fieldchar[0] = ''
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
614 fieldnum[0] = 0
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
615
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
616 for idx, char in enumerate(pattern.replace("''", '\0')):
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
617 if quotebuf is None:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
618 if char == "'": # quote started
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
619 if fieldchar[0]:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
620 append_field()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
621 elif charbuf:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
622 append_chars()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
623 quotebuf = []
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
624 elif char in PATTERN_CHARS:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
625 if charbuf:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
626 append_chars()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
627 if char == fieldchar[0]:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
628 fieldnum[0] += 1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
629 else:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
630 if fieldchar[0]:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
631 append_field()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
632 fieldchar[0] = char
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
633 fieldnum[0] = 1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
634 else:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
635 if fieldchar[0]:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
636 append_field()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
637 charbuf.append(char)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
638
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
639 elif quotebuf is not None:
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
640 if char == "'": # end of quote
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
641 charbuf.extend(quotebuf)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
642 quotebuf = None
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
643 else: # inside quote
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
644 quotebuf.append(char)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
645
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
646 if fieldchar[0]:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
647 append_field()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
648 elif charbuf:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
649 append_chars()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
650
16
ed154241c08d Handle escape chars in datetime patterns.
cmlenz
parents: 15
diff changeset
651 return DateTimePattern(pattern, u''.join(result).replace('\0', "'"))
Copyright (C) 2012-2017 Edgewall Software