num2words 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile +0 -1
- data/README.md +85 -23
- data/config/locales/ar.yml +176 -17
- data/config/locales/be.yml +182 -15
- data/config/locales/bg.yml +183 -16
- data/config/locales/bn.yml +185 -12
- data/config/locales/cs.yml +180 -13
- data/config/locales/da.yml +182 -15
- data/config/locales/de.yml +181 -14
- data/config/locales/el.yml +183 -21
- data/config/locales/en.yml +145 -18
- data/config/locales/es.yml +180 -13
- data/config/locales/et.yml +185 -13
- data/config/locales/fa.yml +179 -12
- data/config/locales/fi.yml +180 -8
- data/config/locales/fr.yml +180 -13
- data/config/locales/gu.yml +182 -10
- data/config/locales/he.yml +182 -20
- data/config/locales/hi.yml +182 -15
- data/config/locales/hr.yml +181 -14
- data/config/locales/hu.yml +180 -13
- data/config/locales/id.yml +179 -12
- data/config/locales/it.yml +181 -14
- data/config/locales/ja.yml +188 -21
- data/config/locales/ru.yml +148 -15
- data/lib/num2words/config.rb +62 -0
- data/lib/num2words/converter.rb +115 -29
- data/lib/num2words/core_ext.rb +12 -0
- data/lib/num2words/locales/ar.rb +10 -2
- data/lib/num2words/locales/be.rb +10 -2
- data/lib/num2words/locales/bg.rb +10 -2
- data/lib/num2words/locales/bn.rb +10 -2
- data/lib/num2words/locales/cs.rb +10 -2
- data/lib/num2words/locales/da.rb +10 -2
- data/lib/num2words/locales/de.rb +10 -2
- data/lib/num2words/locales/el.rb +10 -2
- data/lib/num2words/locales/en.rb +4 -4
- data/lib/num2words/locales/es.rb +10 -2
- data/lib/num2words/locales/et.rb +10 -2
- data/lib/num2words/locales/fa.rb +10 -2
- data/lib/num2words/locales/fi.rb +10 -2
- data/lib/num2words/locales/fr.rb +10 -2
- data/lib/num2words/locales/gu.rb +10 -2
- data/lib/num2words/locales/he.rb +10 -2
- data/lib/num2words/locales/hi.rb +10 -2
- data/lib/num2words/locales/hr.rb +10 -2
- data/lib/num2words/locales/hu.rb +10 -2
- data/lib/num2words/locales/id.rb +10 -2
- data/lib/num2words/locales/it.rb +10 -2
- data/lib/num2words/locales/ja.rb +10 -2
- data/lib/num2words/locales/ru.rb +4 -4
- data/lib/num2words/version.rb +1 -1
- data/lib/num2words.rb +1 -0
- metadata +4 -3
data/config/locales/ru.yml
CHANGED
@@ -13,13 +13,6 @@ ru:
|
|
13
13
|
- ["миллиард", "миллиарда", "миллиардов"]
|
14
14
|
- ["триллион", "триллиона", "триллионов"]
|
15
15
|
|
16
|
-
currencies:
|
17
|
-
RUB:
|
18
|
-
name: ["рубль", "рубля", "рублей"]
|
19
|
-
fractional:
|
20
|
-
name: ["копейка", "копейки", "копеек"]
|
21
|
-
feminine: true
|
22
|
-
|
23
16
|
grammar:
|
24
17
|
minus: "минус"
|
25
18
|
conjunction: "целых"
|
@@ -35,14 +28,6 @@ ru:
|
|
35
28
|
100000000: ["стомиллионная", "стомиллионные", "стомиллионных"]
|
36
29
|
1000000000: ["миллиардная", "миллиардные", "миллиардных"]
|
37
30
|
|
38
|
-
date:
|
39
|
-
template:
|
40
|
-
default: "%{day} %{month} %{year} года"
|
41
|
-
nominative: "%{day} %{month} %{year} год"
|
42
|
-
months:
|
43
|
-
default: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
|
44
|
-
nominative: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
|
45
|
-
|
46
31
|
numbers:
|
47
32
|
ordinals:
|
48
33
|
nominative:
|
@@ -63,3 +48,151 @@ ru:
|
|
63
48
|
"десятого", "одиннадцатого", "двенадцатого", "тринадцатого", "четырнадцатого", "пятнадцатого", "шестнадцатого", "семнадцатого", "восемнадцатого", "девятнадцатого",
|
64
49
|
"двадцатого", "двадцать первого", "двадцать второго", "двадцать третьего", "двадцать четвёртого", "двадцать пятого", "двадцать шестого", "двадцать седьмого", "двадцать восьмого", "двадцать девятого",
|
65
50
|
"тридцатого", "тридцать первого"]
|
51
|
+
|
52
|
+
datetime:
|
53
|
+
template: "%{date}, %{time}"
|
54
|
+
date:
|
55
|
+
template:
|
56
|
+
default: "%{day} %{month} %{year} года"
|
57
|
+
nominative: "%{day} %{month} %{year} год"
|
58
|
+
months:
|
59
|
+
default: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
|
60
|
+
nominative: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
|
61
|
+
time:
|
62
|
+
template:
|
63
|
+
hours_only: "%{hours}"
|
64
|
+
hours_minutes: "%{hours} %{minutes}"
|
65
|
+
hours_minutes_seconds: "%{hours} %{minutes} %{seconds}"
|
66
|
+
words:
|
67
|
+
hour: ["час", "часа", "часов"]
|
68
|
+
minute: ["минута", "минуты", "минут"]
|
69
|
+
second: ["секунда", "секунды", "секунд"]
|
70
|
+
|
71
|
+
warnings:
|
72
|
+
currency_not_available: "Валюта %{currency} недоступна для локали %{lang}, используется текущая."
|
73
|
+
|
74
|
+
currencies:
|
75
|
+
RUB:
|
76
|
+
major_unit: ["рубль", "рубля", "рублей"]
|
77
|
+
minor_unit: ["копейка", "копейки", "копеек"]
|
78
|
+
symbol: "₽"
|
79
|
+
USD:
|
80
|
+
major_unit: ["доллар", "доллара", "долларов"]
|
81
|
+
minor_unit: ["цент", "цента", "центов"]
|
82
|
+
symbol: "$"
|
83
|
+
EUR:
|
84
|
+
major_unit: ["евро", "евро", "евро"]
|
85
|
+
minor_unit: ["цент", "цента", "центов"]
|
86
|
+
symbol: "€"
|
87
|
+
GBP:
|
88
|
+
major_unit: ["фунт", "фунта", "фунтов"]
|
89
|
+
minor_unit: ["пенс", "пенса", "пенсов"]
|
90
|
+
symbol: "£"
|
91
|
+
CNY:
|
92
|
+
major_unit: ["юань", "юаня", "юаней"]
|
93
|
+
minor_unit: ["фэнь", "фэня", "фэней"]
|
94
|
+
symbol: "¥"
|
95
|
+
JPY:
|
96
|
+
major_unit: ["иена", "иены", "иен"]
|
97
|
+
minor_unit: ["сэн", "сэн", "сэн"]
|
98
|
+
symbol: "¥"
|
99
|
+
KRW:
|
100
|
+
major_unit: ["вона", "воны", "вон"]
|
101
|
+
minor_unit: ["чон", "чона", "чон"]
|
102
|
+
symbol: "₩"
|
103
|
+
TRY:
|
104
|
+
major_unit: ["лира", "лиры", "лир"]
|
105
|
+
minor_unit: ["куруш", "куруша", "курушей"]
|
106
|
+
symbol: "₺"
|
107
|
+
PLN:
|
108
|
+
major_unit: ["злотый", "злотых", "злотых"]
|
109
|
+
minor_unit: ["грош", "гроша", "грошей"]
|
110
|
+
symbol: "zł"
|
111
|
+
UAH:
|
112
|
+
major_unit: ["гривна", "гривны", "гривен"]
|
113
|
+
minor_unit: ["копейка", "копейки", "копеек"]
|
114
|
+
symbol: "₴"
|
115
|
+
CZK:
|
116
|
+
major_unit: ["крона", "кроны", "крон"]
|
117
|
+
minor_unit: ["галирж", "галиржа", "галиржей"]
|
118
|
+
symbol: "Kč"
|
119
|
+
RON:
|
120
|
+
major_unit: ["лей", "лея", "леев"]
|
121
|
+
minor_unit: ["бан", "бана", "банов"]
|
122
|
+
symbol: "lei"
|
123
|
+
BGN:
|
124
|
+
major_unit: ["лев", "лева", "левов"]
|
125
|
+
minor_unit: ["стотинка", "стотинки", "стотинок"]
|
126
|
+
symbol: "лв"
|
127
|
+
BYN:
|
128
|
+
major_unit: ["белорусский рубль", "белорусских рубля", "белорусских рублей"]
|
129
|
+
minor_unit: ["копейка", "копейки", "копеек"]
|
130
|
+
symbol: "Br"
|
131
|
+
KZT:
|
132
|
+
major_unit: ["тенге", "тенге", "тенге"]
|
133
|
+
minor_unit: ["тиын", "тиына", "тиынов"]
|
134
|
+
symbol: "₸"
|
135
|
+
ILS:
|
136
|
+
major_unit: ["шекель", "шекеля", "шекелей"]
|
137
|
+
minor_unit: ["агора", "агоры", "агорот"]
|
138
|
+
symbol: "₪"
|
139
|
+
SEK:
|
140
|
+
major_unit: ["крона", "кроны", "крон"]
|
141
|
+
minor_unit: ["эре", "эре", "эре"]
|
142
|
+
symbol: "kr"
|
143
|
+
NOK:
|
144
|
+
major_unit: ["крона", "кроны", "крон"]
|
145
|
+
minor_unit: ["эре", "эре", "эре"]
|
146
|
+
symbol: "kr"
|
147
|
+
DKK:
|
148
|
+
major_unit: ["крона", "кроны", "крон"]
|
149
|
+
minor_unit: ["эре", "эре", "эре"]
|
150
|
+
symbol: "kr"
|
151
|
+
HUF:
|
152
|
+
major_unit: ["форинт", "форинта", "форинтов"]
|
153
|
+
minor_unit: ["филлер", "филлера", "филлеров"]
|
154
|
+
symbol: "Ft"
|
155
|
+
SAR:
|
156
|
+
major_unit: ["риал", "риала", "риалов"]
|
157
|
+
minor_unit: ["халяла", "халялы", "халялов"]
|
158
|
+
symbol: "﷼"
|
159
|
+
INR:
|
160
|
+
major_unit: ["рупия", "рупии", "рупий"]
|
161
|
+
minor_unit: ["пайса", "пайсы", "пайс"]
|
162
|
+
symbol: "₹"
|
163
|
+
THB:
|
164
|
+
major_unit: ["бат", "бата", "батов"]
|
165
|
+
minor_unit: ["сатанг", "сатанга", "сатангов"]
|
166
|
+
symbol: "฿"
|
167
|
+
VND:
|
168
|
+
major_unit: ["донг", "донга", "донгов"]
|
169
|
+
minor_unit: ["су", "су", "су"]
|
170
|
+
symbol: "₫"
|
171
|
+
IDR:
|
172
|
+
major_unit: ["рупия", "рупии", "рупий"]
|
173
|
+
minor_unit: ["сена", "сены", "сенов"]
|
174
|
+
symbol: "Rp"
|
175
|
+
IRR:
|
176
|
+
major_unit: ["риал", "риала", "риалов"]
|
177
|
+
minor_unit: ["динам", "динама", "динамов"]
|
178
|
+
symbol: "﷼"
|
179
|
+
RSD:
|
180
|
+
major_unit: ["динар", "динара", "динаров"]
|
181
|
+
minor_unit: ["пара", "пары", "пар"]
|
182
|
+
symbol: "дин"
|
183
|
+
MYR:
|
184
|
+
major_unit: ["ринггит", "ринггита", "ринггитов"]
|
185
|
+
minor_unit: ["сен", "сена", "сенов"]
|
186
|
+
symbol: "RM"
|
187
|
+
BDT:
|
188
|
+
major_unit: ["така", "таки", "так"]
|
189
|
+
minor_unit: ["пойша", "пойши", "пойш"]
|
190
|
+
symbol: "৳"
|
191
|
+
PKR:
|
192
|
+
major_unit: ["рупия", "рупии", "рупий"]
|
193
|
+
minor_unit: ["пайса", "пайсы", "пайс"]
|
194
|
+
symbol: "₨"
|
195
|
+
KES:
|
196
|
+
major_unit: ["шиллинг", "шиллинга", "шиллингов"]
|
197
|
+
minor_unit: ["цент", "цента", "центов"]
|
198
|
+
symbol: "Sh"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Num2words
|
4
|
+
class Config
|
5
|
+
attr_accessor :currency_warnings
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
reset!
|
9
|
+
end
|
10
|
+
|
11
|
+
def default_currency(locale = nil, currency = nil)
|
12
|
+
if currency
|
13
|
+
currency = currency.to_s.upcase.to_sym
|
14
|
+
available = available_currencies(locale)
|
15
|
+
|
16
|
+
if available.include?(currency)
|
17
|
+
locale ? @local_currency[locale] = currency : @global_currency = currency
|
18
|
+
elsif currency_warnings
|
19
|
+
warn I18n.t("num2words.warnings.currency_not_available", lang: locale, currency: currency, locale: locale)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
locale ? (@local_currency[locale] || available_currencies(locale).first || @global_currency) : @global_currency
|
24
|
+
end
|
25
|
+
|
26
|
+
def available_currencies(locale = I18n.locale)
|
27
|
+
I18n.t("num2words.currencies", locale: locale).keys.map(&:to_sym)
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset!(locale = nil)
|
31
|
+
return @local_currency.delete(locale) if locale
|
32
|
+
|
33
|
+
@global_currency = available_currencies.first
|
34
|
+
@local_currency = {}
|
35
|
+
@currency_warnings = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.config
|
40
|
+
@config ||= Config.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.reset!
|
44
|
+
config.reset!(locale)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.default_currency(locale = nil, currency = nil)
|
48
|
+
config.default_currency(locale, currency)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.available_currencies(locale = I18n.locale)
|
52
|
+
config.available_currencies(locale)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.currency_warnings
|
56
|
+
config.currency_warnings
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.currency_warnings=(value)
|
60
|
+
config.currency_warnings = value
|
61
|
+
end
|
62
|
+
end
|
data/lib/num2words/converter.rb
CHANGED
@@ -1,22 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "date"
|
4
|
+
require "time"
|
4
5
|
|
5
6
|
module Num2words
|
6
7
|
class Converter
|
7
8
|
class << self
|
8
9
|
def to_words(number, *args, **opts)
|
9
|
-
locale
|
10
|
-
|
11
|
-
|
10
|
+
locale = args[0].is_a?(Symbol) ? args[0] : opts[:locale] || I18n.default_locale
|
11
|
+
type_only = args[1].is_a?(Symbol) ? args[1] : opts[:only]
|
12
|
+
type_short = args[2].is_a?(TrueClass) || args[2].is_a?(FalseClass) ? args[2] : opts[:short] || false
|
13
|
+
|
14
|
+
feminine = opts[:feminine] || false
|
15
|
+
style = opts[:style] || :fraction
|
12
16
|
word_case = opts[:word_case] || :default
|
13
17
|
date_format = opts[:format] || :default
|
18
|
+
|
14
19
|
locale_data = Locales[locale]
|
15
20
|
|
16
21
|
result = case detect_type(number)
|
17
22
|
when :float then to_words_fractional(number, locale, feminine, locale_data, style: style)
|
18
23
|
when :integer then to_words_integer(number, locale, feminine, locale_data)
|
24
|
+
when :datetime then to_words_datetime(number, locale, locale_data, format: date_format, only: type_only, short: type_short)
|
19
25
|
when :date then to_words_date(number, locale, locale_data, format: date_format)
|
26
|
+
when :time then to_words_time(number, locale, locale_data, short: type_short)
|
20
27
|
else nil
|
21
28
|
end
|
22
29
|
|
@@ -26,27 +33,37 @@ module Num2words
|
|
26
33
|
end
|
27
34
|
|
28
35
|
def to_currency(amount, *args, **opts)
|
29
|
-
locale
|
30
|
-
word_case
|
31
|
-
|
36
|
+
locale = args.first.is_a?(Symbol) ? args.first : opts[:locale] || I18n.default_locale
|
37
|
+
word_case = opts[:word_case] || :downcase
|
38
|
+
currency = (opts[:code] || Num2words.default_currency(locale)).to_s.upcase.to_sym
|
39
|
+
|
40
|
+
unless Num2words.available_currencies(locale).include?(currency)
|
41
|
+
warn I18n.t("num2words.warnings.currency_not_available",
|
42
|
+
currency: currency, locale: locale) if Num2words.currency_warnings
|
43
|
+
currency = Num2words.default_currency(locale)
|
44
|
+
end
|
32
45
|
|
33
|
-
|
34
|
-
|
35
|
-
minor_value = minor_str.to_i
|
46
|
+
currency_data = I18n.t("num2words.currencies.#{currency}", locale: locale) or
|
47
|
+
raise ArgumentError, "Currency #{currency} not defined in locale #{locale}"
|
36
48
|
|
37
|
-
|
38
|
-
major_name = pluralize(major_value, *locale_data::MAJOR_UNIT)
|
49
|
+
major_value, minor_value = sprintf('%.2f', amount.abs).split('.').map(&:to_i)
|
39
50
|
|
40
|
-
|
41
|
-
|
51
|
+
parts = [
|
52
|
+
to_words(major_value, locale: locale),
|
53
|
+
pluralize(major_value, *currency_data[:major_unit]),
|
54
|
+
to_words(minor_value, locale: locale, feminine: true),
|
55
|
+
pluralize(minor_value, *currency_data[:minor_unit])
|
56
|
+
]
|
42
57
|
|
43
|
-
|
44
|
-
|
58
|
+
parts.unshift(Locales[locale]::GRAMMAR[:minus] || "minus") if amount.negative?
|
59
|
+
|
60
|
+
apply_case(parts.join(" ").strip, word_case)
|
45
61
|
end
|
46
62
|
|
47
63
|
private
|
48
64
|
|
49
65
|
def pluralize(number, singular, few, plural)
|
66
|
+
number = number.abs
|
50
67
|
return plural if (11..14).include?(number % 100)
|
51
68
|
|
52
69
|
case number % 10
|
@@ -78,10 +95,10 @@ module Num2words
|
|
78
95
|
end
|
79
96
|
|
80
97
|
def to_words_fractional(number, locale, feminine, locale_data, style: :fraction)
|
81
|
-
minus_word
|
98
|
+
minus_word = locale_data::GRAMMAR[:minus] || "minus"
|
82
99
|
conjunction_word = locale_data::GRAMMAR[:conjunction] || "and"
|
83
100
|
default_fraction = locale_data::GRAMMAR[:default_fraction] || "parts"
|
84
|
-
fractions_data
|
101
|
+
fractions_data = locale_data::FRACTIONS || {}
|
85
102
|
|
86
103
|
sign_word = number.negative? ? minus_word : ""
|
87
104
|
|
@@ -91,7 +108,7 @@ module Num2words
|
|
91
108
|
return to_words_integer(integer_value, locale, feminine, locale_data) if fraction_string.to_i.zero?
|
92
109
|
|
93
110
|
fraction_string = fraction_string.sub(/0+\z/, "")
|
94
|
-
numerator
|
111
|
+
numerator = fraction_string.to_i
|
95
112
|
denominator = 10 ** fraction_string.length
|
96
113
|
|
97
114
|
integer_words = to_words_integer(integer_value, locale, feminine, locale_data)
|
@@ -134,15 +151,17 @@ module Num2words
|
|
134
151
|
|
135
152
|
day, month, year = [date.day, date.month, date.year]
|
136
153
|
|
154
|
+
return date.strftime("%d.%m.%Y") if format == :short
|
155
|
+
|
137
156
|
months = locale_data::DATE[:months][format] || locale_data::DATE[:months][:default]
|
138
|
-
template = locale_data::
|
157
|
+
template = locale_data::DATE_TEMPLATE[format] || locale_data::DATE_TEMPLATE[:default]
|
139
158
|
|
140
159
|
raise ArgumentError, "Months not found for locale #{locale}" unless months
|
141
160
|
raise ArgumentError, "Template not found for locale #{locale}" unless template
|
142
161
|
|
143
|
-
day_words
|
162
|
+
day_words = to_words_ordinal(day, locale, format, locale_data, gender: :neuter)
|
144
163
|
month_words = months[month - 1]
|
145
|
-
year_words
|
164
|
+
year_words = to_words_ordinal(year, locale, format, locale_data)
|
146
165
|
|
147
166
|
template % { day: day_words, month: month_words, year: year_words }
|
148
167
|
end
|
@@ -158,9 +177,9 @@ module Num2words
|
|
158
177
|
|
159
178
|
if value > 31
|
160
179
|
thousands = (value / 100) * 100
|
161
|
-
last_two
|
180
|
+
last_two = value % 100
|
162
181
|
|
163
|
-
base_year
|
182
|
+
base_year = to_words_integer(thousands, locale, false, locale_data)
|
164
183
|
last_ordinal = gender_data[last_two - 1] || to_words_integer(last_two, locale, false, locale_data)
|
165
184
|
last_ordinal = to_words_integer(last_two, locale, false, locale_data) if locale == :en
|
166
185
|
|
@@ -170,6 +189,63 @@ module Num2words
|
|
170
189
|
to_words_integer(value, locale, false, locale_data)
|
171
190
|
end
|
172
191
|
|
192
|
+
def to_words_time(time, locale, locale_data, format: :default, short: false)
|
193
|
+
time = Time.parse(time) if time.is_a?(String)
|
194
|
+
|
195
|
+
return time.strftime("%H:%M") if format == :short
|
196
|
+
|
197
|
+
words = locale_data::TIME[:words]
|
198
|
+
template = locale_data::TIME_TEMPLATE
|
199
|
+
|
200
|
+
hours = [
|
201
|
+
to_words_integer(time.hour, locale, false, locale_data),
|
202
|
+
pluralize(time.hour, *words[:hour])
|
203
|
+
].join(" ")
|
204
|
+
minutes = [
|
205
|
+
to_words_integer(time.min, locale, true, locale_data),
|
206
|
+
pluralize(time.min, *words[:minute])
|
207
|
+
].join(" ")
|
208
|
+
seconds = [
|
209
|
+
to_words_integer(time.sec, locale, true, locale_data),
|
210
|
+
pluralize(time.sec, *words[:second])
|
211
|
+
].join(" ")
|
212
|
+
|
213
|
+
format = if short
|
214
|
+
time.min.zero? && time.sec.zero? ? :hours_only : :hours_minutes
|
215
|
+
else
|
216
|
+
format
|
217
|
+
end
|
218
|
+
|
219
|
+
case format
|
220
|
+
when :hours_only
|
221
|
+
template[:hours_only] % { hours: hours }
|
222
|
+
when :hours_minutes
|
223
|
+
template[:hours_minutes] % { hours: hours, minutes: minutes }
|
224
|
+
when :hours_minutes_seconds, :default
|
225
|
+
template[:hours_minutes_seconds] % { hours: hours, minutes: minutes, seconds: seconds }
|
226
|
+
else
|
227
|
+
raise ArgumentError, "Unsupported time format: #{format}"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def to_words_datetime(datetime, locale, locale_data, format: :default, only: nil, short: false)
|
232
|
+
datetime = DateTime.parse(datetime) if datetime.is_a?(String)
|
233
|
+
|
234
|
+
date_format = short && only == :date ? :short : format
|
235
|
+
time_format = short && only == :time ? :short : :default
|
236
|
+
|
237
|
+
date_part = to_words_date(datetime.to_date, locale, locale_data, format: date_format)
|
238
|
+
time_part = to_words_time(datetime.to_time, locale, locale_data, format: time_format, short: short)
|
239
|
+
|
240
|
+
return date_part if only == :date
|
241
|
+
return time_part if only == :time
|
242
|
+
|
243
|
+
return "#{date_part}, #{time_part}" if short
|
244
|
+
|
245
|
+
template = locale_data::DATETIME_TEMPLATE
|
246
|
+
template % { date: date_part, time: time_part }
|
247
|
+
end
|
248
|
+
|
173
249
|
def apply_case(text, word_case)
|
174
250
|
case word_case
|
175
251
|
when :upper then text.upcase
|
@@ -184,18 +260,28 @@ module Num2words
|
|
184
260
|
case value
|
185
261
|
when Integer then :integer
|
186
262
|
when Float then :float
|
187
|
-
when Date
|
263
|
+
when Date then :date
|
264
|
+
when Time then :time
|
265
|
+
when DateTime then :datetime
|
188
266
|
when String
|
189
|
-
return :integer if /\A-?\d+\z
|
190
|
-
return :float if /\A-?\d+\.\d+\z
|
267
|
+
return :integer if value.match?(/\A-?\d+\z/)
|
268
|
+
return :float if value.match?(/\A-?\d+\.\d+\z/)
|
269
|
+
return :time if value.match?(/\A\d{1,2}:\d{2}(:\d{2})?\z/)
|
270
|
+
|
271
|
+
# Форматы даты
|
272
|
+
return :date if value.match?(/\A\d{1,2}[.\-]\d{1,2}[.\-]\d{2,4}\z/)
|
273
|
+
return :date if value.match?(/\A\d{4}-\d{2}-\d{2}\z/)
|
274
|
+
return :datetime if value.match?(/\A\d{1,2}[.\-]\d{1,2}[.\-]\d{2,4}\s+\d{1,2}:\d{2}(:\d{2})?\z/)
|
275
|
+
return :datetime if value.match?(/\A\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2})?([.,]\d+)?(Z|[+\-]\d{2}:?\d{2})?\z/)
|
191
276
|
|
192
277
|
begin
|
193
|
-
|
194
|
-
:date
|
278
|
+
date_time = DateTime.parse(value)
|
279
|
+
(date_time.hour != 0 || date_time.min != 0 || date_time.sec != 0) ? :datetime : :date
|
195
280
|
rescue ArgumentError
|
196
281
|
:string
|
197
282
|
end
|
198
|
-
else
|
283
|
+
else
|
284
|
+
:unknown
|
199
285
|
end
|
200
286
|
end
|
201
287
|
end
|
data/lib/num2words/core_ext.rb
CHANGED
@@ -31,3 +31,15 @@ class Date
|
|
31
31
|
Num2words::Converter.to_words(self.strftime("%d.%m.%Y"), *args, **opts)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
class Time
|
36
|
+
def to_words(*args, **opts)
|
37
|
+
Num2words::Converter.to_words(self.strftime("%H:%M:%S"), *args, **opts)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class DateTime
|
42
|
+
def to_words(*args, **opts)
|
43
|
+
Num2words::Converter.to_words(self.strftime("%d.%m.%Y %H:%M:%S"), *args, **opts)
|
44
|
+
end
|
45
|
+
end
|
data/lib/num2words/locales/ar.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :ar)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :ar)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :ar)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :ar)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :ar)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :ar)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :ar)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :ar)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :ar)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :ar)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :ar, AR
|
data/lib/num2words/locales/be.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :be)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :be)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :be)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :be)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :be)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :be)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :be)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :be)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :be)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :be)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :be, BE
|
data/lib/num2words/locales/bg.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :bg)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :bg)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :bg)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :bg)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :bg)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :bg)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :bg)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :bg)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :bg)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :bg)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :bg, BG
|
data/lib/num2words/locales/bn.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :bn)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :bn)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :bn)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :bn)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :bn)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :bn)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :bn)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :bn)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :bn)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :bn)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :bn, BN
|
data/lib/num2words/locales/cs.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :cs)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :cs)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :cs)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :cs)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :cs)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :cs)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :cs)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :cs)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :cs)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :cs)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :cs, CS
|
data/lib/num2words/locales/da.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :da)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :da)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :da)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :da)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :da)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :da)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :da)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :da)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :da)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :da)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :da, DA
|
data/lib/num2words/locales/de.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :de)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :de)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :de)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :de)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :de)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :de)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :de)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :de)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :de)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :de)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :de, DE
|
data/lib/num2words/locales/el.rb
CHANGED
@@ -10,8 +10,16 @@ module Num2words
|
|
10
10
|
HUNDREDS = I18n.t("num2words.hundreds", locale: :el)
|
11
11
|
SCALES = I18n.t("num2words.scales", locale: :el)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
FRACTIONS = I18n.t("num2words.fractions", locale: :el)
|
14
|
+
GRAMMAR = I18n.t("num2words.grammar", locale: :el)
|
15
|
+
|
16
|
+
DATE = I18n.t("num2words.date", locale: :el)
|
17
|
+
DATE_TEMPLATE = I18n.t("num2words.date.template", locale: :el)
|
18
|
+
TIME = I18n.t("num2words.time", locale: :el)
|
19
|
+
TIME_TEMPLATE = I18n.t("num2words.time.template", locale: :el)
|
20
|
+
DATETIME_TEMPLATE = I18n.t("num2words.datetime.template", locale: :el)
|
21
|
+
|
22
|
+
ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :el)
|
15
23
|
end
|
16
24
|
|
17
25
|
register :el, EL
|