# HG changeset patch # User cmlenz # Date 1180967334 0 # Node ID 0505d666fa1f2564cb68d2386e0dcbd7db30db7c # Parent 8b6804eac9e5c9fe62ad8966bcb1a3b71a3e8a4a * Import datetime patterns from CLDR. * Make the date/time arguments to the formatting functions optional, defaulting to the current date/time. diff --git a/babel/core.py b/babel/core.py --- a/babel/core.py +++ b/babel/core.py @@ -397,6 +397,19 @@ :type: `dict` """) + def datetime_formats(self): + return self._data['datetime_formats'] + datetime_formats = property(datetime_formats, doc="""\ + Locale patterns for datetime formatting. + + >>> Locale('en').datetime_formats[None] + u'{1} {0}' + >>> Locale('th').datetime_formats[None] + u'{1}, {0}' + + :type: `dict` + """) + def negotiate(preferred, available): """Find the best match between available and requested locale strings. diff --git a/babel/dates.py b/babel/dates.py --- a/babel/dates.py +++ b/babel/dates.py @@ -32,6 +32,11 @@ LC_TIME = default_locale('LC_TIME') +# Aliases for use in scopes where the modules are shadowed by local variables +date_ = date +datetime_ = datetime +time_ = time + def get_period_names(locale=LC_TIME): """Return the names for day periods (AM/PM) used by the locale. @@ -124,10 +129,28 @@ "short" :param locale: the `Locale` object, or a locale string :return: the date format pattern - :rtype: `dict` + :rtype: `DateTimePattern` """ return Locale.parse(locale).date_formats[format] +def get_datetime_format(format='medium', locale=LC_TIME): + """Return the datetime formatting patterns used by the locale for the + specified format. + + >>> get_datetime_format(locale='en_US') + u'{1} {0}' + + :param format: the format to use, one of "full", "long", "medium", or + "short" + :param locale: the `Locale` object, or a locale string + :return: the datetime format pattern + :rtype: `unicode` + """ + patterns = Locale.parse(locale).datetime_formats + if format not in patterns: + format = None + return patterns[format] + def get_time_format(format='medium', locale=LC_TIME): """Return the time formatting patterns used by the locale for the specified format. @@ -141,11 +164,11 @@ "short" :param locale: the `Locale` object, or a locale string :return: the time format pattern - :rtype: `dict` + :rtype: `DateTimePattern` """ return Locale.parse(locale).time_formats[format] -def format_date(date, format='medium', locale=LC_TIME): +def format_date(date=None, format='medium', locale=LC_TIME): """Returns a date formatted according to the given pattern. >>> d = date(2007, 04, 01) @@ -160,7 +183,8 @@ >>> format_date(d, "EEE, MMM d, ''yy", locale='en') u"Sun, Apr 1, '07" - :param date: the ``date`` or ``datetime`` object + :param date: the ``date`` or ``datetime`` object; if `None`, the current + date is used :param format: one of "full", "long", "medium", or "short", or a custom date/time pattern :param locale: a `Locale` object or a locale identifier @@ -171,7 +195,9 @@ the value of ``date`` parameter is actually a ``datetime`` object, as this function automatically converts that to a ``date``. """ - if isinstance(date, datetime): + if date is None: + date = date_.today() + elif isinstance(date, datetime): date = date.date() locale = Locale.parse(locale) if format in ('full', 'long', 'medium', 'short'): @@ -179,23 +205,33 @@ pattern = parse_pattern(format) return parse_pattern(format).apply(date, locale) -def format_datetime(datetime, format='medium', tzinfo=UTC, locale=LC_TIME): +def format_datetime(datetime=None, format='medium', tzinfo=UTC, locale=LC_TIME): """Returns a date formatted according to the given pattern. - :param datetime: the ``date`` object + >>> dt = datetime(2007, 04, 01, 15, 30) + >>> format_datetime(dt, locale='en_US') + u'Apr 1, 2007 3:30:00 PM' + + :param datetime: the `datetime` object; if `None`, the current date and + time is used :param format: one of "full", "long", "medium", or "short", or a custom date/time pattern :param tzinfo: the timezone to apply to the time for display :param locale: a `Locale` object or a locale identifier :rtype: `unicode` """ + if datetime is None: + datetime = datetime_.now() locale = Locale.parse(locale) if format in ('full', 'long', 'medium', 'short'): - raise NotImplementedError - pattern = parse_pattern(format) - return parse_pattern(format).apply(datetime, locale) + return get_datetime_format(format, locale=locale) \ + .replace('{0}', format_time(datetime, format, tzinfo=tzinfo, + locale=locale)) \ + .replace('{1}', format_date(datetime, format, locale=locale)) + else: + return parse_pattern(format).apply(datetime, locale) -def format_time(time, format='medium', tzinfo=UTC, locale=LC_TIME): +def format_time(time=None, format='medium', tzinfo=UTC, locale=LC_TIME): """Returns a time formatted according to the given pattern. >>> t = time(15, 30) @@ -218,7 +254,8 @@ >>> format_time(t, format='full', tzinfo=cet, locale='de_DE') u'15:30 Uhr MEZ' - :param time: the ``time`` or ``datetime`` object + :param time: the ``time`` or ``datetime`` object; if `None`, the current + time is used :param format: one of "full", "long", "medium", or "short", or a custom date/time pattern :param tzinfo: the time-zone to apply to the time for display @@ -230,7 +267,9 @@ the value of ``time`` parameter is actually a ``datetime`` object, as this function automatically converts that to a ``time``. """ - if isinstance(time, (int, long)): + if time is None: + time = datetime.now().time() + elif isinstance(time, (int, long)): time = datetime.fromtimestamp(time).time() elif isinstance(time, datetime): time = time.time() diff --git a/scripts/dump_data.py b/scripts/dump_data.py --- a/scripts/dump_data.py +++ b/scripts/dump_data.py @@ -14,7 +14,7 @@ from pprint import pprint import sys -from babel import Locale -locale = Locale(sys.argv[1]) -pprint(locale._data) +from babel.localedata import load + +pprint(load(sys.argv[1])) diff --git a/scripts/import_cldr.py b/scripts/import_cldr.py --- a/scripts/import_cldr.py +++ b/scripts/import_cldr.py @@ -239,6 +239,16 @@ except ValueError, e: print>>sys.stderr, 'ERROR: %s' % e + datetime_formats = data.setdefault('datetime_formats', {}) + for elem in calendar.findall('dateTimeFormats/dateTimeFormatLength'): + if 'draft' in elem.attrib and elem.attrib.get('type') in datetime_formats: + continue + try: + datetime_formats[elem.attrib.get('type')] = \ + unicode(elem.findtext('dateTimeFormat/pattern')) + except ValueError, e: + print>>sys.stderr, 'ERROR: %s' % e + # number_symbols = data.setdefault('number_symbols', {})