Permalink
Browse files

Added basic localizations for humanize

Added support for humanize working with different languages (added Russian for example)

New languages support are very basic, and doesn't handle proper changing of nouns plural forms for now.

Updated docs and tests
  • Loading branch information...
1 parent 25abfce commit 214115556933decb3d486f00ab98a20d201ec671 @cleg cleg committed May 8, 2013
Showing with 100 additions and 16 deletions.
  1. +2 −0 .gitignore
  2. +21 −16 arrow/arrow.py
  3. +37 −0 arrow/locales.py
  4. +8 −0 docs/index.rst
  5. +32 −0 tests/arrow_tests.py
View
@@ -7,3 +7,5 @@ nosetests.xml
local/
dist/
docs/_build/
+.idea
+.DS_Store
View
@@ -3,7 +3,9 @@
from dateutil.relativedelta import relativedelta
import calendar
-import parser, formatter
+import parser
+import formatter
+import locales
class Arrow(object):
@@ -371,7 +373,7 @@ def ceil(self, frame):
def format(self, fmt):
return formatter.DateTimeFormatter.format(self._datetime, fmt)
- def humanize(self, other=None):
+ def humanize(self, other=None, locale='english'):
if other is None:
utc = datetime.utcnow().replace(tzinfo=dateutil_tz.tzutc())
@@ -389,45 +391,48 @@ def humanize(self, other=None):
else:
raise TypeError()
+ local_dict = getattr(locales, locale, None)
+ if local_dict is None:
+ raise ValueError('Invalid language {0}'.format(locale))
+
delta = int((self._datetime - dt).total_seconds())
past = delta < 0
delta = abs(delta)
if delta < 10:
- return 'just now'
+ return local_dict['now']
if delta < 45:
- expr = 'seconds'
+ expr = local_dict['seconds']
elif delta < 90:
- expr = 'a minute'
+ expr = local_dict['minute']
elif delta < 2700:
minutes = max(delta / 60, 2)
- expr = '{0} minutes'.format(minutes)
+ expr = local_dict['minutes'].format(minutes)
elif delta < 5400:
- expr = 'an hour'
+ expr = local_dict['hour']
elif delta < 79200:
hours = max(delta / 3600, 2)
- expr = '{0} hours'.format(hours)
+ expr = local_dict['hours'].format(hours)
elif delta < 129600:
- expr = 'a day'
+ expr = local_dict['day']
elif delta < 2160000:
days = max(delta / 86400, 2)
- expr = '{0} days'.format(days)
+ expr = local_dict['days'].format(days)
elif delta < 3888000:
- expr = 'a month'
+ expr = local_dict['month']
elif delta < 29808000:
months = max(abs(dt.month - self._datetime.month), 2)
- expr = '{0} months'.format(months)
+ expr = local_dict['months'].format(months)
elif delta < 47260800:
- expr = 'a year'
+ expr = local_dict['year']
else:
years = max(delta / 31536000, 2)
- expr = '{0} years'.format(years)
-
- return '{0} ago'.format(expr) if past else 'in {0}'.format(expr)
+ expr = local_dict['years'].format(years)
+ return local_dict['past'].format(expr) if past else local_dict['future'].format(expr)
View
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+english = {
+ 'now': 'just now',
+ 'seconds': 'seconds',
+ 'minute': 'a minute',
+ 'minutes': '{0} minutes',
+ 'hour': 'an hour',
+ 'hours': '{0} hours',
+ 'day': 'a day',
+ 'days': '{0} days',
+ 'month': 'a month',
+ 'months': '{0} months',
+ 'year': 'a year',
+ 'years': '{0} years',
+
+ 'past': '{0} ago',
+ 'future': 'in {0}',
+}
+
+russian = {
+ 'now': 'сейчас',
+ 'seconds': 'несколько секунд',
+ 'minute': 'минуту',
+ 'minutes': '{0} minutes',
+ 'hour': 'час',
+ 'hours': '{0} час(а,ов)',
+ 'day': 'день',
+ 'days': '{0} дня(ей)',
+ 'month': 'месяц',
+ 'months': '{0} месяц(а,ев)',
+ 'year': 'год',
+ 'years': '{0} года/лет',
+
+ 'past': '{0} назад',
+ 'future': 'через {0}',
+}
View
@@ -193,6 +193,14 @@ Or another Arrow, or datetime:
>>> b.humanize(a)
'in 2 hours'
+Basic localisations added. Now only russian available (without changing nouns in plural forms), but you can add your language by adding it to `locales.py`
+
+>>> b = arrow.utcnow()
+>>> b.hours += 1
+>>> b.humanize(a, locale='russian')
+'через 2 час(а,ов)'
+
+
Timespans
=========
View
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
from chai import Chai
from datetime import datetime, timedelta
@@ -665,6 +667,13 @@ def test_other(self):
with assertRaises(TypeError):
arw.humanize(object())
+ def test_invalid_locale(self):
+
+ arw = arrow.Arrow.fromdatetime(self.datetime)
+
+ with assertRaises(ValueError):
+ arw.humanize(locale='klingon')
+
def test_none(self):
arw = arrow.Arrow.utcnow()
@@ -673,3 +682,26 @@ def test_none(self):
assertEqual(result, 'just now')
+
+class ArrowHumanizeTestsWithLocale(Chai):
+
+ def setUp(self):
+ super(ArrowHumanizeTestsWithLocale, self).setUp()
+
+ self.datetime = datetime(2013, 1, 1)
+
+ def test_seconds(self):
+
+ arw = arrow.Arrow(2013, 1, 1, 0, 0, 44)
+
+ result = arw.humanize(self.datetime, locale='russian')
+
+ assertEqual(result, 'через несколько секунд')
+
+ def test_years(self):
+
+ arw = arrow.Arrow(2011, 7, 2)
+
+ result = arw.humanize(self.datetime, locale='russian')
+
+ assertEqual(result, '2 года/лет назад')

0 comments on commit 2141155

Please sign in to comment.