1 package ia
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 ia 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 currencyPositivePrefix string
26 currencyNegativePrefix string
27 currencyNegativeSuffix string
28 monthsAbbreviated []string
29 monthsNarrow []string
30 monthsWide []string
31 daysAbbreviated []string
32 daysNarrow []string
33 daysShort []string
34 daysWide []string
35 periodsAbbreviated []string
36 periodsNarrow []string
37 periodsShort []string
38 periodsWide []string
39 erasAbbreviated []string
40 erasNarrow []string
41 erasWide []string
42 timezones map[string]string
43 }
44
45
46 func New() locales.Translator {
47 return &ia{
48 locale: "ia",
49 pluralsCardinal: []locales.PluralRule{2, 6},
50 pluralsOrdinal: []locales.PluralRule{6},
51 pluralsRange: []locales.PluralRule{6},
52 decimal: ",",
53 group: ".",
54 minus: "-",
55 percent: "%",
56 perMille: "‰",
57 timeSeparator: ":",
58 inifinity: "∞",
59 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", "KES", "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", "ƒ", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "₽", "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"},
60 currencyPositivePrefix: " ",
61 currencyNegativePrefix: "( ",
62 currencyNegativeSuffix: ")",
63 monthsAbbreviated: []string{"", "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "oct", "nov", "dec"},
64 monthsNarrow: []string{"", "j", "f", "m", "a", "m", "j", "j", "a", "s", "o", "n", "d"},
65 monthsWide: []string{"", "januario", "februario", "martio", "april", "maio", "junio", "julio", "augusto", "septembre", "octobre", "novembre", "decembre"},
66 daysAbbreviated: []string{"dom", "lun", "mar", "mer", "jov", "ven", "sab"},
67 daysNarrow: []string{"d", "l", "m", "m", "j", "v", "s"},
68 daysShort: []string{"do", "lu", "ma", "me", "jo", "ve", "sa"},
69 daysWide: []string{"dominica", "lunedi", "martedi", "mercuridi", "jovedi", "venerdi", "sabbato"},
70 periodsAbbreviated: []string{"AM", "PM"},
71 periodsNarrow: []string{"AM", "PM"},
72 periodsWide: []string{"AM", "PM"},
73 erasAbbreviated: []string{"a.Chr.", "p.Chr."},
74 erasNarrow: []string{"", ""},
75 erasWide: []string{"ante Christo", "post Christo"},
76 timezones: map[string]string{"ACDT": "ACDT", "ACST": "ACST", "ACWDT": "ACWDT", "ACWST": "ACWST", "ADT": "hora estive atlantic", "AEDT": "AEDT", "AEST": "AEST", "AKDT": "hora estive de Alaska", "AKST": "hora normal de Alaska", "ARST": "ARST", "ART": "ART", "AST": "hora normal atlantic", "AWDT": "AWDT", "AWST": "AWST", "BOT": "BOT", "BT": "BT", "CAT": "CAT", "CDT": "hora estive central", "CHADT": "CHADT", "CHAST": "CHAST", "CLST": "CLST", "CLT": "CLT", "COST": "COST", "COT": "COT", "CST": "hora normal central", "ChST": "ChST", "EAT": "EAT", "ECT": "ECT", "EDT": "hora estive del est", "EST": "hora normal del est", "GFT": "GFT", "GMT": "hora medie de Greenwich", "GST": "GST", "GYT": "GYT", "HADT": "hora estive de Hawaii-Aleutianas", "HAST": "hora normal de Hawaii-Aleutianas", "HAT": "hora estive de Terranova", "HECU": "hora estive de Cuba", "HEEG": "hora estive de Groenlandia oriental", "HENOMX": "hora estive del nordwest de Mexico", "HEOG": "hora estive de Groenlandia occidental", "HEPM": "hora estive de Saint-Pierre e Miquelon", "HEPMX": "hora estive del Pacifico mexican", "HKST": "HKST", "HKT": "HKT", "HNCU": "hora normal de Cuba", "HNEG": "hora normal de Groenlandia oriental", "HNNOMX": "hora normal del nordwest de Mexico", "HNOG": "hora normal de Groenlandia occidental", "HNPM": "hora normal de Saint-Pierre e Miquelon", "HNPMX": "hora normal del Pacifico mexican", "HNT": "hora normal de Terranova", "IST": "IST", "JDT": "JDT", "JST": "JST", "LHDT": "LHDT", "LHST": "LHST", "MDT": "hora estive del montanias", "MESZ": "hora estive de Europa central", "MEZ": "hora normal de Europa central", "MST": "hora normal del montanias", "MYT": "MYT", "NZDT": "NZDT", "NZST": "NZST", "OESZ": "hora estive de Europa oriental", "OEZ": "hora normal de Europa oriental", "PDT": "hora estive pacific", "PST": "hora normal pacific", "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": "hora estive de Europa occidental", "WEZ": "hora normal de Europa occidental", "WIB": "WIB", "WIT": "WIT", "WITA": "WITA", "∅∅∅": "∅∅∅"},
77 }
78 }
79
80
81 func (ia *ia) Locale() string {
82 return ia.locale
83 }
84
85
86 func (ia *ia) PluralsCardinal() []locales.PluralRule {
87 return ia.pluralsCardinal
88 }
89
90
91 func (ia *ia) PluralsOrdinal() []locales.PluralRule {
92 return ia.pluralsOrdinal
93 }
94
95
96 func (ia *ia) PluralsRange() []locales.PluralRule {
97 return ia.pluralsRange
98 }
99
100
101 func (ia *ia) CardinalPluralRule(num float64, v uint64) locales.PluralRule {
102
103 n := math.Abs(num)
104 i := int64(n)
105
106 if i == 1 && v == 0 {
107 return locales.PluralRuleOne
108 }
109
110 return locales.PluralRuleOther
111 }
112
113
114 func (ia *ia) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
115 return locales.PluralRuleOther
116 }
117
118
119 func (ia *ia) RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) locales.PluralRule {
120 return locales.PluralRuleOther
121 }
122
123
124 func (ia *ia) MonthAbbreviated(month time.Month) string {
125 return ia.monthsAbbreviated[month]
126 }
127
128
129 func (ia *ia) MonthsAbbreviated() []string {
130 return ia.monthsAbbreviated[1:]
131 }
132
133
134 func (ia *ia) MonthNarrow(month time.Month) string {
135 return ia.monthsNarrow[month]
136 }
137
138
139 func (ia *ia) MonthsNarrow() []string {
140 return ia.monthsNarrow[1:]
141 }
142
143
144 func (ia *ia) MonthWide(month time.Month) string {
145 return ia.monthsWide[month]
146 }
147
148
149 func (ia *ia) MonthsWide() []string {
150 return ia.monthsWide[1:]
151 }
152
153
154 func (ia *ia) WeekdayAbbreviated(weekday time.Weekday) string {
155 return ia.daysAbbreviated[weekday]
156 }
157
158
159 func (ia *ia) WeekdaysAbbreviated() []string {
160 return ia.daysAbbreviated
161 }
162
163
164 func (ia *ia) WeekdayNarrow(weekday time.Weekday) string {
165 return ia.daysNarrow[weekday]
166 }
167
168
169 func (ia *ia) WeekdaysNarrow() []string {
170 return ia.daysNarrow
171 }
172
173
174 func (ia *ia) WeekdayShort(weekday time.Weekday) string {
175 return ia.daysShort[weekday]
176 }
177
178
179 func (ia *ia) WeekdaysShort() []string {
180 return ia.daysShort
181 }
182
183
184 func (ia *ia) WeekdayWide(weekday time.Weekday) string {
185 return ia.daysWide[weekday]
186 }
187
188
189 func (ia *ia) WeekdaysWide() []string {
190 return ia.daysWide
191 }
192
193
194 func (ia *ia) Decimal() string {
195 return ia.decimal
196 }
197
198
199 func (ia *ia) Group() string {
200 return ia.group
201 }
202
203
204 func (ia *ia) Minus() string {
205 return ia.minus
206 }
207
208
209 func (ia *ia) FmtNumber(num float64, v uint64) string {
210
211 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
212 l := len(s) + 2 + 1*len(s[:len(s)-int(v)-1])/3
213 count := 0
214 inWhole := v == 0
215 b := make([]byte, 0, l)
216
217 for i := len(s) - 1; i >= 0; i-- {
218
219 if s[i] == '.' {
220 b = append(b, ia.decimal[0])
221 inWhole = true
222 continue
223 }
224
225 if inWhole {
226 if count == 3 {
227 b = append(b, ia.group[0])
228 count = 1
229 } else {
230 count++
231 }
232 }
233
234 b = append(b, s[i])
235 }
236
237 if num < 0 {
238 b = append(b, ia.minus[0])
239 }
240
241
242 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
243 b[i], b[j] = b[j], b[i]
244 }
245
246 return string(b)
247 }
248
249
250
251 func (ia *ia) FmtPercent(num float64, v uint64) string {
252 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
253 l := len(s) + 3
254 b := make([]byte, 0, l)
255
256 for i := len(s) - 1; i >= 0; i-- {
257
258 if s[i] == '.' {
259 b = append(b, ia.decimal[0])
260 continue
261 }
262
263 b = append(b, s[i])
264 }
265
266 if num < 0 {
267 b = append(b, ia.minus[0])
268 }
269
270
271 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
272 b[i], b[j] = b[j], b[i]
273 }
274
275 b = append(b, ia.percent...)
276
277 return string(b)
278 }
279
280
281 func (ia *ia) FmtCurrency(num float64, v uint64, currency currency.Type) string {
282
283 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
284 symbol := ia.currencies[currency]
285 l := len(s) + len(symbol) + 4 + 1*len(s[:len(s)-int(v)-1])/3
286 count := 0
287 inWhole := v == 0
288 b := make([]byte, 0, l)
289
290 for i := len(s) - 1; i >= 0; i-- {
291
292 if s[i] == '.' {
293 b = append(b, ia.decimal[0])
294 inWhole = true
295 continue
296 }
297
298 if inWhole {
299 if count == 3 {
300 b = append(b, ia.group[0])
301 count = 1
302 } else {
303 count++
304 }
305 }
306
307 b = append(b, s[i])
308 }
309
310 for j := len(symbol) - 1; j >= 0; j-- {
311 b = append(b, symbol[j])
312 }
313
314 for j := len(ia.currencyPositivePrefix) - 1; j >= 0; j-- {
315 b = append(b, ia.currencyPositivePrefix[j])
316 }
317
318 if num < 0 {
319 b = append(b, ia.minus[0])
320 }
321
322
323 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
324 b[i], b[j] = b[j], b[i]
325 }
326
327 if int(v) < 2 {
328
329 if v == 0 {
330 b = append(b, ia.decimal...)
331 }
332
333 for i := 0; i < 2-int(v); i++ {
334 b = append(b, '0')
335 }
336 }
337
338 return string(b)
339 }
340
341
342
343 func (ia *ia) FmtAccounting(num float64, v uint64, currency currency.Type) string {
344
345 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
346 symbol := ia.currencies[currency]
347 l := len(s) + len(symbol) + 6 + 1*len(s[:len(s)-int(v)-1])/3
348 count := 0
349 inWhole := v == 0
350 b := make([]byte, 0, l)
351
352 for i := len(s) - 1; i >= 0; i-- {
353
354 if s[i] == '.' {
355 b = append(b, ia.decimal[0])
356 inWhole = true
357 continue
358 }
359
360 if inWhole {
361 if count == 3 {
362 b = append(b, ia.group[0])
363 count = 1
364 } else {
365 count++
366 }
367 }
368
369 b = append(b, s[i])
370 }
371
372 if num < 0 {
373
374 for j := len(symbol) - 1; j >= 0; j-- {
375 b = append(b, symbol[j])
376 }
377
378 for j := len(ia.currencyNegativePrefix) - 1; j >= 0; j-- {
379 b = append(b, ia.currencyNegativePrefix[j])
380 }
381
382 } else {
383
384 for j := len(symbol) - 1; j >= 0; j-- {
385 b = append(b, symbol[j])
386 }
387
388 for j := len(ia.currencyPositivePrefix) - 1; j >= 0; j-- {
389 b = append(b, ia.currencyPositivePrefix[j])
390 }
391
392 }
393
394
395 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
396 b[i], b[j] = b[j], b[i]
397 }
398
399 if int(v) < 2 {
400
401 if v == 0 {
402 b = append(b, ia.decimal...)
403 }
404
405 for i := 0; i < 2-int(v); i++ {
406 b = append(b, '0')
407 }
408 }
409
410 if num < 0 {
411 b = append(b, ia.currencyNegativeSuffix...)
412 }
413
414 return string(b)
415 }
416
417
418 func (ia *ia) FmtDateShort(t time.Time) string {
419
420 b := make([]byte, 0, 32)
421
422 if t.Day() < 10 {
423 b = append(b, '0')
424 }
425
426 b = strconv.AppendInt(b, int64(t.Day()), 10)
427 b = append(b, []byte{0x2d}...)
428
429 if t.Month() < 10 {
430 b = append(b, '0')
431 }
432
433 b = strconv.AppendInt(b, int64(t.Month()), 10)
434
435 b = append(b, []byte{0x2d}...)
436
437 if t.Year() > 0 {
438 b = strconv.AppendInt(b, int64(t.Year()), 10)
439 } else {
440 b = strconv.AppendInt(b, int64(-t.Year()), 10)
441 }
442
443 return string(b)
444 }
445
446
447 func (ia *ia) FmtDateMedium(t time.Time) string {
448
449 b := make([]byte, 0, 32)
450
451 b = strconv.AppendInt(b, int64(t.Day()), 10)
452 b = append(b, []byte{0x20}...)
453 b = append(b, ia.monthsAbbreviated[t.Month()]...)
454 b = append(b, []byte{0x20}...)
455
456 if t.Year() > 0 {
457 b = strconv.AppendInt(b, int64(t.Year()), 10)
458 } else {
459 b = strconv.AppendInt(b, int64(-t.Year()), 10)
460 }
461
462 return string(b)
463 }
464
465
466 func (ia *ia) FmtDateLong(t time.Time) string {
467
468 b := make([]byte, 0, 32)
469
470 b = strconv.AppendInt(b, int64(t.Day()), 10)
471 b = append(b, []byte{0x20, 0x64, 0x65}...)
472 b = append(b, []byte{0x20}...)
473 b = append(b, ia.monthsWide[t.Month()]...)
474 b = append(b, []byte{0x20}...)
475
476 if t.Year() > 0 {
477 b = strconv.AppendInt(b, int64(t.Year()), 10)
478 } else {
479 b = strconv.AppendInt(b, int64(-t.Year()), 10)
480 }
481
482 return string(b)
483 }
484
485
486 func (ia *ia) FmtDateFull(t time.Time) string {
487
488 b := make([]byte, 0, 32)
489
490 b = append(b, ia.daysWide[t.Weekday()]...)
491 b = append(b, []byte{0x20, 0x6c, 0x65}...)
492 b = append(b, []byte{0x20}...)
493 b = strconv.AppendInt(b, int64(t.Day()), 10)
494 b = append(b, []byte{0x20, 0x64, 0x65}...)
495 b = append(b, []byte{0x20}...)
496 b = append(b, ia.monthsWide[t.Month()]...)
497 b = append(b, []byte{0x20}...)
498
499 if t.Year() > 0 {
500 b = strconv.AppendInt(b, int64(t.Year()), 10)
501 } else {
502 b = strconv.AppendInt(b, int64(-t.Year()), 10)
503 }
504
505 return string(b)
506 }
507
508
509 func (ia *ia) FmtTimeShort(t time.Time) string {
510
511 b := make([]byte, 0, 32)
512
513 if t.Hour() < 10 {
514 b = append(b, '0')
515 }
516
517 b = strconv.AppendInt(b, int64(t.Hour()), 10)
518 b = append(b, ia.timeSeparator...)
519
520 if t.Minute() < 10 {
521 b = append(b, '0')
522 }
523
524 b = strconv.AppendInt(b, int64(t.Minute()), 10)
525
526 return string(b)
527 }
528
529
530 func (ia *ia) FmtTimeMedium(t time.Time) string {
531
532 b := make([]byte, 0, 32)
533
534 if t.Hour() < 10 {
535 b = append(b, '0')
536 }
537
538 b = strconv.AppendInt(b, int64(t.Hour()), 10)
539 b = append(b, ia.timeSeparator...)
540
541 if t.Minute() < 10 {
542 b = append(b, '0')
543 }
544
545 b = strconv.AppendInt(b, int64(t.Minute()), 10)
546 b = append(b, ia.timeSeparator...)
547
548 if t.Second() < 10 {
549 b = append(b, '0')
550 }
551
552 b = strconv.AppendInt(b, int64(t.Second()), 10)
553
554 return string(b)
555 }
556
557
558 func (ia *ia) FmtTimeLong(t time.Time) string {
559
560 b := make([]byte, 0, 32)
561
562 if t.Hour() < 10 {
563 b = append(b, '0')
564 }
565
566 b = strconv.AppendInt(b, int64(t.Hour()), 10)
567 b = append(b, ia.timeSeparator...)
568
569 if t.Minute() < 10 {
570 b = append(b, '0')
571 }
572
573 b = strconv.AppendInt(b, int64(t.Minute()), 10)
574 b = append(b, ia.timeSeparator...)
575
576 if t.Second() < 10 {
577 b = append(b, '0')
578 }
579
580 b = strconv.AppendInt(b, int64(t.Second()), 10)
581 b = append(b, []byte{0x20}...)
582
583 tz, _ := t.Zone()
584 b = append(b, tz...)
585
586 return string(b)
587 }
588
589
590 func (ia *ia) FmtTimeFull(t time.Time) string {
591
592 b := make([]byte, 0, 32)
593
594 if t.Hour() < 10 {
595 b = append(b, '0')
596 }
597
598 b = strconv.AppendInt(b, int64(t.Hour()), 10)
599 b = append(b, ia.timeSeparator...)
600
601 if t.Minute() < 10 {
602 b = append(b, '0')
603 }
604
605 b = strconv.AppendInt(b, int64(t.Minute()), 10)
606 b = append(b, ia.timeSeparator...)
607
608 if t.Second() < 10 {
609 b = append(b, '0')
610 }
611
612 b = strconv.AppendInt(b, int64(t.Second()), 10)
613 b = append(b, []byte{0x20}...)
614
615 tz, _ := t.Zone()
616
617 if btz, ok := ia.timezones[tz]; ok {
618 b = append(b, btz...)
619 } else {
620 b = append(b, tz...)
621 }
622
623 return string(b)
624 }
625
View as plain text