1package ki 2 3import ( 4 "math" 5 "strconv" 6 "time" 7 8 "github.com/go-playground/locales" 9 "github.com/go-playground/locales/currency" 10) 11 12type ki 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 // idx = enum of currency code 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// New returns a new instance of translator for the 'ki' locale 45func New() locales.Translator { 46 return &ki{ 47 locale: "ki", 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", "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", "UZS", "VEB", "VEF", "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{"", "JEN", "WKR", "WGT", "WKN", "WTN", "WTD", "WMJ", "WNN", "WKD", "WIK", "WMW", "DIT"}, 56 monthsNarrow: []string{"", "J", "K", "G", "K", "G", "G", "M", "K", "K", "I", "I", "D"}, 57 monthsWide: []string{"", "Njenuarĩ", "Mwere wa kerĩ", "Mwere wa gatatũ", "Mwere wa kana", "Mwere wa gatano", "Mwere wa gatandatũ", "Mwere wa mũgwanja", "Mwere wa kanana", "Mwere wa kenda", "Mwere wa ikũmi", "Mwere wa ikũmi na ũmwe", "Ndithemba"}, 58 daysAbbreviated: []string{"KMA", "NTT", "NMN", "NMT", "ART", "NMA", "NMM"}, 59 daysNarrow: []string{"K", "N", "N", "N", "A", "N", "N"}, 60 daysWide: []string{"Kiumia", "Njumatatũ", "Njumaine", "Njumatana", "Aramithi", "Njumaa", "Njumamothi"}, 61 periodsAbbreviated: []string{"Kiroko", "Hwaĩ-inĩ"}, 62 periodsWide: []string{"Kiroko", "Hwaĩ-inĩ"}, 63 erasAbbreviated: []string{"MK", "TK"}, 64 erasNarrow: []string{"", ""}, 65 erasWide: []string{"Mbere ya Kristo", "Thutha wa Kristo"}, 66 timezones: map[string]string{"HKST": "HKST", "ChST": "ChST", "PST": "PST", "AEST": "AEST", "SGT": "SGT", "HEEG": "HEEG", "HEPM": "HEPM", "CAT": "CAT", "CHADT": "CHADT", "BOT": "BOT", "HNEG": "HNEG", "ACST": "ACST", "GFT": "GFT", "WIT": "WIT", "OESZ": "OESZ", "ARST": "ARST", "GMT": "GMT", "CST": "CST", "LHST": "LHST", "WART": "WART", "WESZ": "WESZ", "NZST": "NZST", "NZDT": "NZDT", "JST": "JST", "AKST": "AKST", "CDT": "CDT", "AWST": "AWST", "MDT": "MDT", "WITA": "WITA", "JDT": "JDT", "HADT": "HADT", "COT": "COT", "HNPMX": "HNPMX", "SAST": "SAST", "MYT": "MYT", "EST": "EST", "MEZ": "MEZ", "HNT": "HNT", "OEZ": "OEZ", "UYST": "UYST", "CHAST": "CHAST", "PDT": "PDT", "WIB": "WIB", "HEOG": "HEOG", "HKT": "HKT", "HENOMX": "HENOMX", "TMT": "TMT", "∅∅∅": "∅∅∅", "AKDT": "AKDT", "HNOG": "HNOG", "AWDT": "AWDT", "HEPMX": "HEPMX", "MST": "MST", "LHDT": "LHDT", "WARST": "WARST", "HAT": "HAT", "SRT": "SRT", "AEDT": "AEDT", "WEZ": "WEZ", "ACWST": "ACWST", "IST": "IST", "HAST": "HAST", "ART": "ART", "UYT": "UYT", "HECU": "HECU", "ACDT": "ACDT", "MESZ": "MESZ", "ACWDT": "ACWDT", "HNPM": "HNPM", "TMST": "TMST", "COST": "COST", "HNCU": "HNCU", "BT": "BT", "ECT": "ECT", "CLT": "CLT", "ADT": "ADT", "WAT": "WAT", "HNNOMX": "HNNOMX", "VET": "VET", "EAT": "EAT", "CLST": "CLST", "GYT": "GYT", "AST": "AST", "WAST": "WAST", "EDT": "EDT"}, 67 } 68} 69 70// Locale returns the current translators string locale 71func (ki *ki) Locale() string { 72 return ki.locale 73} 74 75// PluralsCardinal returns the list of cardinal plural rules associated with 'ki' 76func (ki *ki) PluralsCardinal() []locales.PluralRule { 77 return ki.pluralsCardinal 78} 79 80// PluralsOrdinal returns the list of ordinal plural rules associated with 'ki' 81func (ki *ki) PluralsOrdinal() []locales.PluralRule { 82 return ki.pluralsOrdinal 83} 84 85// PluralsRange returns the list of range plural rules associated with 'ki' 86func (ki *ki) PluralsRange() []locales.PluralRule { 87 return ki.pluralsRange 88} 89 90// CardinalPluralRule returns the cardinal PluralRule given 'num' and digits/precision of 'v' for 'ki' 91func (ki *ki) CardinalPluralRule(num float64, v uint64) locales.PluralRule { 92 return locales.PluralRuleUnknown 93} 94 95// OrdinalPluralRule returns the ordinal PluralRule given 'num' and digits/precision of 'v' for 'ki' 96func (ki *ki) OrdinalPluralRule(num float64, v uint64) locales.PluralRule { 97 return locales.PluralRuleUnknown 98} 99 100// RangePluralRule returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for 'ki' 101func (ki *ki) RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) locales.PluralRule { 102 return locales.PluralRuleUnknown 103} 104 105// MonthAbbreviated returns the locales abbreviated month given the 'month' provided 106func (ki *ki) MonthAbbreviated(month time.Month) string { 107 return ki.monthsAbbreviated[month] 108} 109 110// MonthsAbbreviated returns the locales abbreviated months 111func (ki *ki) MonthsAbbreviated() []string { 112 return ki.monthsAbbreviated[1:] 113} 114 115// MonthNarrow returns the locales narrow month given the 'month' provided 116func (ki *ki) MonthNarrow(month time.Month) string { 117 return ki.monthsNarrow[month] 118} 119 120// MonthsNarrow returns the locales narrow months 121func (ki *ki) MonthsNarrow() []string { 122 return ki.monthsNarrow[1:] 123} 124 125// MonthWide returns the locales wide month given the 'month' provided 126func (ki *ki) MonthWide(month time.Month) string { 127 return ki.monthsWide[month] 128} 129 130// MonthsWide returns the locales wide months 131func (ki *ki) MonthsWide() []string { 132 return ki.monthsWide[1:] 133} 134 135// WeekdayAbbreviated returns the locales abbreviated weekday given the 'weekday' provided 136func (ki *ki) WeekdayAbbreviated(weekday time.Weekday) string { 137 return ki.daysAbbreviated[weekday] 138} 139 140// WeekdaysAbbreviated returns the locales abbreviated weekdays 141func (ki *ki) WeekdaysAbbreviated() []string { 142 return ki.daysAbbreviated 143} 144 145// WeekdayNarrow returns the locales narrow weekday given the 'weekday' provided 146func (ki *ki) WeekdayNarrow(weekday time.Weekday) string { 147 return ki.daysNarrow[weekday] 148} 149 150// WeekdaysNarrow returns the locales narrow weekdays 151func (ki *ki) WeekdaysNarrow() []string { 152 return ki.daysNarrow 153} 154 155// WeekdayShort returns the locales short weekday given the 'weekday' provided 156func (ki *ki) WeekdayShort(weekday time.Weekday) string { 157 return ki.daysShort[weekday] 158} 159 160// WeekdaysShort returns the locales short weekdays 161func (ki *ki) WeekdaysShort() []string { 162 return ki.daysShort 163} 164 165// WeekdayWide returns the locales wide weekday given the 'weekday' provided 166func (ki *ki) WeekdayWide(weekday time.Weekday) string { 167 return ki.daysWide[weekday] 168} 169 170// WeekdaysWide returns the locales wide weekdays 171func (ki *ki) WeekdaysWide() []string { 172 return ki.daysWide 173} 174 175// Decimal returns the decimal point of number 176func (ki *ki) Decimal() string { 177 return ki.decimal 178} 179 180// Group returns the group of number 181func (ki *ki) Group() string { 182 return ki.group 183} 184 185// Group returns the minus sign of number 186func (ki *ki) Minus() string { 187 return ki.minus 188} 189 190// FmtNumber returns 'num' with digits/precision of 'v' for 'ki' and handles both Whole and Real numbers based on 'v' 191func (ki *ki) FmtNumber(num float64, v uint64) string { 192 193 return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64) 194} 195 196// FmtPercent returns 'num' with digits/precision of 'v' for 'ki' and handles both Whole and Real numbers based on 'v' 197// NOTE: 'num' passed into FmtPercent is assumed to be in percent already 198func (ki *ki) FmtPercent(num float64, v uint64) string { 199 return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64) 200} 201 202// FmtCurrency returns the currency representation of 'num' with digits/precision of 'v' for 'ki' 203func (ki *ki) FmtCurrency(num float64, v uint64, currency currency.Type) string { 204 205 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64) 206 symbol := ki.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, ki.decimal[0]) 216 inWhole = true 217 continue 218 } 219 220 if inWhole { 221 if count == 3 { 222 b = append(b, ki.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, ki.minus[0]) 238 } 239 240 // reverse 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, ki.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// FmtAccounting returns the currency representation of 'num' with digits/precision of 'v' for 'ki' 260// in accounting notation. 261func (ki *ki) FmtAccounting(num float64, v uint64, currency currency.Type) string { 262 263 s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64) 264 symbol := ki.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, ki.decimal[0]) 274 inWhole = true 275 continue 276 } 277 278 if inWhole { 279 if count == 3 { 280 b = append(b, ki.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, ki.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 // reverse 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, ki.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, ki.currencyNegativeSuffix...) 324 } 325 326 return string(b) 327} 328 329// FmtDateShort returns the short date representation of 't' for 'ki' 330func (ki *ki) 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// FmtDateMedium returns the medium date representation of 't' for 'ki' 359func (ki *ki) 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, ki.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// FmtDateLong returns the long date representation of 't' for 'ki' 378func (ki *ki) 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, ki.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// FmtDateFull returns the full date representation of 't' for 'ki' 397func (ki *ki) FmtDateFull(t time.Time) string { 398 399 b := make([]byte, 0, 32) 400 401 b = append(b, ki.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, ki.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// FmtTimeShort returns the short time representation of 't' for 'ki' 418func (ki *ki) 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, ki.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// FmtTimeMedium returns the medium time representation of 't' for 'ki' 439func (ki *ki) 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, ki.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, ki.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// FmtTimeLong returns the long time representation of 't' for 'ki' 467func (ki *ki) 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, ki.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, ki.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// FmtTimeFull returns the full time representation of 't' for 'ki' 499func (ki *ki) 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, ki.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, ki.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 := ki.timezones[tz]; ok { 527 b = append(b, btz...) 528 } else { 529 b = append(b, tz...) 530 } 531 532 return string(b) 533} 534