Skip to content

Commit

Permalink
Add Amharic Locale (arrow-py#1093)
Browse files Browse the repository at this point in the history
  • Loading branch information
yichidev authored Feb 18, 2022
1 parent 5ad47f1 commit c9cae9e
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 0 deletions.
2 changes: 2 additions & 0 deletions arrow/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,6 @@
"ka-ge",
"kk",
"kk-kz",
"am",
"am-et",
}
171 changes: 171 additions & 0 deletions arrow/locales.py
Original file line number Diff line number Diff line change
Expand Up @@ -6100,3 +6100,174 @@ class KazakhLocale(Locale):
"ЖСксСнбі",
]
day_abbreviations = ["", "Дс", "Бс", "Π‘Ρ€", "Бс", "Π–ΠΌ", "Π‘Π±", "Жс"]


class AmharicLocale(Locale):
names = ["am", "am-et"]

past = "{0} α‰ αŠα‰΅"
future = "{0} α‹αˆ΅αŒ₯"
and_word = "αŠ₯αŠ“"

timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[Mapping[str, str], str]]] = {
"now": "αŠ αˆαŠ•",
"second": {
"past": "αŠ¨αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅",
"future": "α‰ αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅",
},
"seconds": {
"past": "ከ {0} αˆ°αŠ¨αŠ•α‹΅",
"future": "α‰  {0} αˆ°αŠ¨αŠ•α‹΅",
},
"minute": {
"past": "αŠ¨αŠ αŠ•α‹΅ ደቂቃ",
"future": "α‰ αŠ αŠ•α‹΅ ደቂቃ",
},
"minutes": {
"past": "ከ {0} α‹°α‰‚α‰ƒα‹Žα‰½",
"future": "α‰  {0} α‹°α‰‚α‰ƒα‹Žα‰½",
},
"hour": {
"past": "αŠ¨αŠ αŠ•α‹΅ αˆ°α‹“α‰΅",
"future": "α‰ αŠ αŠ•α‹΅ αˆ°α‹“α‰΅",
},
"hours": {
"past": "ከ {0} αˆ°α‹“α‰³α‰΅",
"future": "α‰  {0} αˆ°αŠ¨αŠ•α‹΅",
},
"day": {
"past": "αŠ¨αŠ αŠ•α‹΅ α‰€αŠ•",
"future": "α‰ αŠ αŠ•α‹΅ α‰€αŠ•",
},
"days": {
"past": "ከ {0} α‰€αŠ“α‰΅",
"future": "α‰  {0} α‰€αŠ“α‰΅",
},
"week": {
"past": "αŠ¨αŠ αŠ•α‹΅ αˆ³αˆαŠ•α‰΅",
"future": "α‰ αŠ αŠ•α‹΅ αˆ³αˆαŠ•α‰΅",
},
"weeks": {
"past": "ከ {0} αˆ³αˆαŠ•α‰³α‰΅",
"future": "α‰  {0} αˆ³αˆαŠ•α‰³α‰΅",
},
"month": {
"past": "αŠ¨αŠ αŠ•α‹΅ α‹ˆαˆ­",
"future": "α‰ αŠ αŠ•α‹΅ α‹ˆαˆ­",
},
"months": {
"past": "ከ {0} α‹ˆαˆ­",
"future": "α‰  {0} α‹ˆαˆ«α‰΅",
},
"year": {
"past": "αŠ¨αŠ αŠ•α‹΅ αŠ αˆ˜α‰΅",
"future": "α‰ αŠ αŠ•α‹΅ αŠ αˆ˜α‰΅",
},
"years": {
"past": "ከ {0} α‹“αˆ˜α‰³α‰΅",
"future": "α‰  {0} α‹“αˆ˜α‰³α‰΅",
},
}
# Amharic: the general format to describe timeframe is different from past and future,
# so we do not copy the original timeframes dictionary
timeframes_only_distance = {
"second": "αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅",
"seconds": "{0} αˆ°αŠ¨αŠ•α‹΅",
"minute": "αŠ αŠ•α‹΅ ደቂቃ",
"minutes": "{0} α‹°α‰‚α‰ƒα‹Žα‰½",
"hour": "αŠ αŠ•α‹΅ αˆ°α‹“α‰΅",
"hours": "{0} αˆ°α‹“α‰΅",
"day": "αŠ αŠ•α‹΅ α‰€αŠ•",
"days": "{0} α‰€αŠ“α‰΅",
"week": "αŠ αŠ•α‹΅ αˆ³αˆαŠ•α‰΅",
"weeks": "{0} αˆ³αˆαŠ•α‰΅",
"month": "αŠ αŠ•α‹΅ α‹ˆαˆ­",
"months": "{0} α‹ˆαˆ«α‰΅",
"year": "αŠ αŠ•α‹΅ αŠ αˆ˜α‰΅",
"years": "{0} α‹“αˆ˜α‰³α‰΅",
}

month_names = [
"",
"αŒƒαŠ•α‹©α‹ˆαˆͺ",
"ፌα‰₯αˆ©α‹ˆαˆͺ",
"αˆ›αˆ­α‰½",
"αŠ€α•αˆͺል",
"αˆœα‹­",
"αŒαŠ•",
"αŒαˆ‹α‹­",
"αŠ¦αŒˆαˆ΅α‰΅",
"αˆ΄α•α‰΄αˆα‰ αˆ­",
"αŠ¦αŠ­α‰Άα‰ αˆ­",
"αŠ–α‰¬αˆα‰ αˆ­",
"α‹²αˆ΄αˆα‰ αˆ­",
]

month_abbreviations = [
"",
"αŒƒαŠ•α‹©",
"ፌα‰₯ሩ",
"αˆ›αˆ­α‰½",
"αŠ€α•αˆͺ",
"αˆœα‹­",
"αŒαŠ•",
"αŒαˆ‹α‹­",
"ኦገሡ",
"αˆ΄α•α‰΄",
"αŠ¦αŠ­α‰Ά",
"αŠ–α‰¬αˆ",
"α‹²αˆ΄αˆ",
]

day_names = [
"",
"ሰኞ",
"αˆ›αŠ­αˆ°αŠž",
"αˆ¨α‰‘α‹•",
"αˆαˆ™αˆ΅",
"α‹“αˆ­α‰₯",
"α‰…α‹³αˆœ",
"αŠ₯αˆ‘α‹΅",
]
day_abbreviations = ["", "αŠ₯", "ሰ", "αˆ›", "ረ", "ሐ", "α‹“", "α‰…"]

def _ordinal_number(self, n: int) -> str:
return f"{n}αŠ›"

def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
"""
Amharic awares time frame format function, takes into account
the differences between general, past, and future forms (three different suffixes).
"""
abs_delta = abs(delta)
form = self.timeframes[timeframe]

if isinstance(form, str):
return form.format(abs_delta)

if delta > 0:
key = "future"
else:
key = "past"
form = form[key]

return form.format(abs_delta)

def describe(
self,
timeframe: TimeFrameLiteral,
delta: Union[float, int] = 1, # key is always future when only_distance=False
only_distance: bool = False,
) -> str:
"""Describes a delta within a timeframe in plain language.
:param timeframe: a string representing a timeframe.
:param delta: a quantity representing a delta in a timeframe.
:param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
"""

if not only_distance:
return super().describe(timeframe, delta, only_distance)
humanized = self.timeframes_only_distance[timeframe].format(trunc(abs(delta)))

return humanized
76 changes: 76 additions & 0 deletions tests/test_locales.py
Original file line number Diff line number Diff line change
Expand Up @@ -2919,3 +2919,79 @@ def test_weekday(self):
dt = arrow.Arrow(2015, 4, 11, 17, 30, 00)
assert self.locale.day_name(dt.isoweekday()) == "lΓΈrdag"
assert self.locale.day_abbreviation(dt.isoweekday()) == "lΓΈr"


@pytest.mark.usefixtures("lang_locale")
class TestAmharicLocale:
def test_format_timeframe(self):
assert self.locale._format_timeframe("now", 0) == "αŠ αˆαŠ•"
# second(s)
assert self.locale._format_timeframe("second", 1) == "α‰ αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅"
assert self.locale._format_timeframe("second", -1) == "αŠ¨αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅"
assert self.locale._format_timeframe("seconds", 6) == "α‰  6 αˆ°αŠ¨αŠ•α‹΅"
assert self.locale._format_timeframe("seconds", -36) == "ከ 36 αˆ°αŠ¨αŠ•α‹΅"
# minute(s)
assert self.locale._format_timeframe("minute", 1) == "α‰ αŠ αŠ•α‹΅ ደቂቃ"
assert self.locale._format_timeframe("minute", -1) == "αŠ¨αŠ αŠ•α‹΅ ደቂቃ"
assert self.locale._format_timeframe("minutes", 7) == "α‰  7 α‹°α‰‚α‰ƒα‹Žα‰½"
assert self.locale._format_timeframe("minutes", -20) == "ከ 20 α‹°α‰‚α‰ƒα‹Žα‰½"
# hour(s)
assert self.locale._format_timeframe("hour", 1) == "α‰ αŠ αŠ•α‹΅ αˆ°α‹“α‰΅"
assert self.locale._format_timeframe("hour", -1) == "αŠ¨αŠ αŠ•α‹΅ αˆ°α‹“α‰΅"
assert self.locale._format_timeframe("hours", 7) == "α‰  7 αˆ°αŠ¨αŠ•α‹΅"
assert self.locale._format_timeframe("hours", -20) == "ከ 20 αˆ°α‹“α‰³α‰΅"
# day(s)
assert self.locale._format_timeframe("day", 1) == "α‰ αŠ αŠ•α‹΅ α‰€αŠ•"
assert self.locale._format_timeframe("day", -1) == "αŠ¨αŠ αŠ•α‹΅ α‰€αŠ•"
assert self.locale._format_timeframe("days", 7) == "α‰  7 α‰€αŠ“α‰΅"
assert self.locale._format_timeframe("days", -20) == "ከ 20 α‰€αŠ“α‰΅"
# week(s)
assert self.locale._format_timeframe("week", 1) == "α‰ αŠ αŠ•α‹΅ αˆ³αˆαŠ•α‰΅"
assert self.locale._format_timeframe("week", -1) == "αŠ¨αŠ αŠ•α‹΅ αˆ³αˆαŠ•α‰΅"
assert self.locale._format_timeframe("weeks", 7) == "α‰  7 αˆ³αˆαŠ•α‰³α‰΅"
assert self.locale._format_timeframe("weeks", -20) == "ከ 20 αˆ³αˆαŠ•α‰³α‰΅"
# month(s)
assert self.locale._format_timeframe("month", 1) == "α‰ αŠ αŠ•α‹΅ α‹ˆαˆ­"
assert self.locale._format_timeframe("month", -1) == "αŠ¨αŠ αŠ•α‹΅ α‹ˆαˆ­"
assert self.locale._format_timeframe("months", 7) == "α‰  7 α‹ˆαˆ«α‰΅"
assert self.locale._format_timeframe("months", -20) == "ከ 20 α‹ˆαˆ­"
# year(s)
assert self.locale._format_timeframe("year", 1) == "α‰ αŠ αŠ•α‹΅ αŠ αˆ˜α‰΅"
assert self.locale._format_timeframe("year", -1) == "αŠ¨αŠ αŠ•α‹΅ αŠ αˆ˜α‰΅"
assert self.locale._format_timeframe("years", 7) == "α‰  7 α‹“αˆ˜α‰³α‰΅"
assert self.locale._format_timeframe("years", -20) == "ከ 20 α‹“αˆ˜α‰³α‰΅"

def test_describe_am(self):
assert self.locale.describe("second", only_distance=True) == "αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅"
assert (
self.locale.describe("second", only_distance=False) == "α‰ αŠ αŠ•α‹΅ αˆ°αŠ¨αŠ•α‹΅ α‹αˆ΅αŒ₯"
) # (in) a second

assert self.locale.describe("minute", only_distance=True) == "αŠ αŠ•α‹΅ ደቂቃ"
assert (
self.locale.describe("minute", only_distance=False) == "α‰ αŠ αŠ•α‹΅ ደቂቃ α‹αˆ΅αŒ₯"
) # (in) a minute

def test_format_relative_now(self):
result = self.locale._format_relative("αŠ αˆαŠ•", "now", 0)
assert result == "αŠ αˆαŠ•"

def test_ordinal_number(self):
assert self.locale.ordinal_number(1) == "1αŠ›"

def test_format_relative_future(self):

result = self.locale._format_relative("α‰ αŠ αŠ•α‹΅ αˆ°α‹“α‰΅", "hour", 1)

assert result == "α‰ αŠ αŠ•α‹΅ αˆ°α‹“α‰΅ α‹αˆ΅αŒ₯" # (in) one hour

def test_format_relative_past(self):

result = self.locale._format_relative("αŠ¨αŠ αŠ•α‹΅ αˆ°α‹“α‰΅", "hour", -1)

assert result == "αŠ¨αŠ αŠ•α‹΅ αˆ°α‹“α‰΅ α‰ αŠα‰΅" # an hour ago

def test_weekday(self):
dt = arrow.Arrow(2015, 4, 11, 17, 30, 00)
assert self.locale.day_name(dt.isoweekday()) == "α‰…α‹³αˆœ"
assert self.locale.day_abbreviation(dt.isoweekday()) == "α‹“"

0 comments on commit c9cae9e

Please sign in to comment.