1 package kam
2
3 import (
4 "math"
5 "strconv"
6 "time"
7
8 "github.com/go-playground/locales"
9 "github.com/go-playground/locales/currency"
10 )
11
12 type kam struct {
13 locale string
14 pluralsCardinal []locales.PluralRule
15 pluralsOrdinal []locales.PluralRule
16 pluralsRange []locales.PluralRule
17 decimal string
18 group string
19 minus string
20 percent string
21 perMille string
22 timeSeparator string
23 inifinity string
24 currencies []string
25 currencyNegativePrefix string
26 currencyNegativeSuffix string
27 monthsAbbreviated []string
28 monthsNarrow []string
29 monthsWide []string
30 daysAbbreviated []string
31 daysNarrow []string
32 daysShort []string
33 daysWide []string
34 periodsAbbreviated []string
35 periodsNarrow []string
36 periodsShort []string
37 periodsWide []string
38 erasAbbreviated []string
39 erasNarrow []string
40 erasWide []string
41 timezones map[string]string
42 }
43
44
45 func New() locales.Translator {
46 return &kam{
47 locale: "kam",
48 pluralsCardinal: nil,
49 pluralsOrdinal: nil,
50 pluralsRange: nil,
51 timeSeparator: ":",
52 currencies: []string{"ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK", "AON", "AOR", "ARA", "ARL", "ARM", "ARP", "ARS", "ATS", "AUD", "AWG", "AZM", "AZN", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", "BEL", "BGL", "BGM", "BGN", "BGO", "BHD", "BIF", "BMD", "BND", "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", "BSD", "BTN", "BUK", "BWP", "BYB", "BYN", "BYR", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CLE", "CLF", "CLP", "CNH", "CNX", "CNY", "COP", "COU", "CRC", "CSD", "CSK", "CUC", "CUP", "CVE", "CYP", "CZK", "DDM", "DEM", "DJF", "DKK", "DOP", "DZD", "ECS", "ECV", "EEK", "EGP", "ERN", "ESA", "ESB", "ESP", "ETB", "EUR", "FIM", "FJD", "FKP", "FRF", "GBP", "GEK", "GEL", "GHC", "GHS", "GIP", "GMD", "GNF", "GNS", "GQE", "GRD", "GTQ", "GWE", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IDR", "IEP", "ILP", "ILR", "ILS", "INR", "IQD", "IRR", "ISJ", "ISK", "ITL", "JMD", "JOD", "JPY", "Ksh", "KGS", "KHR", "KMF", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LTT", "LUC", "LUF", "LUL", "LVL", "LVR", "LYD", "MAD", "MAF", "MCF", "MDC", "MDL", "MGA", "MGF", "MKD", "MKN", "MLF", "MMK", "MNT", "MOP", "MRO", "MRU", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MXN", "MXP", "MXV", "MYR", "MZE", "MZM", "MZN", "NAD", "NGN", "NIC", "NIO", "NLG", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "RUB", "RUR", "RWF", "SAR", "SBD", "SCR", "SDD", "SDG", "SDP", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRD", "SRG", "SSP", "STD", "STN", "SUR", "SVC", "SYP", "SZL", "THB", "TJR", "TJS", "TMM", "TMT", "TND", "TOP", "TPE", "TRL", "TRY", "TTD", "TWD", "TZS", "UAH", "UAK", "UGS", "UGX", "USD", "USN", "USS", "UYI", "UYP", "UYU", "UYW", "UZS", "VEB", "VEF", "VES", "VND", "VNN", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XEU", "XFO", "XFU", "XOF", "XPD", "XPF", "XPT", "XRE", "XSU", "XTS", "XUA", "XXX", "YDD", "YER", "YUD", "YUM", "YUN", "YUR", "ZAL", "ZAR", "ZMK", "ZMW", "ZRN", "ZRZ", "ZWD", "ZWL", "ZWR"},
53 currencyNegativePrefix: "(",
54 currencyNegativeSuffix: ")",
55 monthsAbbreviated: []string{"", "Mbe", "Kel", "Ktũ", "Kan", "Ktn", "Tha", "Moo", "Nya", "Knd", "Ĩku", "Ĩkm", "Ĩkl"},
56 monthsNarrow: []string{"", "M", "K", "K", "K", "K", "T", "M", "N", "K", "Ĩ", "Ĩ", "Ĩ"},
57 monthsWide: []string{"", "Mwai wa mbee", "Mwai wa kelĩ", "Mwai wa katatũ", "Mwai wa kana", "Mwai wa katano", "Mwai wa thanthatũ", "Mwai wa muonza", "Mwai wa nyaanya", "Mwai wa kenda", "Mwai wa ĩkumi", "Mwai wa ĩkumi na ĩmwe", "Mwai wa ĩkumi na ilĩ"},
58 daysAbbreviated: []string{"Wky", "Wkw", "Wkl", "Wtũ", "Wkn", "Wtn", "Wth"},
59 daysNarrow: []string{"Y", "W", "E", "A", "A", "A", "A"},
60 daysWide: []string{"Wa kyumwa", "Wa kwambĩlĩlya", "Wa kelĩ", "Wa katatũ", "Wa kana", "Wa katano", "Wa thanthatũ"},
61 periodsAbbreviated: []string{"Ĩyakwakya", "Ĩyawĩoo"},
62 periodsWide: []string{"Ĩyakwakya", "Ĩyawĩoo"},
63 erasAbbreviated: []string{"MY", "IY"},
64 erasNarrow: []string{"", ""},
65 erasWide: []string{"Mbee wa Yesũ", "Ĩtina wa Yesũ"},
66 timezones: map[string]string{"ACDT": "ACDT", "ACST": "ACST", "ACWDT": "ACWDT", "ACWST": "ACWST", "ADT": "ADT", "AEDT": "AEDT", "AEST": "AEST", "AKDT": "AKDT", "AKST": "AKST", "ARST": "ARST", "ART": "ART", "AST": "AST", "AWDT": "AWDT", "AWST": "AWST", "BOT": "BOT", "BT": "BT", "CAT": "CAT", "CDT": "CDT", "CHADT": "CHADT", "CHAST": "CHAST", "CLST": "CLST", "CLT": "CLT", "COST": "COST", "COT": "COT", "CST": "CST", "ChST": "ChST", "EAT": "EAT", "ECT": "ECT", "EDT": "EDT", "EST": "EST", "GFT": "GFT", "GMT": "GMT", "GST": "GST", "GYT": "GYT", "HADT": "HADT", "HAST": "HAST", "HAT": "HAT", "HECU": "HECU", "HEEG": "HEEG", "HENOMX": "HENOMX", "HEOG": "HEOG", "HEPM": "HEPM", "HEPMX": "HEPMX", "HKST": "HKST", "HKT": "HKT", "HNCU": "HNCU", "HNEG": "HNEG", "HNNOMX": "HNNOMX", "HNOG": "HNOG", "HNPM": "HNPM", "HNPMX": "HNPMX", "HNT": "HNT", "IST": "IST", "JDT": "JDT", "JST": "JST", "LHDT": "LHDT", "LHST": "LHST", "MDT": "MDT", "MESZ": "MESZ", "MEZ": "MEZ", "MST": "MST", "MYT": "MYT", "NZDT": "NZDT", "NZST": "NZST", "OESZ": "OESZ", "OEZ": "OEZ", "PDT": "PDT", "PST": "PST", "SAST": "SAST", "SGT": "SGT", "SRT": "SRT", "TMST": "TMST", "TMT": "TMT", "UYST": "UYST", "UYT": "UYT", "VET": "VET", "WARST": "WARST", "WART": "WART", "WAST": "WAST", "WAT": "WAT", "WESZ": "WESZ", "WEZ": "WEZ", "WIB": "WIB", "WIT": "WIT", "WITA": "WITA", "∅∅∅": "∅∅∅"},
67 }
68 }
69
70
71 func (kam *kam) Locale() string {
72 return kam.locale
73 }
74
75
76 func (kam *kam) PluralsCardinal() []locales.PluralRule {
77 return kam.pluralsCardinal
78 }
79
80
81 func (kam *kam) PluralsOrdinal() []locales.PluralRule {
82 return kam.pluralsOrdinal
83 }
84
85
86 func (kam *kam) PluralsRange() []locales.PluralRule {
87 return kam.pluralsRange
88 }
89
90
91 func (kam *kam) CardinalPluralRule(num float64, v uint64) locales.PluralRule {
92 return locales.PluralRuleUnknown
93 }
94
95
96 func (kam *kam) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
97 return locales.PluralRuleUnknown
98 }
99
100
101 func (kam *kam) RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) locales.PluralRule {
102 return locales.PluralRuleUnknown
103 }
104
105
106 func (kam *kam) MonthAbbreviated(month time.Month) string {
107 return kam.monthsAbbreviated[month]
108 }
109
110
111 func (kam *kam) MonthsAbbreviated() []string {
112 return kam.monthsAbbreviated[1:]
113 }
114
115
116 func (kam *kam) MonthNarrow(month time.Month) string {
117 return kam.monthsNarrow[month]
118 }
119
120
121 func (kam *kam) MonthsNarrow() []string {
122 return kam.monthsNarrow[1:]
123 }
124
125
126 func (kam *kam) MonthWide(month time.Month) string {
127 return kam.monthsWide[month]
128 }
129
130
131 func (kam *kam) MonthsWide() []string {
132 return kam.monthsWide[1:]
133 }
134
135
136 func (kam *kam) WeekdayAbbreviated(weekday time.Weekday) string {
137 return kam.daysAbbreviated[weekday]
138 }
139
140
141 func (kam *kam) WeekdaysAbbreviated() []string {
142 return kam.daysAbbreviated
143 }
144
145
146 func (kam *kam) WeekdayNarrow(weekday time.Weekday) string {
147 return kam.daysNarrow[weekday]
148 }
149
150
151 func (kam *kam) WeekdaysNarrow() []string {
152 return kam.daysNarrow
153 }
154
155
156 func (kam *kam) WeekdayShort(weekday time.Weekday) string {
157 return kam.daysShort[weekday]
158 }
159
160
161 func (kam *kam) WeekdaysShort() []string {
162 return kam.daysShort
163 }
164
165
166 func (kam *kam) WeekdayWide(weekday time.Weekday) string {
167 return kam.daysWide[weekday]
168 }
169
170
171 func (kam *kam) WeekdaysWide() []string {
172 return kam.daysWide
173 }
174
175
176 func (kam *kam) Decimal() string {
177 return kam.decimal
178 }
179
180
181 func (kam *kam) Group() string {
182 return kam.group
183 }
184
185
186 func (kam *kam) Minus() string {
187 return kam.minus
188 }
189
190
191 func (kam *kam) FmtNumber(num float64, v uint64) string {
192
193 return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
194 }
195
196
197
198 func (kam *kam) FmtPercent(num float64, v uint64) string {
199 return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
200 }
201
202
203 func (kam *kam) FmtCurrency(num float64, v uint64, currency currency.Type) string {
204
205 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
206 symbol := kam.currencies[currency]
207 l := len(s) + len(symbol) + 0
208 count := 0
209 inWhole := v == 0
210 b := make([]byte, 0, l)
211
212 for i := len(s) - 1; i >= 0; i-- {
213
214 if s[i] == '.' {
215 b = append(b, kam.decimal[0])
216 inWhole = true
217 continue
218 }
219
220 if inWhole {
221 if count == 3 {
222 b = append(b, kam.group[0])
223 count = 1
224 } else {
225 count++
226 }
227 }
228
229 b = append(b, s[i])
230 }
231
232 for j := len(symbol) - 1; j >= 0; j-- {
233 b = append(b, symbol[j])
234 }
235
236 if num < 0 {
237 b = append(b, kam.minus[0])
238 }
239
240
241 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
242 b[i], b[j] = b[j], b[i]
243 }
244
245 if int(v) < 2 {
246
247 if v == 0 {
248 b = append(b, kam.decimal...)
249 }
250
251 for i := 0; i < 2-int(v); i++ {
252 b = append(b, '0')
253 }
254 }
255
256 return string(b)
257 }
258
259
260
261 func (kam *kam) FmtAccounting(num float64, v uint64, currency currency.Type) string {
262
263 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
264 symbol := kam.currencies[currency]
265 l := len(s) + len(symbol) + 2
266 count := 0
267 inWhole := v == 0
268 b := make([]byte, 0, l)
269
270 for i := len(s) - 1; i >= 0; i-- {
271
272 if s[i] == '.' {
273 b = append(b, kam.decimal[0])
274 inWhole = true
275 continue
276 }
277
278 if inWhole {
279 if count == 3 {
280 b = append(b, kam.group[0])
281 count = 1
282 } else {
283 count++
284 }
285 }
286
287 b = append(b, s[i])
288 }
289
290 if num < 0 {
291
292 for j := len(symbol) - 1; j >= 0; j-- {
293 b = append(b, symbol[j])
294 }
295
296 b = append(b, kam.currencyNegativePrefix[0])
297
298 } else {
299
300 for j := len(symbol) - 1; j >= 0; j-- {
301 b = append(b, symbol[j])
302 }
303
304 }
305
306
307 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
308 b[i], b[j] = b[j], b[i]
309 }
310
311 if int(v) < 2 {
312
313 if v == 0 {
314 b = append(b, kam.decimal...)
315 }
316
317 for i := 0; i < 2-int(v); i++ {
318 b = append(b, '0')
319 }
320 }
321
322 if num < 0 {
323 b = append(b, kam.currencyNegativeSuffix...)
324 }
325
326 return string(b)
327 }
328
329
330 func (kam *kam) FmtDateShort(t time.Time) string {
331
332 b := make([]byte, 0, 32)
333
334 if t.Day() < 10 {
335 b = append(b, '0')
336 }
337
338 b = strconv.AppendInt(b, int64(t.Day()), 10)
339 b = append(b, []byte{0x2f}...)
340
341 if t.Month() < 10 {
342 b = append(b, '0')
343 }
344
345 b = strconv.AppendInt(b, int64(t.Month()), 10)
346
347 b = append(b, []byte{0x2f}...)
348
349 if t.Year() > 0 {
350 b = strconv.AppendInt(b, int64(t.Year()), 10)
351 } else {
352 b = strconv.AppendInt(b, int64(-t.Year()), 10)
353 }
354
355 return string(b)
356 }
357
358
359 func (kam *kam) FmtDateMedium(t time.Time) string {
360
361 b := make([]byte, 0, 32)
362
363 b = strconv.AppendInt(b, int64(t.Day()), 10)
364 b = append(b, []byte{0x20}...)
365 b = append(b, kam.monthsAbbreviated[t.Month()]...)
366 b = append(b, []byte{0x20}...)
367
368 if t.Year() > 0 {
369 b = strconv.AppendInt(b, int64(t.Year()), 10)
370 } else {
371 b = strconv.AppendInt(b, int64(-t.Year()), 10)
372 }
373
374 return string(b)
375 }
376
377
378 func (kam *kam) FmtDateLong(t time.Time) string {
379
380 b := make([]byte, 0, 32)
381
382 b = strconv.AppendInt(b, int64(t.Day()), 10)
383 b = append(b, []byte{0x20}...)
384 b = append(b, kam.monthsWide[t.Month()]...)
385 b = append(b, []byte{0x20}...)
386
387 if t.Year() > 0 {
388 b = strconv.AppendInt(b, int64(t.Year()), 10)
389 } else {
390 b = strconv.AppendInt(b, int64(-t.Year()), 10)
391 }
392
393 return string(b)
394 }
395
396
397 func (kam *kam) FmtDateFull(t time.Time) string {
398
399 b := make([]byte, 0, 32)
400
401 b = append(b, kam.daysWide[t.Weekday()]...)
402 b = append(b, []byte{0x2c, 0x20}...)
403 b = strconv.AppendInt(b, int64(t.Day()), 10)
404 b = append(b, []byte{0x20}...)
405 b = append(b, kam.monthsWide[t.Month()]...)
406 b = append(b, []byte{0x20}...)
407
408 if t.Year() > 0 {
409 b = strconv.AppendInt(b, int64(t.Year()), 10)
410 } else {
411 b = strconv.AppendInt(b, int64(-t.Year()), 10)
412 }
413
414 return string(b)
415 }
416
417
418 func (kam *kam) FmtTimeShort(t time.Time) string {
419
420 b := make([]byte, 0, 32)
421
422 if t.Hour() < 10 {
423 b = append(b, '0')
424 }
425
426 b = strconv.AppendInt(b, int64(t.Hour()), 10)
427 b = append(b, kam.timeSeparator...)
428
429 if t.Minute() < 10 {
430 b = append(b, '0')
431 }
432
433 b = strconv.AppendInt(b, int64(t.Minute()), 10)
434
435 return string(b)
436 }
437
438
439 func (kam *kam) FmtTimeMedium(t time.Time) string {
440
441 b := make([]byte, 0, 32)
442
443 if t.Hour() < 10 {
444 b = append(b, '0')
445 }
446
447 b = strconv.AppendInt(b, int64(t.Hour()), 10)
448 b = append(b, kam.timeSeparator...)
449
450 if t.Minute() < 10 {
451 b = append(b, '0')
452 }
453
454 b = strconv.AppendInt(b, int64(t.Minute()), 10)
455 b = append(b, kam.timeSeparator...)
456
457 if t.Second() < 10 {
458 b = append(b, '0')
459 }
460
461 b = strconv.AppendInt(b, int64(t.Second()), 10)
462
463 return string(b)
464 }
465
466
467 func (kam *kam) FmtTimeLong(t time.Time) string {
468
469 b := make([]byte, 0, 32)
470
471 if t.Hour() < 10 {
472 b = append(b, '0')
473 }
474
475 b = strconv.AppendInt(b, int64(t.Hour()), 10)
476 b = append(b, kam.timeSeparator...)
477
478 if t.Minute() < 10 {
479 b = append(b, '0')
480 }
481
482 b = strconv.AppendInt(b, int64(t.Minute()), 10)
483 b = append(b, kam.timeSeparator...)
484
485 if t.Second() < 10 {
486 b = append(b, '0')
487 }
488
489 b = strconv.AppendInt(b, int64(t.Second()), 10)
490 b = append(b, []byte{0x20}...)
491
492 tz, _ := t.Zone()
493 b = append(b, tz...)
494
495 return string(b)
496 }
497
498
499 func (kam *kam) FmtTimeFull(t time.Time) string {
500
501 b := make([]byte, 0, 32)
502
503 if t.Hour() < 10 {
504 b = append(b, '0')
505 }
506
507 b = strconv.AppendInt(b, int64(t.Hour()), 10)
508 b = append(b, kam.timeSeparator...)
509
510 if t.Minute() < 10 {
511 b = append(b, '0')
512 }
513
514 b = strconv.AppendInt(b, int64(t.Minute()), 10)
515 b = append(b, kam.timeSeparator...)
516
517 if t.Second() < 10 {
518 b = append(b, '0')
519 }
520
521 b = strconv.AppendInt(b, int64(t.Second()), 10)
522 b = append(b, []byte{0x20}...)
523
524 tz, _ := t.Zone()
525
526 if btz, ok := kam.timezones[tz]; ok {
527 b = append(b, btz...)
528 } else {
529 b = append(b, tz...)
530 }
531
532 return string(b)
533 }
534
View as plain text