summaryrefslogtreecommitdiff
path: root/babel
diff options
context:
space:
mode:
Diffstat (limited to 'babel')
-rw-r--r--babel/dates.py121
1 files changed, 59 insertions, 62 deletions
diff --git a/babel/dates.py b/babel/dates.py
index 6a017e8..72674e8 100644
--- a/babel/dates.py
+++ b/babel/dates.py
@@ -17,18 +17,17 @@
"""
from __future__ import division
-from datetime import date, datetime, time, timedelta
-from bisect import bisect_right
+
import re
import pytz as _pytz
+from datetime import date, datetime, time, timedelta
+from bisect import bisect_right
+
from babel.core import default_locale, get_global, Locale
from babel.util import UTC, LOCALTZ
from babel._compat import string_types, integer_types, number_types
-__all__ = ['format_date', 'format_datetime', 'format_time', 'format_timedelta',
- 'get_timezone_name', 'parse_date', 'parse_datetime', 'parse_time']
-
LC_TIME = default_locale('LC_TIME')
@@ -37,6 +36,7 @@ date_ = date
datetime_ = datetime
time_ = time
+
def get_timezone(zone=None):
"""Looks up a timezone by name and returns it. The timezone object
returned comes from ``pytz`` and corresponds to the `tzinfo` interface and
@@ -44,6 +44,9 @@ def get_timezone(zone=None):
If a timezone is not known a :exc:`LookupError` is raised. If `zone`
is ``None`` a local zone object is returned.
+
+ :param zone: the name of the timezone to look up. If a timezone object
+ itself is passed in, mit's returned unchanged.
"""
if zone is None:
return LOCALTZ
@@ -54,6 +57,7 @@ def get_timezone(zone=None):
except _pytz.UnknownTimeZoneError:
raise LookupError('Unknown timezone %s' % zone)
+
def get_next_timezone_transition(zone=None, dt=None):
"""Given a timezone it will return a :class:`TimezoneTransition` object
that holds the information about the next timezone transition that's going
@@ -66,6 +70,11 @@ def get_next_timezone_transition(zone=None, dt=None):
Transition information can only be provided for timezones returned by
the :func:`get_timezone` function.
+
+ :param zone: the timezone for which the transition should be looked up.
+ If not provided the local timezone is used.
+ :param dt: the date after which the next transition should be found.
+ If not given the current time is assumed.
"""
zone = get_timezone(zone)
if dt is None:
@@ -97,28 +106,40 @@ def get_next_timezone_transition(zone=None, dt=None):
class TimezoneTransition(object):
+ """A helper object that represents the return value from
+ :func:`get_next_timezone_transition`.
+ """
def __init__(self, activates, from_tzinfo, to_tzinfo, reference_date=None):
+ #: the time of the activation of the timezone transition in UTC.
self.activates = activates
+ #: the timezone from where the transition starts.
self.from_tzinfo = from_tzinfo
+ #: the timezone for after the transition.
self.to_tzinfo = to_tzinfo
+ #: the reference date that was provided. This is the `dt` parameter
+ #: to the :func:`get_next_timezone_transition`.
self.reference_date = reference_date
@property
def from_tz(self):
+ """The name of the timezone before the transition."""
return self.from_tzinfo._tzname
@property
def to_tz(self):
+ """The name of the timezone after the transition."""
return self.to_tzinfo._tzname
@property
def from_offset(self):
- return self.from_tzinfo._utcoffset.total_seconds()
+ """The UTC offset in seconds before the transition."""
+ return int(self.from_tzinfo._utcoffset.total_seconds())
@property
def to_offset(self):
- return self.to_tzinfo._utcoffset.total_seconds()
+ """The UTC offset in seconds after the transition."""
+ return int(self.to_tzinfo._utcoffset.total_seconds())
def __repr__(self):
return '<TimezoneTransition %s -> %s (%s)>' % (
@@ -127,6 +148,7 @@ class TimezoneTransition(object):
self.activates,
)
+
def get_period_names(locale=LC_TIME):
"""Return the names for day periods (AM/PM) used by the locale.
@@ -134,11 +156,10 @@ def get_period_names(locale=LC_TIME):
u'AM'
:param locale: the `Locale` object, or a locale string
- :return: the dictionary of period names
- :rtype: `dict`
"""
return Locale.parse(locale).periods
+
def get_day_names(width='wide', context='format', locale=LC_TIME):
"""Return the day names used by the locale for the specified format.
@@ -152,11 +173,10 @@ def get_day_names(width='wide', context='format', locale=LC_TIME):
:param width: the width to use, one of "wide", "abbreviated", or "narrow"
:param context: the context, either "format" or "stand-alone"
:param locale: the `Locale` object, or a locale string
- :return: the dictionary of day names
- :rtype: `dict`
"""
return Locale.parse(locale).days[context][width]
+
def get_month_names(width='wide', context='format', locale=LC_TIME):
"""Return the month names used by the locale for the specified format.
@@ -170,11 +190,10 @@ def get_month_names(width='wide', context='format', locale=LC_TIME):
:param width: the width to use, one of "wide", "abbreviated", or "narrow"
:param context: the context, either "format" or "stand-alone"
:param locale: the `Locale` object, or a locale string
- :return: the dictionary of month names
- :rtype: `dict`
"""
return Locale.parse(locale).months[context][width]
+
def get_quarter_names(width='wide', context='format', locale=LC_TIME):
"""Return the quarter names used by the locale for the specified format.
@@ -186,11 +205,10 @@ def get_quarter_names(width='wide', context='format', locale=LC_TIME):
:param width: the width to use, one of "wide", "abbreviated", or "narrow"
:param context: the context, either "format" or "stand-alone"
:param locale: the `Locale` object, or a locale string
- :return: the dictionary of quarter names
- :rtype: `dict`
"""
return Locale.parse(locale).quarters[context][width]
+
def get_era_names(width='wide', locale=LC_TIME):
"""Return the era names used by the locale for the specified format.
@@ -201,11 +219,10 @@ def get_era_names(width='wide', locale=LC_TIME):
:param width: the width to use, either "wide", "abbreviated", or "narrow"
:param locale: the `Locale` object, or a locale string
- :return: the dictionary of era names
- :rtype: `dict`
"""
return Locale.parse(locale).eras[width]
+
def get_date_format(format='medium', locale=LC_TIME):
"""Return the date formatting patterns used by the locale for the specified
format.
@@ -218,11 +235,10 @@ def get_date_format(format='medium', locale=LC_TIME):
:param format: the format to use, one of "full", "long", "medium", or
"short"
:param locale: the `Locale` object, or a locale string
- :return: the date format pattern
- :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.
@@ -233,14 +249,13 @@ def get_datetime_format(format='medium', locale=LC_TIME):
: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.
@@ -253,11 +268,10 @@ def get_time_format(format='medium', locale=LC_TIME):
:param format: the format to use, one of "full", "long", "medium", or
"short"
:param locale: the `Locale` object, or a locale string
- :return: the time format pattern
- :rtype: `DateTimePattern`
"""
return Locale.parse(locale).time_formats[format]
+
def get_timezone_gmt(datetime=None, width='long', locale=LC_TIME):
"""Return the timezone associated with the given `datetime` object formatted
as string indicating the offset from GMT.
@@ -279,13 +293,12 @@ def get_timezone_gmt(datetime=None, width='long', locale=LC_TIME):
>>> get_timezone_gmt(dt, 'long', locale='fr_FR')
u'UTC-08:00'
+ .. versionadded:: 0.9
+
:param datetime: the ``datetime`` object; if `None`, the current date and
time in UTC is used
:param width: either "long" or "short"
:param locale: the `Locale` object, or a locale string
- :return: the GMT offset representation of the timezone
- :rtype: `unicode`
- :since: version 0.9
"""
if datetime is None:
datetime = datetime_.utcnow()
@@ -304,6 +317,7 @@ def get_timezone_gmt(datetime=None, width='long', locale=LC_TIME):
pattern = locale.zone_formats['gmt'] % '%+03d:%02d'
return pattern % (hours, seconds // 60)
+
def get_timezone_location(dt_or_tzinfo=None, locale=LC_TIME):
"""Return a representation of the given timezone using "location format".
@@ -324,13 +338,13 @@ def get_timezone_location(dt_or_tzinfo=None, locale=LC_TIME):
>>> get_timezone_name(tz, locale='de_DE')
u'Mitteleurop\\xe4ische Zeit'
+ .. versionadded:: 0.9
+
:param dt_or_tzinfo: the ``datetime`` or ``tzinfo`` object that determines
the timezone; if `None`, the current date and time in
UTC is assumed
:param locale: the `Locale` object, or a locale string
:return: the localized timezone name using location format
- :rtype: `unicode`
- :since: version 0.9
"""
if dt_or_tzinfo is None:
dt = datetime.now()
@@ -391,6 +405,7 @@ def get_timezone_location(dt_or_tzinfo=None, locale=LC_TIME):
'1': territory_name
})
+
def get_timezone_name(dt_or_tzinfo=None, width='long', uncommon=False,
locale=LC_TIME, zone_variant=None):
r"""Return the localized display name for the given timezone. The timezone
@@ -430,7 +445,15 @@ def get_timezone_name(dt_or_tzinfo=None, width='long', uncommon=False,
>>> get_timezone_name(tz, locale='de_DE')
u'Neufundland-Zeit'
- Note that short format is currently not supported for all timezones.
+ Note that short format is currently not supported for all timezones and
+ all locales. This is partially because not every timezone has a short
+ code in every locale. In that case it currently falls back to the long
+ format.
+
+ For more information see `LDML Appendix J: Time Zone Display Names
+ <http://www.unicode.org/reports/tr35/#Time_Zone_Fallback>`_
+
+ .. versionadded:: 0.9
.. versionchanged:: 1.0
Added `zone_variant` support.
@@ -449,11 +472,6 @@ def get_timezone_name(dt_or_tzinfo=None, width='long', uncommon=False,
values are valid: ``'generic'``, ``'daylight'`` and
``'standard'``.
:param locale: the `Locale` object, or a locale string
- :return: the timezone display name
- :rtype: `unicode`
- :since: version 0.9
- :see: `LDML Appendix J: Time Zone Display Names
- <http://www.unicode.org/reports/tr35/#Time_Zone_Fallback>`_
"""
if dt_or_tzinfo is None:
dt = datetime.now()
@@ -516,6 +534,7 @@ def get_timezone_name(dt_or_tzinfo=None, width='long', uncommon=False,
return get_timezone_location(dt_or_tzinfo, locale=locale)
+
def format_date(date=None, format='medium', locale=LC_TIME):
"""Return a date formatted according to the given pattern.
@@ -536,12 +555,6 @@ def format_date(date=None, format='medium', locale=LC_TIME):
:param format: one of "full", "long", "medium", or "short", or a custom
date/time pattern
:param locale: a `Locale` object or a locale identifier
- :rtype: `unicode`
-
- :note: If the pattern contains time fields, an `AttributeError` will be
- raised when trying to apply the formatting. This is also true if
- the value of ``date`` parameter is actually a ``datetime`` object,
- as this function automatically converts that to a ``date``.
"""
if date is None:
date = date_.today()
@@ -554,6 +567,7 @@ def format_date(date=None, format='medium', locale=LC_TIME):
pattern = parse_pattern(format)
return pattern.apply(date, locale)
+
def format_datetime(datetime=None, format='medium', tzinfo=None,
locale=LC_TIME):
r"""Return a date formatted according to the given pattern.
@@ -578,7 +592,6 @@ def format_datetime(datetime=None, format='medium', tzinfo=None,
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_.utcnow()
@@ -603,6 +616,7 @@ def format_datetime(datetime=None, format='medium', tzinfo=None,
else:
return parse_pattern(format).apply(datetime, locale)
+
def format_time(time=None, format='medium', tzinfo=None, locale=LC_TIME):
r"""Return a time formatted according to the given pattern.
@@ -657,12 +671,6 @@ def format_time(time=None, format='medium', tzinfo=None, locale=LC_TIME):
date/time pattern
:param tzinfo: the time-zone to apply to the time for display
:param locale: a `Locale` object or a locale identifier
- :rtype: `unicode`
-
- :note: If the pattern contains date fields, an `AttributeError` will be
- raised when trying to apply the formatting. This is also true if
- the value of ``time`` parameter is actually a ``datetime`` object,
- as this function automatically converts that to a ``time``.
"""
if time is None:
time = datetime.utcnow()
@@ -684,6 +692,7 @@ def format_time(time=None, format='medium', tzinfo=None, locale=LC_TIME):
format = get_time_format(format, locale=locale)
return parse_pattern(format).apply(time, locale)
+
TIMEDELTA_UNITS = (
('year', 3600 * 24 * 365),
('month', 3600 * 24 * 30),
@@ -694,6 +703,7 @@ TIMEDELTA_UNITS = (
('second', 1)
)
+
def format_timedelta(delta, granularity='second', threshold=.85,
add_direction=False, format='medium',
locale=LC_TIME):
@@ -742,7 +752,6 @@ def format_timedelta(delta, granularity='second', threshold=.85,
about the value being in the past.
:param format: the format (currently only "medium" and "short" are supported)
:param locale: a `Locale` object or a locale identifier
- :rtype: `unicode`
"""
if format not in ('short', 'medium'):
raise TypeError('Format can only be one of "short" or "medium"')
@@ -781,6 +790,7 @@ def format_timedelta(delta, granularity='second', threshold=.85,
return u''
+
def parse_date(string, locale=LC_TIME):
"""Parse a date from a string.
@@ -794,8 +804,6 @@ def parse_date(string, locale=LC_TIME):
:param string: the string containing the date
:param locale: a `Locale` object or a locale identifier
- :return: the parsed date
- :rtype: `date`
"""
# TODO: try ISO format first?
format = get_date_format(locale=locale).pattern.lower()
@@ -824,18 +832,6 @@ def parse_date(string, locale=LC_TIME):
month, day = day, month
return date(year, month, day)
-def parse_datetime(string, locale=LC_TIME):
- """Parse a date and time from a string.
-
- This function uses the date and time formats for the locale as a hint to
- determine the order in which the time fields appear in the string.
-
- :param string: the string containing the date and time
- :param locale: a `Locale` object or a locale identifier
- :return: the parsed date/time
- :rtype: `datetime`
- """
- raise NotImplementedError
def parse_time(string, locale=LC_TIME):
"""Parse a time from a string.
@@ -1103,6 +1099,7 @@ PATTERN_CHARS = {
'z': [1, 2, 3, 4], 'Z': [1, 2, 3, 4], 'v': [1, 4], 'V': [1, 4] # zone
}
+
def parse_pattern(pattern):
"""Parse date, time, and datetime format patterns.