├── .github └── workflows │ └── go.yml ├── .gitignore ├── LICENSE ├── README.md ├── automation.go ├── automation_test.go ├── default_formats.go ├── default_orders.go ├── doc.go ├── format_bg_bg.go ├── format_ca_es.go ├── format_common.go ├── format_cs_cz.go ├── format_da_dk.go ├── format_de_de.go ├── format_el_gr.go ├── format_en_gb.go ├── format_en_us.go ├── format_es_es.go ├── format_et_ee.go ├── format_fi_fi.go ├── format_fr_fr.go ├── format_hr_hr.go ├── format_hu_hu.go ├── format_id_id.go ├── format_it_it.go ├── format_ja_jp.go ├── format_kk_kz.go ├── format_ko_kr.go ├── format_lt_lt.go ├── format_lv_lv.go ├── format_nb_no.go ├── format_nl_be.go ├── format_nn_no.go ├── format_pl_pl.go ├── format_pt_br.go ├── format_pt_pt.go ├── format_ro_RO.go ├── format_ru_ru.go ├── format_sk_sk.go ├── format_sl_si.go ├── format_sv_se.go ├── format_th_th.go ├── format_tr_tr.go ├── format_uk_ua.go ├── format_uz_uz.go ├── format_zh_cn.go ├── format_zh_hk.go ├── format_zh_tw.go ├── go.mod ├── locale.go ├── monday.go ├── monday_test.go ├── set.go ├── set_test.go ├── utils_layout.go └── utils_layout_test.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: [push] 3 | jobs: 4 | 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: Set up Go 1.13 11 | uses: actions/setup-go@v1 12 | with: 13 | go-version: 1.13 14 | id: go 15 | 16 | - name: Check out code into the Go module directory 17 | uses: actions/checkout@v2 18 | 19 | - name: Get dependencies 20 | run: | 21 | go get -v -t -d ./... 22 | if [ -f Gopkg.toml ]; then 23 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 24 | dep ensure 25 | fi 26 | 27 | - name: Build 28 | run: | 29 | go vet 30 | go build -v . 31 | 32 | - name: Test 33 | run: go test -v -race . 34 | 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | /monday.iml 24 | /.idea/ 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021 Dmitry Bondarenko 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Description 2 | ==== 3 | 4 | Monday is a minimalistic translator for month and day of week names in time.Date objects. Supports 20+ different locales. 5 | Written in pure [Go](http://golang.org). 6 | 7 | ![Go](https://github.com/goodsign/monday/workflows/Go/badge.svg) 8 | 9 | Installing 10 | ==== 11 | 12 | ``` 13 | go get github.com/goodsign/monday 14 | ``` 15 | 16 | Usage 17 | ==== 18 | 19 | Format 20 | --------------------- 21 | 22 | Given that you already use [time.Format](http://golang.org/pkg/time/#Time.Format) somewhere in your code, 23 | to translate your output you should import monday and replace 24 | 25 | ```go 26 | yourTime.Format(yourLayout) 27 | ``` 28 | 29 | with 30 | 31 | ```go 32 | // Change LocaleEnUS to the locale you want to use for translation 33 | monday.Format(yourTime, yourLayout, monday.LocaleEnUS) 34 | ``` 35 | 36 | Parse 37 | --------------------- 38 | 39 | Given that you already use [time.ParseInLocation](http://golang.org/pkg/time/#ParseInLocation) somewhere in your code, 40 | to parse input string in a different language you should import monday and replace 41 | 42 | ```go 43 | time.ParseInLocation(yourLayout, yourString, yourLocation) 44 | ``` 45 | 46 | with 47 | 48 | ```go 49 | // Change LocaleEnUS to the locale you want to use for translation 50 | monday.ParseInLocation(yourLayout, yourString, yourLocation, monday.LocaleEnUS) 51 | ``` 52 | 53 | Predefined formats 54 | --------------------- 55 | 56 | Monday declares some predefined formats: Full, Long, Medium, Short, DateTime formats for each locale. E.g. to get 57 | short format for any locale you can use map: 58 | 59 | ```go 60 | monday.ShortFormatsByLocale[locale] 61 | ``` 62 | 63 | Usage notes 64 | ----------- 65 | 66 | **Monday** is not an alternative to standard **time** package. It is a temporary solution to use while 67 | the internationalization features are not ready. 68 | 69 | That's why **monday** doesn't create any additional parsing algorithms, layout identifiers. It is just 70 | a wrapper for time.Format and time.ParseInLocation and uses all the same layout IDs, constants, etc. 71 | 72 | So, the changes you need to temporarily switch to **monday** (while the internationalization features are being developed) 73 | are minimal: you preserve your layout, your time object, your parsed date string formats and the only change is 74 | the func call itself. 75 | 76 | Locales 77 | ---- 78 | 79 | Supported locales are listed in **locale.go** file. 80 | 81 | ``` 82 | const ( 83 | LocaleEnUS = "en_US" // English (United States) 84 | LocaleEnGB = "en_GB" // English (United Kingdom) 85 | LocaleDaDK = "da_DK" // Danish (Denmark) 86 | LocaleNlBE = "nl_BE" // Dutch (Belgium) 87 | LocaleNlNL = "nl_NL" // Dutch (Netherlands) 88 | LocaleFiFI = "fi_FI" // Finnish (Finland) 89 | LocaleFrFR = "fr_FR" // French (France) 90 | LocaleFrCA = "fr_CA" // French (Canada) 91 | LocaleDeDE = "de_DE" // German (Germany) 92 | LocaleHuHU = "hu_HU" // Hungarian (Hungary) 93 | LocaleItIT = "it_IT" // Italian (Italy) 94 | LocaleNnNO = "nn_NO" // Norwegian Nynorsk (Norway) 95 | LocaleNbNO = "nb_NO" // Norwegian Bokmål (Norway) 96 | LocalePlPL = "pl_PL" // Polish (Poland) 97 | LocalePtPT = "pt_PT" // Portuguese (Portugal) 98 | LocalePtBR = "pt_BR" // Portuguese (Brazil) 99 | LocaleRoRO = "ro_RO" // Romanian (Romania) 100 | LocaleRuRU = "ru_RU" // Russian (Russia) 101 | LocaleEsES = "es_ES" // Spanish (Spain) 102 | LocaleCaES = "ca_ES" // Catalan (Spain) 103 | LocaleSvSE = "sv_SE" // Swedish (Sweden) 104 | LocaleTrTR = "tr_TR" // Turkish (Turkey) 105 | LocaleUkUA = "uk_UA" // Ukrainian (Ukraine) 106 | LocaleBgBG = "bg_BG" // Bulgarian (Bulgaria) 107 | LocaleZhCN = "zh_CN" // Chinese (Mainland) 108 | LocaleZhTW = "zh_TW" // Chinese (Taiwan) 109 | LocaleZhHK = "zh_HK" // Chinese (Hong Kong) 110 | LocaleKoKR = "ko_KR" // Korean (Korea) 111 | LocaleJaJP = "ja_JP" // Japanese (Japan) 112 | LocaleElGR = "el_GR" // Greek (Greece) 113 | LocaleIdID = "id_ID" // Indonesian (Indonesia) 114 | LocaleFrGP = "fr_GP" // French (Guadeloupe) 115 | LocaleFrLU = "fr_LU" // French (Luxembourg) 116 | LocaleFrMQ = "fr_MQ" // French (Martinique) 117 | LocaleFrGF = "fr_GF" // French (French Guiana) 118 | LocaleFrGF = "fr_RE" // French (Reunion) 119 | LocaleCsCZ = "cs_CZ" // Czech (Czech Republic) 120 | LocaleSlSI = "sl_SI" // Slovenian (Slovenia) 121 | LocaleLtLT = "lt_LT" // Lithuanian (Lithuania) 122 | LocaleEtEE = "et_EE" // Estonian (Estonia) 123 | LocaleHrHR = "hr_HR" // Croatian (Croatia) 124 | LocaleLvLV = "lv_LV" // Latvian (Latvia) 125 | LocaleSkSK = "sk_SK" // Slovak (Slovakia) 126 | LocaleThTH = "th_TH" // Thai (Thailand) 127 | LocaleUzUZ = "uz_UZ" // Uzbek (Uzbekistan) 128 | LocaleKkKZ = "kk_KZ" // Kazakh (Kazakhstan) 129 | ) 130 | ``` 131 | 132 | LocaleDetector 133 | ==== 134 | 135 | ```go 136 | var timeLocaleDetector *monday.LocaleDetector = monday.NewLocaleDetector() 137 | dateTime, err := timeLocaleDetector.Parse(layout,datestr) 138 | ``` 139 | parses datetime with **unknown** locale (for now - layout must be defined, as for time.Parse()) 140 | 141 | useful for text parsing tools/crawlers (f.e.: rss-feeds crawler) 142 | 143 | TODO: 144 | * make LocaleDetector insensitive to whitespaces count 145 | 146 | Thread-safety 147 | ==== 148 | 149 | **Monday** initializes all its data once in the **init** func and then uses only 150 | func calls and local vars. Thus, it's thread-safe and doesn't need any mutexes to be 151 | used with. 152 | 153 | Monday Licence 154 | ========== 155 | 156 | The **Monday** library is released under the [BSD Licence](http://opensource.org/licenses/bsd-license.php) 157 | 158 | [LICENCE file](https://github.com/goodsign/monday/blob/master/LICENCE) 159 | 160 | Thanks 161 | ========== 162 | 163 | * [Martin Angers](https://github.com/PuerkitoBio) 164 | * Andrey Mirtchovski 165 | * [mikespook](https://github.com/mikespook) 166 | * [Luis Azevedo](https://github.com/braceta) 167 | * [imikod](https://github.com/imikod) 168 | * [Renato Serra](https://github.com/RenatoSerra22) 169 | * [Zachary Stewart](https://github.com/ztstewart) 170 | -------------------------------------------------------------------------------- /automation.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "regexp" 7 | "strconv" 8 | "strings" 9 | "text/scanner" 10 | "time" 11 | ) 12 | 13 | var ( 14 | wordsRx = regexp.MustCompile("(\\p{L}+)") 15 | debugLayoutDef = false 16 | ) 17 | 18 | // An InvalidTypeError indicates that data was parsed incorrectly as a result 19 | // of a type mismatch. 20 | type InvalidTypeError struct { 21 | error 22 | } 23 | 24 | // An InvalidLengthError is returned when an item's length was longer or 25 | // shorter than expected for a particular token. 26 | type InvalidLengthError struct { 27 | error 28 | } 29 | 30 | // NewInvalidTypeError instantiates an InvalidTypeError. 31 | func NewInvalidTypeError() InvalidTypeError { 32 | return InvalidTypeError{error: errors.New("invalid type for token")} 33 | } 34 | 35 | // NewInvalidLengthError instantiates an InvalidLengthError. 36 | func NewInvalidLengthError() InvalidLengthError { 37 | return InvalidLengthError{error: errors.New("invalid length for token")} 38 | } 39 | 40 | type layoutSpanI interface { 41 | scanInt(s *scanner.Scanner) (int, error) 42 | scanString(s *scanner.Scanner) (string, error) 43 | isString() bool 44 | isDelimiter() bool 45 | } 46 | 47 | type lengthLimitSpan struct { 48 | minLength int 49 | maxLength int 50 | } 51 | 52 | func (lls lengthLimitSpan) scanInt(s *scanner.Scanner) (int, error) { 53 | return -1, NewInvalidTypeError() 54 | } 55 | 56 | func (lls lengthLimitSpan) scanString(s *scanner.Scanner) (string, error) { 57 | return "", NewInvalidTypeError() 58 | } 59 | 60 | func (lls lengthLimitSpan) isString() bool { return false } 61 | func (lls lengthLimitSpan) isDelimiter() bool { return false } 62 | 63 | func initLengthLimitSpan(min, max int) lengthLimitSpan { 64 | return lengthLimitSpan{ 65 | minLength: min, 66 | maxLength: max, 67 | } 68 | } 69 | 70 | type limitedStringSpan struct { 71 | lengthLimitSpan 72 | } 73 | 74 | func initLimitedStringSpan(minLength, maxLength int) limitedStringSpan { 75 | return limitedStringSpan{lengthLimitSpan: initLengthLimitSpan(minLength, maxLength)} 76 | } 77 | 78 | func (lss limitedStringSpan) scanString(s *scanner.Scanner) (string, error) { 79 | tok := s.Scan() 80 | if tok != scanner.EOF && tok == -2 { 81 | return s.TokenText(), nil 82 | } 83 | return "", NewInvalidTypeError() 84 | } 85 | 86 | func (lss limitedStringSpan) isString() bool { return true } 87 | func (lss limitedStringSpan) String() string { 88 | return fmt.Sprintf("[limitedStringSpan:%v]", lss.lengthLimitSpan) 89 | } 90 | 91 | type rangeIntSpan struct { 92 | lengthLimitSpan 93 | min int 94 | max int 95 | } 96 | 97 | func initRangeIntSpan(minValue, maxValue, minLength, maxLength int) rangeIntSpan { 98 | return rangeIntSpan{ 99 | lengthLimitSpan: initLengthLimitSpan(minLength, maxLength), 100 | min: minValue, 101 | max: maxValue, 102 | } 103 | } 104 | 105 | func (rs rangeIntSpan) scanInt(s *scanner.Scanner) (int, error) { 106 | var tok = s.Scan() 107 | var negative bool 108 | if tok == 45 { 109 | negative = true 110 | if debugLayoutDef { 111 | fmt.Printf("scan negative:'%s'\n", s.TokenText()) 112 | } 113 | tok = s.Scan() 114 | } else if tok == 43 { // positive 115 | tok = s.Scan() 116 | } 117 | if tok == -3 { 118 | str := s.TokenText() 119 | i, err := strconv.Atoi(str) 120 | if err != nil { 121 | return 0, err 122 | } 123 | if negative { 124 | i = i * -1 125 | } 126 | return i, nil 127 | } 128 | 129 | if debugLayoutDef { 130 | fmt.Printf("invalid tok: %v '%s'\n", tok, s.TokenText()) 131 | } 132 | 133 | return 0, NewInvalidTypeError() 134 | } 135 | 136 | func (rs rangeIntSpan) String() string { 137 | return fmt.Sprintf("[rangeIntSpan:%v]", rs.lengthLimitSpan) 138 | } 139 | 140 | type delimiterSpan struct { 141 | lengthLimitSpan 142 | character string 143 | } 144 | 145 | func initDelimiterSpan(character string, minLength, maxLength int) delimiterSpan { 146 | return delimiterSpan{ 147 | lengthLimitSpan: initLengthLimitSpan(minLength, maxLength), 148 | character: character, 149 | } 150 | } 151 | 152 | func (ds delimiterSpan) scanString(s *scanner.Scanner) (string, error) { 153 | tok := s.Scan() 154 | if tok != scanner.EOF && tok != -2 && tok != 45 && tok != -3 { 155 | return s.TokenText(), nil 156 | } 157 | if debugLayoutDef { 158 | fmt.Printf("expected tok:=!(-2,-3,45), received:%d ('%s')\n", tok, s.TokenText()) 159 | } 160 | 161 | return "", NewInvalidTypeError() 162 | } 163 | 164 | func (ds delimiterSpan) isString() bool { return false } 165 | func (ds delimiterSpan) isDelimiter() bool { return true } 166 | func (ds delimiterSpan) String() string { 167 | return fmt.Sprintf("[delimiterSpan '%s':%v]", ds.character, ds.lengthLimitSpan) 168 | } 169 | 170 | type layoutDef struct { 171 | spans []layoutSpanI 172 | errorPosition int 173 | } 174 | 175 | func (ld *layoutDef) validate(value string) bool { 176 | s := &scanner.Scanner{} 177 | s.Init(strings.NewReader(value)) 178 | s.Whitespace = 0 179 | for _, span := range ld.spans { 180 | if span.isString() || span.isDelimiter() { 181 | if _, err := span.scanString(s); err != nil { 182 | ld.errorPosition = s.Pos().Offset 183 | if debugLayoutDef { 184 | fmt.Printf("error at pos: %d: %s (span=%+v) - expected string or delimiter\n", s.Pos().Offset, err.Error(), span) 185 | } 186 | return false 187 | } 188 | } else if _, err := span.scanInt(s); err != nil { 189 | if debugLayoutDef { 190 | fmt.Printf("error at pos: %d: %s (span=%+v) - expected integer\n", s.Pos().Offset, err.Error(), span) 191 | } 192 | ld.errorPosition = s.Pos().Offset 193 | return false 194 | } 195 | } 196 | ld.errorPosition = s.Pos().Offset 197 | return s.Pos().Offset == len(value) 198 | } 199 | 200 | // A LocaleDetector parses time.Time values by using various heuristics and 201 | // techniques to determine which locale should be used to parse the 202 | // time.Time value. As not all possible locales and formats are supported, 203 | // this process can be somewhat lossy and inaccurate. 204 | type LocaleDetector struct { 205 | localeMap map[string]*set 206 | lastLocale Locale 207 | layoutsMap map[string]layoutDef 208 | lastErrorPosition int 209 | } 210 | 211 | func (ld *LocaleDetector) prepareLayout(layout string) layoutDef { 212 | s := scanner.Scanner{} 213 | s.Init(strings.NewReader(layout)) 214 | s.Whitespace = 0 215 | result := make([]layoutSpanI, 0) 216 | var tok rune 217 | // var pos int = 0 218 | var span layoutSpanI 219 | var sign bool 220 | // var neg bool = false 221 | for tok != scanner.EOF { 222 | tok = s.Scan() 223 | switch tok { 224 | case -2: // text 225 | span = initLimitedStringSpan(1, -1) 226 | case -3: // digit 227 | span = initRangeIntSpan(-1, -1, 1, -1) 228 | if sign { 229 | sign = false 230 | } 231 | case 45: // negative sign 232 | sign = true 233 | // neg = s.TokenText() == "-" 234 | continue 235 | case 43: // positive sign 236 | sign = true 237 | continue 238 | case scanner.EOF: 239 | continue 240 | default: // fixed character 241 | span = initDelimiterSpan(s.TokenText(), 1, 1) 242 | } 243 | result = append(result, span) 244 | // length := s.Pos().Offset - pos 245 | // pos = s.Pos().Offset 246 | // fmt.Printf("tok'%s' [%d %d] length=%d\n", s.TokenText(), pos, s.Pos().Offset, length) 247 | 248 | } 249 | if debugLayoutDef { 250 | fmt.Printf("layout:'%s'\n", layout) 251 | fmt.Printf("layout:%v\n", result) 252 | } 253 | ret := layoutDef{spans: result} 254 | ld.layoutsMap[layout] = ret 255 | return ret 256 | } 257 | 258 | func (ld *LocaleDetector) validateValue(layout string, value string) bool { 259 | l, ok := ld.layoutsMap[layout] 260 | if !ok { 261 | l = ld.prepareLayout(layout) 262 | } 263 | result := l.validate(value) 264 | ld.lastErrorPosition = l.errorPosition 265 | return result 266 | } 267 | 268 | func (ld *LocaleDetector) errorPosition() int { return ld.lastErrorPosition } 269 | 270 | func (ld *LocaleDetector) addWords(words []string, v Locale) { 271 | for _, w := range words { 272 | l := strings.ToLower(w) 273 | if _, ok := ld.localeMap[w]; !ok { 274 | ld.localeMap[w] = newSet(v) 275 | if l != w { 276 | ld.localeMap[l] = newSet(v) 277 | } 278 | } else { 279 | ld.localeMap[w].Add(v) 280 | if l != w { 281 | ld.localeMap[l].Add(v) 282 | } 283 | } 284 | } 285 | } 286 | 287 | // NewLocaleDetector instances a LocaleDetector instance. 288 | func NewLocaleDetector() *LocaleDetector { 289 | ld := &LocaleDetector{localeMap: make(map[string]*set), lastLocale: LocaleEnGB, layoutsMap: make(map[string]layoutDef)} 290 | for _, v := range ListLocales() { 291 | days := GetShortDays(v) 292 | ld.addWords(days, v) 293 | days = GetLongDays(v) 294 | ld.addWords(days, v) 295 | months := GetShortMonths(v) 296 | ld.addWords(months, v) 297 | months = GetLongMonths(v) 298 | ld.addWords(months, v) 299 | } 300 | return ld 301 | } 302 | 303 | // Parse will attempt to parse a time.Time struct from a layout (format) and a 304 | // value to parse from. 305 | // 306 | // If no locale can be determined, this method will return an error and an 307 | // empty time object. 308 | func (ld *LocaleDetector) Parse(layout, value string) (time.Time, error) { 309 | if ld.validateValue(layout, value) { 310 | ld.lastLocale = ld.detectLocale(value) 311 | return ParseInLocation(layout, value, time.UTC, ld.lastLocale) 312 | } 313 | return time.Time{}, &time.ParseError{ 314 | Value: value, 315 | Layout: layout, 316 | Message: fmt.Sprintf("'%s' not matches to '%s' last error position = %d\n", value, layout, ld.lastErrorPosition), 317 | } 318 | } 319 | 320 | func (ld *LocaleDetector) detectLocale(value string) Locale { 321 | localesMap := make(map[Locale]int) 322 | for _, v := range wordsRx.FindAllStringSubmatchIndex(value, -1) { 323 | word := strings.ToLower(value[v[0]:v[1]]) 324 | 325 | if len(word) <= 1 { 326 | continue 327 | } 328 | 329 | if localesSet, ok := ld.localeMap[word]; ok { 330 | localesSet.Each(func(loc Locale) bool { 331 | if _, ok := localesMap[loc]; !ok { 332 | localesMap[loc] = 1 333 | } else { 334 | localesMap[loc]++ 335 | } 336 | return true 337 | }) 338 | } 339 | } 340 | var result Locale = LocaleEnUS 341 | frequency := 0 342 | for key, counter := range localesMap { 343 | if counter > frequency { 344 | frequency = counter 345 | result = key 346 | } 347 | } 348 | return result 349 | } 350 | -------------------------------------------------------------------------------- /automation_test.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | // "fmt" 5 | "testing" 6 | ) 7 | 8 | type layoutData struct { 9 | layout string 10 | matches []string 11 | unmatches []string 12 | locales []Locale 13 | } 14 | 15 | var ( 16 | testingLayoutsData = []layoutData{ 17 | layoutData{ 18 | layout: "Mon, 2 Jan 2006 15:4:5 -0700", 19 | matches: []string{ 20 | "Нд, 22 Гру 2019 00:35:44 +0200", 21 | "Вт, 2 Янв 1997 12:01:44 -0330", 22 | "Tue, 12 Feb 2014 22:03:40 -0300", 23 | "Fri, 12 Feb 2016 16:01:00 +0000", 24 | }, 25 | unmatches: []string{ 26 | "Mon, 2 Jan 2006 15:4:5 -0700 ", 27 | "Mon, 2 Jan 2006 15:4:5 -0700", 28 | "Mon, 2 Jan 2006 15:4:5", 29 | "Mon, 2 Jan 2006 15:4:5 4 -0700", 30 | "Mon, 2 Jan 2006 15:4:5 4 +0200", 31 | }, 32 | locales: []Locale{ 33 | LocaleUkUA, 34 | LocaleRuRU, 35 | LocaleEnUS, 36 | LocaleEnUS, 37 | }, 38 | }, 39 | layoutData{ 40 | layout: "2006-01-02T15:04:05-07:00", 41 | matches: []string{ 42 | "2019-12-22T00:35:44+02:00", 43 | "2016-02-02T00:00:00+03:00", 44 | "2016-01-26T00:10:21-03:00", 45 | "2016-01-26T22:15:30+03:00", 46 | }, 47 | locales: makeSingleLocalesArray(LocaleEnUS, 4), 48 | }, 49 | layoutData{ 50 | layout: "Пон, 2 Янв 2006 15:4:5 -0700", 51 | }, 52 | } 53 | ) 54 | 55 | func TestLayoutValidator(t *testing.T) { 56 | ld := NewLocaleDetector() 57 | for _, ltd := range testingLayoutsData { 58 | ld.prepareLayout(ltd.layout) 59 | for i, m := range ltd.matches { 60 | if !ld.validateValue(ltd.layout, m) { 61 | t.Errorf("'%s' not matches to '%s' last error position = %d\n", m, ltd.layout, ld.errorPosition()) 62 | } 63 | locale := ld.detectLocale(m) 64 | if !compareLocales(locale, ltd.locales[i]) { 65 | t.Errorf("locales detect error, expected '%s', result '%s'\n", ltd.locales[i], locale) 66 | } 67 | } 68 | for _, u := range ltd.unmatches { 69 | if ld.validateValue(ltd.layout, u) { 70 | t.Errorf("'%s' matches to '%s'\n", u, ltd.layout) 71 | } 72 | } 73 | } 74 | } 75 | 76 | // TODO: locale groups. 77 | var englishLocales = newSet(LocaleEnUS, LocaleEnGB) 78 | 79 | func compareLocales(a, b Locale) bool { 80 | if a == b { 81 | return true 82 | } 83 | if englishLocales.Has(a) && englishLocales.Has(b) { 84 | return true 85 | } 86 | return false 87 | } 88 | 89 | func TestCompareLocales(t *testing.T) { 90 | if !compareLocales(LocaleEnGB, LocaleEnUS) { 91 | t.Errorf("compareLocales not works as expected") 92 | } 93 | } 94 | 95 | func TestParsing(t *testing.T) { 96 | ld := NewLocaleDetector() 97 | for _, ltd := range testingLayoutsData { 98 | for i, formatted := range ltd.matches { 99 | dt, err := ld.Parse(ltd.layout, formatted) 100 | if err != nil { 101 | t.Errorf("error parsing '%s' with layout: '%s' [error:%s]\n", formatted, ltd.layout, err.Error()) 102 | } else { 103 | restored := Format(dt, ltd.layout, ltd.locales[i]) 104 | if restored != formatted { 105 | dt2, err2 := ld.Parse(ltd.layout, restored) 106 | if err2 != nil { 107 | t.Errorf("parsed time '%s' (%s) does not match restored time '%s'\n", formatted, dt, restored) 108 | } 109 | if dt2.Unix() != dt.Unix() { 110 | t.Errorf("restored time '%v' != parsed time '%v' (restored='%s')", dt2, dt, restored) 111 | } 112 | } 113 | } 114 | } 115 | } 116 | } 117 | 118 | func makeSingleLocalesArray(loc Locale, length int) []Locale { 119 | result := make([]Locale, length) 120 | for i := range result { 121 | result[i] = loc 122 | } 123 | return result 124 | } 125 | -------------------------------------------------------------------------------- /default_formats.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // Default date formats by country. 4 | // Mostly taken from http://en.wikipedia.org/wiki/Date_format_by_country 5 | const ( 6 | DefaultFormatEnUS = "01/02/06" 7 | 8 | DefaultFormatEnUSFull = "Monday, January 2, 2006" // English (United States) 9 | DefaultFormatEnUSLong = "January 2, 2006" 10 | DefaultFormatEnUSMedium = "Jan 02, 2006" 11 | DefaultFormatEnUSShort = "1/2/06" 12 | DefaultFormatEnUSDateTime = "1/2/06 3:04 PM" 13 | DefaultFormatEnUSTime = "3:04 PM" 14 | 15 | DefaultFormatEnGBFull = "Monday, 2 January 2006" // English (United Kingdom) 16 | DefaultFormatEnGBLong = "2 January 2006" 17 | DefaultFormatEnGBMedium = "02 Jan 2006" 18 | DefaultFormatEnGBShort = "02/01/2006" 19 | DefaultFormatEnGBDateTime = "02/01/2006 15:04" 20 | DefaultFormatEnGBTime = "15:04" 21 | 22 | DefaultFormatDaDKFull = "Monday den 2. January 2006" // Danish (Denmark) 23 | DefaultFormatDaDKLong = "2. Jan 2006" 24 | DefaultFormatDaDKMedium = "02/01/2006" 25 | DefaultFormatDaDKShort = "02/01/06" 26 | DefaultFormatDaDKDateTime = "02/01/2006 15.04" 27 | DefaultFormatDaDKTime = "15.04" 28 | 29 | DefaultFormatNlBEFull = "Monday 2 January 2006" // Dutch (Belgium) 30 | DefaultFormatNlBELong = "2 January 2006" 31 | DefaultFormatNlBEMedium = "02-Jan-2006" 32 | DefaultFormatNlBEShort = "2/01/06" 33 | DefaultFormatNlBEDateTime = "2/01/06 15:04" 34 | DefaultFormatNlBETime = "15:04" 35 | 36 | DefaultFormatNlNLFull = "Monday 2 January 2006" // Dutch (Netherlands) 37 | DefaultFormatNlNLLong = "2 January 2006" 38 | DefaultFormatNlNLMedium = "02 Jan 2006" 39 | DefaultFormatNlNLShort = "02-01-06" 40 | DefaultFormatNlNLDateTime = "02-01-06 15:04" 41 | DefaultFormatNlNLTime = "15:04" 42 | 43 | DefaultFormatFiFIFull = "Monday 2. January 2006" // Finnish (Finland) 44 | DefaultFormatFiFILong = "2. January 2006" 45 | DefaultFormatFiFIMedium = "02.1.2006" 46 | DefaultFormatFiFIShort = "02.1.2006" 47 | DefaultFormatFiFIDateTime = "02.1.2006 15.04" 48 | DefaultFormatFiFITime = "15.04" 49 | 50 | DefaultFormatFrFRFull = "Monday 2 January 2006" // French (France) 51 | DefaultFormatFrFRLong = "2 January 2006" 52 | DefaultFormatFrFRMedium = "02 Jan 2006" 53 | DefaultFormatFrFRShort = "02/01/2006" 54 | DefaultFormatFrFRDateTime = "02/01/2006 15:04" 55 | DefaultFormatFrFRTime = "15:04" 56 | 57 | DefaultFormatFrCAFull = "Monday 2 January 2006" // French (Canada) 58 | DefaultFormatFrCALong = "2 January 2006" 59 | DefaultFormatFrCAMedium = "2006-01-02" 60 | DefaultFormatFrCAShort = "06-01-02" 61 | DefaultFormatFrCADateTime = "06-01-02 15:04" 62 | DefaultFormatFrCATime = "15:04" 63 | 64 | DefaultFormatFrGPFull = "Monday 2 January 2006" // French (Guadeloupe) 65 | DefaultFormatFrGPLong = "2 January 2006" 66 | DefaultFormatFrGPMedium = "2006-01-02" 67 | DefaultFormatFrGPShort = "06-01-02" 68 | DefaultFormatFrGPDateTime = "06-01-02 15:04" 69 | DefaultFormatFrGPTime = "15:04" 70 | 71 | DefaultFormatFrLUFull = "Monday 2 January 2006" // French (Luxembourg) 72 | DefaultFormatFrLULong = "2 January 2006" 73 | DefaultFormatFrLUMedium = "2006-01-02" 74 | DefaultFormatFrLUShort = "06-01-02" 75 | DefaultFormatFrLUDateTime = "06-01-02 15:04" 76 | DefaultFormatFrLUTime = "15:04" 77 | 78 | DefaultFormatFrMQFull = "Monday 2 January 2006" // French (Martinique) 79 | DefaultFormatFrMQLong = "2 January 2006" 80 | DefaultFormatFrMQMedium = "2006-01-02" 81 | DefaultFormatFrMQShort = "06-01-02" 82 | DefaultFormatFrMQDateTime = "06-01-02 15:04" 83 | DefaultFormatFrMQTime = "15:04" 84 | 85 | DefaultFormatFrGFFull = "Monday 2 January 2006" // French (French Guiana) 86 | DefaultFormatFrGFLong = "2 January 2006" 87 | DefaultFormatFrGFMedium = "2006-01-02" 88 | DefaultFormatFrGFShort = "06-01-02" 89 | DefaultFormatFrGFDateTime = "06-01-02 15:04" 90 | DefaultFormatFrGFTime = "15:04" 91 | 92 | DefaultFormatFrREFull = "Monday 2 January 2006" // French (Reunion) 93 | DefaultFormatFrRELong = "2 January 2006" 94 | DefaultFormatFrREMedium = "2006-01-02" 95 | DefaultFormatFrREShort = "06-01-02" 96 | DefaultFormatFrREDateTime = "06-01-02 15:04" 97 | DefaultFormatFrRETime = "15:04" 98 | 99 | DefaultFormatDeDEFull = "Monday, 2. January 2006" // German (Germany) 100 | DefaultFormatDeDELong = "2. January 2006" 101 | DefaultFormatDeDEMedium = "02.01.2006" 102 | DefaultFormatDeDEShort = "02.01.06" 103 | DefaultFormatDeDEDateTime = "02.01.06 15:04" 104 | DefaultFormatDeDETime = "15:04" 105 | 106 | DefaultFormatHuHUFull = "2006. January 2., Monday" // Hungarian (Hungary) 107 | DefaultFormatHuHULong = "2006. January 2." 108 | DefaultFormatHuHUMedium = "2006.01.02." 109 | DefaultFormatHuHUShort = "2006.01.02." 110 | DefaultFormatHuHUDateTime = "2006.01.02. 15:04" 111 | DefaultFormatHuHUTime = "15:04" 112 | 113 | DefaultFormatItITFull = "Monday 2 January 2006" // Italian (Italy) 114 | DefaultFormatItITLong = "2 January 2006" 115 | DefaultFormatItITMedium = "02/Jan/2006" 116 | DefaultFormatItITShort = "02/01/06" 117 | DefaultFormatItITDateTime = "02/01/06 15:04" 118 | DefaultFormatItITTime = "15:04" 119 | 120 | DefaultFormatNnNOFull = "Monday 2. January 2006" // Norwegian Nynorsk (Norway) 121 | DefaultFormatNnNOLong = "2. January 2006" 122 | DefaultFormatNnNOMedium = "02. Jan 2006" 123 | DefaultFormatNnNOShort = "02.01.06" 124 | DefaultFormatNnNODateTime = "02.01.06 15:04" 125 | DefaultFormatNnNOTime = "15:04" 126 | 127 | DefaultFormatNbNOFull = "Monday 2. January 2006" // Norwegian Bokmål (Norway) 128 | DefaultFormatNbNOLong = "2. January 2006" 129 | DefaultFormatNbNOMedium = "02. Jan 2006" 130 | DefaultFormatNbNOShort = "02.01.06" 131 | DefaultFormatNbNODateTime = "15:04 02.01.06" 132 | DefaultFormatNbNOTime = "15:04" 133 | 134 | DefaultFormatPlPLFull = "Monday, 2 January 2006" // Polish (Poland) 135 | DefaultFormatPlPLLong = "2 January 2006" 136 | DefaultFormatPlPLMedium = "02 Jan 2006" 137 | DefaultFormatPlPLShort = "02.01.2006" 138 | DefaultFormatPlPLDateTime = "02.01.2006, 15:04" 139 | DefaultFormatPlPLTime = "15:04" 140 | 141 | DefaultFormatPtPTFull = "Monday, 2 de January de 2006" // Portuguese (Portugal) 142 | DefaultFormatPtPTLong = "2 de January de 2006" 143 | DefaultFormatPtPTMedium = "02/01/2006" 144 | DefaultFormatPtPTShort = "02/01/06" 145 | DefaultFormatPtPTDateTime = "02/01/06, 15:04" 146 | DefaultFormatPtPTTime = "15:04" 147 | 148 | DefaultFormatPtBRFull = "Monday, 2 de January de 2006" // Portuguese (Brazil) 149 | DefaultFormatPtBRLong = "02 de January de 2006" 150 | DefaultFormatPtBRMedium = "02/01/2006" 151 | DefaultFormatPtBRShort = "02/01/06" 152 | DefaultFormatPtBRDateTime = "02/01/06, 15:04" 153 | DefaultFormatPtBRTime = "15:04" 154 | 155 | DefaultFormatRoROFull = "Monday, 02 January 2006" // Romanian (Romania) 156 | DefaultFormatRoROLong = "02 January 2006" 157 | DefaultFormatRoROMedium = "02.01.2006" 158 | DefaultFormatRoROShort = "02.01.2006" 159 | DefaultFormatRoRODateTime = "02.01.06, 15:04" 160 | DefaultFormatRoROTime = "15:04" 161 | 162 | DefaultFormatRuRUFull = "Monday, 2 January 2006 г." // Russian (Russia) 163 | DefaultFormatRuRULong = "2 January 2006 г." 164 | DefaultFormatRuRUMedium = "02 Jan 2006 г." 165 | DefaultFormatRuRUShort = "02.01.06" 166 | DefaultFormatRuRUDateTime = "02.01.06, 15:04" 167 | DefaultFormatRuRUTime = "15:04" 168 | 169 | DefaultFormatEsESFull = "Monday, 2 de January de 2006" // Spanish (Spain) 170 | DefaultFormatEsESLong = "2 de January de 2006" 171 | DefaultFormatEsESMedium = "02/01/2006" 172 | DefaultFormatEsESShort = "02/01/06" 173 | DefaultFormatEsESDateTime = "02/01/06 15:04" 174 | DefaultFormatEsESTime = "15:04" 175 | 176 | DefaultFormatCaESFull = "Monday, 2 de January de 2006" // Spanish (Spain) 177 | DefaultFormatCaESLong = "2 de January de 2006" 178 | DefaultFormatCaESMedium = "02/01/2006" 179 | DefaultFormatCaESShort = "02/01/06" 180 | DefaultFormatCaESDateTime = "02/01/06 15:04" 181 | DefaultFormatCaESTime = "15:04" 182 | 183 | DefaultFormatSvSEFull = "Mondayen den 2:e January 2006" // Swedish (Sweden) 184 | DefaultFormatSvSELong = "2 January 2006" 185 | DefaultFormatSvSEMedium = "2 Jan 2006" 186 | DefaultFormatSvSEShort = "2006-01-02" 187 | DefaultFormatSvSEDateTime = "2006-01-02 15:04" 188 | DefaultFormatSvSETime = "15:04" 189 | 190 | DefaultFormatTrTRFull = "2 January 2006 Monday" // Turkish (Turkey) 191 | DefaultFormatTrTRLong = "2 January 2006" 192 | DefaultFormatTrTRMedium = "2 Jan 2006" 193 | DefaultFormatTrTRShort = "2.01.2006" 194 | DefaultFormatTrTRDateTime = "2.01.2006 15:04" 195 | DefaultFormatTrTRTime = "15:04" 196 | 197 | DefaultFormatUkUAFull = "Monday, 2 January 2006 р." // Ukrainian (Ukraine) 198 | DefaultFormatUkUALong = "2 January 2006 р." 199 | DefaultFormatUkUAMedium = "02 Jan 2006 р." 200 | DefaultFormatUkUAShort = "02.01.06" 201 | DefaultFormatUkUADateTime = "02.01.06, 15:04" 202 | DefaultFormatUkUATime = "15:04" 203 | 204 | DefaultFormatBgBGFull = "Monday, 2 January 2006" // Bulgarian (Bulgaria) 205 | DefaultFormatBgBGLong = "2 January 2006" 206 | DefaultFormatBgBGMedium = "2 Jan 2006" 207 | DefaultFormatBgBGShort = "2.01.2006" 208 | DefaultFormatBgBGDateTime = "2.01.2006 15:04" 209 | DefaultFormatBgBGTime = "15:04" 210 | 211 | DefaultFormatZhCNFull = "2006年1月2日 Monday" // Chinese (Mainland) 212 | DefaultFormatZhCNLong = "2006年1月2日" 213 | DefaultFormatZhCNMedium = "2006-01-02" 214 | DefaultFormatZhCNShort = "2006/1/2" 215 | DefaultFormatZhCNDateTime = "2006-01-02 15:04" 216 | DefaultFormatZhCNTime = "15:04" 217 | 218 | DefaultFormatZhTWFull = "2006年1月2日 Monday" // Chinese (Taiwan) 219 | DefaultFormatZhTWLong = "2006年1月2日" 220 | DefaultFormatZhTWMedium = "2006-01-02" 221 | DefaultFormatZhTWShort = "2006/1/2" 222 | DefaultFormatZhTWDateTime = "2006-01-02 15:04" 223 | DefaultFormatZhTWTime = "15:04" 224 | 225 | DefaultFormatZhHKFull = "2006年1月2日 Monday" // Chinese (Hong Kong) 226 | DefaultFormatZhHKLong = "2006年1月2日" 227 | DefaultFormatZhHKMedium = "2006-01-02" 228 | DefaultFormatZhHKShort = "2006/1/2" 229 | DefaultFormatZhHKDateTime = "2006-01-02 15:04" 230 | DefaultFormatZhHKTime = "15:04" 231 | 232 | DefaultFormatKoKRFull = "2006년1월2일 월요일" // Korean (Korea) 233 | DefaultFormatKoKRLong = "2006년1월2일" 234 | DefaultFormatKoKRMedium = "2006-01-02" 235 | DefaultFormatKoKRShort = "2006/1/2" 236 | DefaultFormatKoKRDateTime = "2006-01-02 15:04" 237 | DefaultFormatKoKRTime = "15:04" 238 | 239 | DefaultFormatJaJPFull = "2006年1月2日 Monday" // Japanese (Japan) 240 | DefaultFormatJaJPLong = "2006年1月2日" 241 | DefaultFormatJaJPMedium = "2006/01/02" 242 | DefaultFormatJaJPShort = "2006/1/2" 243 | DefaultFormatJaJPDateTime = "2006/01/02 15:04" 244 | DefaultFormatJaJPTime = "15:04" 245 | 246 | DefaultFormatElGRFull = "Monday, 2 January 2006" // Greek (Greece) 247 | DefaultFormatElGRLong = "2 January 2006" 248 | DefaultFormatElGRMedium = "2 Jan 2006" 249 | DefaultFormatElGRShort = "02/01/06" 250 | DefaultFormatElGRDateTime = "02/01/06 15:04" 251 | DefaultFormatElGRTime = "15:04" 252 | 253 | DefaultFormatCsCZFull = "Monday, 2. January 2006" // Czech (Czech Republic) 254 | DefaultFormatCsCZLong = "2. January 2006" 255 | DefaultFormatCsCZMedium = "02 Jan 2006" 256 | DefaultFormatCsCZShort = "02/01/2006" 257 | DefaultFormatCsCZDateTime = "02/01/2006 15:04" 258 | DefaultFormatCsCZTime = "15:04" 259 | 260 | DefaultFormatLtLTFull = "2006 m. January 2 d., Monday" // Lithuanian (Lithuania) 261 | DefaultFormatLtLTLong = "2006 January 2 d." 262 | DefaultFormatLtLTMedium = "2006 Jan 2" 263 | DefaultFormatLtLTShort = "2006-01-02" 264 | DefaultFormatLtLTDateTime = "2006-01-02, 15:04" 265 | DefaultFormatLtLTTime = "15:04" 266 | 267 | DefaultFormatEtEEFull = "Monday, 2. January 2006" // Estonian (Estonia) 268 | DefaultFormatEtEELong = "2. January 2006" 269 | DefaultFormatEtEEMedium = "2. Jan 2006" 270 | DefaultFormatEtEEShort = "2.1.2006" 271 | DefaultFormatEtEEDateTime = "2.1.2006 15:04" 272 | DefaultFormatEtEETime = "2.1.2006 15:04" 273 | 274 | DefaultFormatHrHRFull = "Monday, 2. January 2006." // Croatian (Croatia) 275 | DefaultFormatHrHRLong = "2. January 2006." 276 | DefaultFormatHrHRMedium = "2. Jan 2006." 277 | DefaultFormatHrHRShort = "2.1.2006." 278 | DefaultFormatHrHRDateTime = "2.1.2006. 15:04" 279 | DefaultFormatHrHRTime = "15:04" 280 | 281 | DefaultFormatLvLVFull = "Monday, 2006. gada 2. January" // Latvian (Latvia) 282 | DefaultFormatLvLVLong = "2006. gada 2. January" 283 | DefaultFormatLvLVMedium = "2006. g. 2. Jan." 284 | DefaultFormatLvLVShort = "2.1.2006." 285 | DefaultFormatLvLVDateTime = "2.1.2006. 15:04" 286 | DefaultFormatLvLVTime = "15:04" 287 | 288 | DefaultFormatSkSKFull = "Monday, 2. January 2006" // Slovak (Slovakia) 289 | DefaultFormatSkSKLong = "2. January 2006" 290 | DefaultFormatSkSKMedium = "2. 1. 2006" 291 | DefaultFormatSkSKShort = "2. 1. 2006" 292 | DefaultFormatSkSKDateTime = "2. 1. 2006, 15:04" 293 | DefaultFormatSkSKTime = "15:04" 294 | 295 | DefaultFormatThTHFull = "Monday ที่ 2 January 2006" // Thai (Thailand) 296 | DefaultFormatThTHLong = "วันที่ 2 January 2006" 297 | DefaultFormatThTHMedium = "2 Jan 2006" 298 | DefaultFormatThTHShort = "02/01/2006" 299 | DefaultFormatThTHDateTime = "02/01/2006 15:04" 300 | DefaultFormatThTHTime = "15:04" 301 | 302 | DefaultFormatUzUZFull = "Monday, 02 January 2006" // Uzbek (Uzbekistan) 303 | DefaultFormatUzUZLong = "2 January 2006" 304 | DefaultFormatUzUZMedium = "2 Jan 2006" 305 | DefaultFormatUzUZShort = "02.01.2006" 306 | DefaultFormatUzUZDateTime = "02.01.2006 15:04" 307 | DefaultFormatUzUZTime = "15:04" 308 | 309 | DefaultFormatKkKZFull = "Monday, 2 January 2006 ж." // Kazakh (Kazakhstan) 310 | DefaultFormatKkKZLong = "2 January 2006 ж." 311 | DefaultFormatKkKZMedium = "02 Jan 2006 ж." 312 | DefaultFormatKkKZShort = "02.01.06" 313 | DefaultFormatKkKZDateTime = "02.01.06, 15:04" 314 | DefaultFormatKkKZTime = "15:04" 315 | 316 | DefaultFormatSlSIFull = "Monday, 2. January 2006" // Slovenian (Slovenia) 317 | DefaultFormatSlSILong = "2. January 2006" 318 | DefaultFormatSlSIMedium = "02.01.2006" 319 | DefaultFormatSlSIShort = "2. 1. 06" 320 | DefaultFormatSlSIDateTime = "2. 1. 2006 15:04" 321 | DefaultFormatSlSITime = "15:04" 322 | ) 323 | 324 | // FullFormatsByLocale maps locales to the'full' date formats for all 325 | // supported locales. 326 | var FullFormatsByLocale = map[Locale]string{ 327 | LocaleEnUS: DefaultFormatEnUSFull, 328 | LocaleEnGB: DefaultFormatEnGBFull, 329 | LocaleDaDK: DefaultFormatDaDKFull, 330 | LocaleNlBE: DefaultFormatNlBEFull, 331 | LocaleNlNL: DefaultFormatNlNLFull, 332 | LocaleFiFI: DefaultFormatFiFIFull, 333 | LocaleFrFR: DefaultFormatFrFRFull, 334 | LocaleFrCA: DefaultFormatFrCAFull, 335 | LocaleFrGP: DefaultFormatFrGPFull, 336 | LocaleFrLU: DefaultFormatFrLUFull, 337 | LocaleFrMQ: DefaultFormatFrMQFull, 338 | LocaleFrGF: DefaultFormatFrGFFull, 339 | LocaleFrRE: DefaultFormatFrREFull, 340 | LocaleDeDE: DefaultFormatDeDEFull, 341 | LocaleHuHU: DefaultFormatHuHUFull, 342 | LocaleItIT: DefaultFormatItITFull, 343 | LocaleNnNO: DefaultFormatNnNOFull, 344 | LocaleNbNO: DefaultFormatNbNOFull, 345 | LocalePtPT: DefaultFormatPtPTFull, 346 | LocalePtBR: DefaultFormatPtBRFull, 347 | LocaleRoRO: DefaultFormatRoROFull, 348 | LocaleRuRU: DefaultFormatRuRUFull, 349 | LocaleEsES: DefaultFormatEsESFull, 350 | LocaleCaES: DefaultFormatCaESFull, 351 | LocaleSvSE: DefaultFormatSvSEFull, 352 | LocaleTrTR: DefaultFormatTrTRFull, 353 | LocaleBgBG: DefaultFormatBgBGFull, 354 | LocaleZhCN: DefaultFormatZhCNFull, 355 | LocaleZhTW: DefaultFormatZhTWFull, 356 | LocaleZhHK: DefaultFormatZhHKFull, 357 | LocaleKoKR: DefaultFormatKoKRFull, 358 | LocaleJaJP: DefaultFormatJaJPFull, 359 | LocaleElGR: DefaultFormatElGRFull, 360 | LocaleCsCZ: DefaultFormatCsCZFull, 361 | LocaleUkUA: DefaultFormatUkUAFull, 362 | LocaleLtLT: DefaultFormatLtLTFull, 363 | LocaleEtEE: DefaultFormatEtEEFull, 364 | LocaleHrHR: DefaultFormatHrHRFull, 365 | LocaleLvLV: DefaultFormatLvLVFull, 366 | LocaleSkSK: DefaultFormatSkSKFull, 367 | LocaleThTH: DefaultFormatThTHFull, 368 | LocaleUzUZ: DefaultFormatUzUZFull, 369 | LocaleKkKZ: DefaultFormatKkKZFull, 370 | LocaleSlSI: DefaultFormatSlSIFull, 371 | } 372 | 373 | // LongFormatsByLocale maps locales to the 'long' date formats for all 374 | // supported locales. 375 | var LongFormatsByLocale = map[Locale]string{ 376 | LocaleEnUS: DefaultFormatEnUSLong, 377 | LocaleEnGB: DefaultFormatEnGBLong, 378 | LocaleDaDK: DefaultFormatDaDKLong, 379 | LocaleNlBE: DefaultFormatNlBELong, 380 | LocaleNlNL: DefaultFormatNlNLLong, 381 | LocaleFiFI: DefaultFormatFiFILong, 382 | LocaleFrFR: DefaultFormatFrFRLong, 383 | LocaleFrCA: DefaultFormatFrCALong, 384 | LocaleFrGP: DefaultFormatFrGPLong, 385 | LocaleFrLU: DefaultFormatFrLULong, 386 | LocaleFrMQ: DefaultFormatFrMQLong, 387 | LocaleFrRE: DefaultFormatFrRELong, 388 | LocaleFrGF: DefaultFormatFrGFLong, 389 | LocaleDeDE: DefaultFormatDeDELong, 390 | LocaleHuHU: DefaultFormatHuHULong, 391 | LocaleItIT: DefaultFormatItITLong, 392 | LocaleNnNO: DefaultFormatNnNOLong, 393 | LocaleNbNO: DefaultFormatNbNOLong, 394 | LocalePtPT: DefaultFormatPtPTLong, 395 | LocalePtBR: DefaultFormatPtBRLong, 396 | LocaleRoRO: DefaultFormatRoROLong, 397 | LocaleRuRU: DefaultFormatRuRULong, 398 | LocaleEsES: DefaultFormatEsESLong, 399 | LocaleCaES: DefaultFormatCaESLong, 400 | LocaleSvSE: DefaultFormatSvSELong, 401 | LocaleTrTR: DefaultFormatTrTRLong, 402 | LocaleBgBG: DefaultFormatBgBGLong, 403 | LocaleZhCN: DefaultFormatZhCNLong, 404 | LocaleZhTW: DefaultFormatZhTWLong, 405 | LocaleZhHK: DefaultFormatZhHKLong, 406 | LocaleKoKR: DefaultFormatKoKRLong, 407 | LocaleJaJP: DefaultFormatJaJPLong, 408 | LocaleElGR: DefaultFormatElGRLong, 409 | LocaleCsCZ: DefaultFormatCsCZLong, 410 | LocaleUkUA: DefaultFormatUkUALong, 411 | LocaleLtLT: DefaultFormatLtLTLong, 412 | LocaleEtEE: DefaultFormatEtEELong, 413 | LocaleHrHR: DefaultFormatHrHRLong, 414 | LocaleLvLV: DefaultFormatLvLVLong, 415 | LocaleSkSK: DefaultFormatSkSKLong, 416 | LocaleThTH: DefaultFormatThTHLong, 417 | LocaleUzUZ: DefaultFormatUzUZLong, 418 | LocaleKkKZ: DefaultFormatKkKZLong, 419 | LocaleSlSI: DefaultFormatSlSILong, 420 | } 421 | 422 | // MediumFormatsByLocale maps locales to the 'medium' date formats for all 423 | // supported locales. 424 | var MediumFormatsByLocale = map[Locale]string{ 425 | LocaleEnUS: DefaultFormatEnUSMedium, 426 | LocaleEnGB: DefaultFormatEnGBMedium, 427 | LocaleDaDK: DefaultFormatDaDKMedium, 428 | LocaleNlBE: DefaultFormatNlBEMedium, 429 | LocaleNlNL: DefaultFormatNlNLMedium, 430 | LocaleFiFI: DefaultFormatFiFIMedium, 431 | LocaleFrFR: DefaultFormatFrFRMedium, 432 | LocaleFrGP: DefaultFormatFrGPMedium, 433 | LocaleFrCA: DefaultFormatFrCAMedium, 434 | LocaleFrLU: DefaultFormatFrLUMedium, 435 | LocaleFrMQ: DefaultFormatFrMQMedium, 436 | LocaleFrGF: DefaultFormatFrGFMedium, 437 | LocaleFrRE: DefaultFormatFrREMedium, 438 | LocaleDeDE: DefaultFormatDeDEMedium, 439 | LocaleHuHU: DefaultFormatHuHUMedium, 440 | LocaleItIT: DefaultFormatItITMedium, 441 | LocaleNnNO: DefaultFormatNnNOMedium, 442 | LocaleNbNO: DefaultFormatNbNOMedium, 443 | LocalePtPT: DefaultFormatPtPTMedium, 444 | LocalePtBR: DefaultFormatPtBRMedium, 445 | LocaleRoRO: DefaultFormatRoROMedium, 446 | LocaleRuRU: DefaultFormatRuRUMedium, 447 | LocaleEsES: DefaultFormatEsESMedium, 448 | LocaleCaES: DefaultFormatCaESMedium, 449 | LocaleSvSE: DefaultFormatSvSEMedium, 450 | LocaleTrTR: DefaultFormatTrTRMedium, 451 | LocaleBgBG: DefaultFormatBgBGMedium, 452 | LocaleZhCN: DefaultFormatZhCNMedium, 453 | LocaleZhTW: DefaultFormatZhTWMedium, 454 | LocaleZhHK: DefaultFormatZhHKMedium, 455 | LocaleKoKR: DefaultFormatKoKRMedium, 456 | LocaleJaJP: DefaultFormatJaJPMedium, 457 | LocaleElGR: DefaultFormatElGRMedium, 458 | LocaleCsCZ: DefaultFormatCsCZMedium, 459 | LocaleUkUA: DefaultFormatUkUAMedium, 460 | LocaleLtLT: DefaultFormatLtLTMedium, 461 | LocaleEtEE: DefaultFormatEtEEMedium, 462 | LocaleHrHR: DefaultFormatHrHRMedium, 463 | LocaleLvLV: DefaultFormatLvLVMedium, 464 | LocaleSkSK: DefaultFormatSkSKMedium, 465 | LocaleThTH: DefaultFormatThTHMedium, 466 | LocaleUzUZ: DefaultFormatUzUZMedium, 467 | LocaleKkKZ: DefaultFormatKkKZMedium, 468 | LocaleSlSI: DefaultFormatSlSIMedium, 469 | } 470 | 471 | // ShortFormatsByLocale maps locales to the 'short' date formats for all 472 | // supported locales. 473 | var ShortFormatsByLocale = map[Locale]string{ 474 | LocaleEnUS: DefaultFormatEnUSShort, 475 | LocaleEnGB: DefaultFormatEnGBShort, 476 | LocaleDaDK: DefaultFormatDaDKShort, 477 | LocaleNlBE: DefaultFormatNlBEShort, 478 | LocaleNlNL: DefaultFormatNlNLShort, 479 | LocaleFiFI: DefaultFormatFiFIShort, 480 | LocaleFrFR: DefaultFormatFrFRShort, 481 | LocaleFrCA: DefaultFormatFrCAShort, 482 | LocaleFrLU: DefaultFormatFrLUShort, 483 | LocaleFrMQ: DefaultFormatFrMQShort, 484 | LocaleFrGF: DefaultFormatFrGFShort, 485 | LocaleFrGP: DefaultFormatFrGPShort, 486 | LocaleFrRE: DefaultFormatFrREShort, 487 | LocaleDeDE: DefaultFormatDeDEShort, 488 | LocaleHuHU: DefaultFormatHuHUShort, 489 | LocaleItIT: DefaultFormatItITShort, 490 | LocaleNnNO: DefaultFormatNnNOShort, 491 | LocaleNbNO: DefaultFormatNbNOShort, 492 | LocalePtPT: DefaultFormatPtPTShort, 493 | LocalePtBR: DefaultFormatPtBRShort, 494 | LocaleRoRO: DefaultFormatRoROShort, 495 | LocaleRuRU: DefaultFormatRuRUShort, 496 | LocaleEsES: DefaultFormatEsESShort, 497 | LocaleCaES: DefaultFormatCaESShort, 498 | LocaleSvSE: DefaultFormatSvSEShort, 499 | LocaleTrTR: DefaultFormatTrTRShort, 500 | LocaleBgBG: DefaultFormatBgBGShort, 501 | LocaleZhCN: DefaultFormatZhCNShort, 502 | LocaleZhTW: DefaultFormatZhTWShort, 503 | LocaleZhHK: DefaultFormatZhHKShort, 504 | LocaleKoKR: DefaultFormatKoKRShort, 505 | LocaleJaJP: DefaultFormatJaJPShort, 506 | LocaleElGR: DefaultFormatElGRShort, 507 | LocaleCsCZ: DefaultFormatCsCZShort, 508 | LocaleUkUA: DefaultFormatUkUAShort, 509 | LocaleLtLT: DefaultFormatLtLTShort, 510 | LocaleEtEE: DefaultFormatEtEEShort, 511 | LocaleHrHR: DefaultFormatHrHRShort, 512 | LocaleLvLV: DefaultFormatLvLVShort, 513 | LocaleSkSK: DefaultFormatSkSKShort, 514 | LocaleUzUZ: DefaultFormatUzUZShort, 515 | LocaleKkKZ: DefaultFormatKkKZShort, 516 | LocaleSlSI: DefaultFormatSlSIShort, 517 | } 518 | 519 | // DateTimeFormatsByLocale maps locales to the 'DateTime' date formats for 520 | // all supported locales. 521 | var DateTimeFormatsByLocale = map[Locale]string{ 522 | LocaleEnUS: DefaultFormatEnUSDateTime, 523 | LocaleEnGB: DefaultFormatEnGBDateTime, 524 | LocaleDaDK: DefaultFormatDaDKDateTime, 525 | LocaleNlBE: DefaultFormatNlBEDateTime, 526 | LocaleNlNL: DefaultFormatNlNLDateTime, 527 | LocaleFiFI: DefaultFormatFiFIDateTime, 528 | LocaleFrFR: DefaultFormatFrFRDateTime, 529 | LocaleFrCA: DefaultFormatFrCADateTime, 530 | LocaleFrGP: DefaultFormatFrGPDateTime, 531 | LocaleFrLU: DefaultFormatFrLUDateTime, 532 | LocaleFrMQ: DefaultFormatFrMQDateTime, 533 | LocaleFrGF: DefaultFormatFrGFDateTime, 534 | LocaleFrRE: DefaultFormatFrREDateTime, 535 | LocaleDeDE: DefaultFormatDeDEDateTime, 536 | LocaleHuHU: DefaultFormatHuHUDateTime, 537 | LocaleItIT: DefaultFormatItITDateTime, 538 | LocaleNnNO: DefaultFormatNnNODateTime, 539 | LocaleNbNO: DefaultFormatNbNODateTime, 540 | LocalePtPT: DefaultFormatPtPTDateTime, 541 | LocalePtBR: DefaultFormatPtBRDateTime, 542 | LocaleRoRO: DefaultFormatRoRODateTime, 543 | LocaleRuRU: DefaultFormatRuRUDateTime, 544 | LocaleEsES: DefaultFormatEsESDateTime, 545 | LocaleCaES: DefaultFormatCaESDateTime, 546 | LocaleSvSE: DefaultFormatSvSEDateTime, 547 | LocaleTrTR: DefaultFormatTrTRDateTime, 548 | LocaleBgBG: DefaultFormatBgBGDateTime, 549 | LocaleZhCN: DefaultFormatZhCNDateTime, 550 | LocaleZhTW: DefaultFormatZhTWDateTime, 551 | LocaleZhHK: DefaultFormatZhHKDateTime, 552 | LocaleKoKR: DefaultFormatKoKRDateTime, 553 | LocaleJaJP: DefaultFormatJaJPDateTime, 554 | LocaleElGR: DefaultFormatElGRDateTime, 555 | LocaleCsCZ: DefaultFormatCsCZDateTime, 556 | LocaleUkUA: DefaultFormatUkUADateTime, 557 | LocaleLtLT: DefaultFormatLtLTDateTime, 558 | LocaleEtEE: DefaultFormatEtEEDateTime, 559 | LocaleHrHR: DefaultFormatHrHRDateTime, 560 | LocaleLvLV: DefaultFormatLvLVDateTime, 561 | LocaleSkSK: DefaultFormatSkSKDateTime, 562 | LocaleUzUZ: DefaultFormatUzUZDateTime, 563 | LocaleKkKZ: DefaultFormatKkKZDateTime, 564 | LocaleSlSI: DefaultFormatSlSIDateTime, 565 | } 566 | 567 | // TimeFormatsByLocale maps locales to the 'Time' date formats for 568 | // all supported locales. 569 | var TimeFormatsByLocale = map[Locale]string{ 570 | LocaleEnUS: DefaultFormatEnUSTime, 571 | LocaleEnGB: DefaultFormatEnGBTime, 572 | LocaleDaDK: DefaultFormatDaDKTime, 573 | LocaleNlBE: DefaultFormatNlBETime, 574 | LocaleNlNL: DefaultFormatNlNLTime, 575 | LocaleFiFI: DefaultFormatFiFITime, 576 | LocaleFrFR: DefaultFormatFrFRTime, 577 | LocaleFrCA: DefaultFormatFrCATime, 578 | LocaleFrGP: DefaultFormatFrGPTime, 579 | LocaleFrLU: DefaultFormatFrLUTime, 580 | LocaleFrMQ: DefaultFormatFrMQTime, 581 | LocaleFrGF: DefaultFormatFrGFTime, 582 | LocaleFrRE: DefaultFormatFrRETime, 583 | LocaleDeDE: DefaultFormatDeDETime, 584 | LocaleHuHU: DefaultFormatHuHUTime, 585 | LocaleItIT: DefaultFormatItITTime, 586 | LocaleNnNO: DefaultFormatNnNOTime, 587 | LocaleNbNO: DefaultFormatNbNOTime, 588 | LocalePtPT: DefaultFormatPtPTTime, 589 | LocalePtBR: DefaultFormatPtBRTime, 590 | LocaleRoRO: DefaultFormatRoROTime, 591 | LocaleRuRU: DefaultFormatRuRUTime, 592 | LocaleEsES: DefaultFormatEsESTime, 593 | LocaleCaES: DefaultFormatCaESTime, 594 | LocaleSvSE: DefaultFormatSvSETime, 595 | LocaleTrTR: DefaultFormatTrTRTime, 596 | LocaleBgBG: DefaultFormatBgBGTime, 597 | LocaleZhCN: DefaultFormatZhCNTime, 598 | LocaleZhTW: DefaultFormatZhTWTime, 599 | LocaleZhHK: DefaultFormatZhHKTime, 600 | LocaleKoKR: DefaultFormatKoKRTime, 601 | LocaleJaJP: DefaultFormatJaJPTime, 602 | LocaleElGR: DefaultFormatElGRTime, 603 | LocaleCsCZ: DefaultFormatCsCZTime, 604 | LocaleUkUA: DefaultFormatUkUATime, 605 | LocaleLtLT: DefaultFormatLtLTTime, 606 | LocaleUzUZ: DefaultFormatUzUZTime, 607 | LocaleKkKZ: DefaultFormatKkKZTime, 608 | LocaleSlSI: DefaultFormatSlSITime, 609 | } 610 | -------------------------------------------------------------------------------- /default_orders.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | var dayLongOrderMondayFirst = []string{ 4 | "Monday", 5 | "Tuesday", 6 | "Wednesday", 7 | "Thursday", 8 | "Friday", 9 | "Saturday", 10 | "Sunday", 11 | } 12 | 13 | var dayLongOrderSundayFirst = []string{ 14 | "Sunday", 15 | "Monday", 16 | "Tuesday", 17 | "Wednesday", 18 | "Thursday", 19 | "Friday", 20 | "Saturday", 21 | } 22 | 23 | var dayShortOrderMondayFirst = []string{ 24 | "Mon", 25 | "Tue", 26 | "Wed", 27 | "Thu", 28 | "Fri", 29 | "Sat", 30 | "Sun", 31 | } 32 | 33 | var dayShortOrderSundayFirst = []string{ 34 | "Sun", 35 | "Mon", 36 | "Tue", 37 | "Wed", 38 | "Thu", 39 | "Fri", 40 | "Sat", 41 | } 42 | 43 | var monthLongOrder = []string{ 44 | "January", 45 | "February", 46 | "March", 47 | "April", 48 | "May", 49 | "June", 50 | "July", 51 | "August", 52 | "September", 53 | "October", 54 | "November", 55 | "December", 56 | } 57 | 58 | var monthShortOrder = []string{ 59 | "Jan", 60 | "Feb", 61 | "Mar", 62 | "Apr", 63 | "May", 64 | "Jun", 65 | "Jul", 66 | "Aug", 67 | "Sep", 68 | "Oct", 69 | "Nov", 70 | "Dec", 71 | } 72 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package monday is a minimalistic translator for month and day of week names in time.Date objects 3 | 4 | Introduction 5 | 6 | Monday is not an alternative to standard time package. It is a temporary solution to use while 7 | the internationalization features are not ready. 8 | 9 | That's why monday doesn't create any additional parsing algorithms, layout identifiers. It is just 10 | a wrapper for time.Format and time.ParseInLocation and uses all the same layout IDs, constants, etc. 11 | 12 | Usage 13 | 14 | Format usage: 15 | 16 | t := time.Date(2013, 4, 12, 0, 0, 0, 0, time.UTC) 17 | layout := "2 January 2006 15:04:05 MST" 18 | 19 | translationEnUS := monday.Format(t, layout, monday.LocaleEnUS) // Instead of t.Format(layout) 20 | translationRuRU := monday.Format(t, layout, monday.LocaleRuRU) // Instead of t.Format(layout) 21 | ... 22 | 23 | Parse usage: 24 | layout := "2 January 2006 15:04:05 MST" 25 | 26 | // Instead of time.ParseInLocation(layout, "12 April 2013 00:00:00 MST", time.UTC) 27 | parsed := monday.ParseInLocation(layout, "12 April 2013 00:00:00 MST", time.UTC, monday.LocaleEnUS)) 28 | parsed2 = monday.ParseInLocation(layout, "12 апреля 2013 00:00:00 MST", time.UTC, monday.LocaleRuRU)) 29 | ... 30 | 31 | Thread safety 32 | 33 | Monday initializes all its data once in the init func and then uses only 34 | func calls and local vars. Thus, it's thread-safe and doesn't need any mutexes to be 35 | used with. 36 | 37 | */ 38 | package monday 39 | -------------------------------------------------------------------------------- /format_bg_bg.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "bg_BG" locale: Bulgarian (Bulgaria) 5 | // ============================================================ 6 | 7 | var longDayNamesBgBG = map[string]string{ 8 | "Sunday": "Неделя", 9 | "Monday": "Понеделник", 10 | "Tuesday": "Вторник", 11 | "Wednesday": "Сряда", 12 | "Thursday": "Четвъртък", 13 | "Friday": "Петък", 14 | "Saturday": "Събота", 15 | } 16 | 17 | var shortDayNamesBgBG = map[string]string{ 18 | "Sun": "Нд", 19 | "Mon": "Пн", 20 | "Tue": "Вт", 21 | "Wed": "Ср", 22 | "Thu": "Чt", 23 | "Fri": "Пт", 24 | "Sat": "Сб", 25 | } 26 | 27 | var longMonthNamesBgBG = map[string]string{ 28 | "January": "Януари", 29 | "February": "Февруари", 30 | "March": "Март", 31 | "April": "Април", 32 | "May": "Май", 33 | "June": "Юни", 34 | "July": "Юли", 35 | "August": "Август", 36 | "September": "Септември", 37 | "October": "Октомври", 38 | "November": "Ноември", 39 | "December": "Декември", 40 | } 41 | 42 | var shortMonthNamesBgBG = map[string]string{ 43 | "Jan": "Яну", 44 | "Feb": "Фев", 45 | "Mar": "Мар", 46 | "Apr": "Апр", 47 | "May": "Май", 48 | "Jun": "Юни", 49 | "Jul": "Юли", 50 | "Aug": "Авг", 51 | "Sep": "Сеп", 52 | "Oct": "Окт", 53 | "Nov": "Ное", 54 | "Dec": "Дек", 55 | } 56 | -------------------------------------------------------------------------------- /format_ca_es.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "ca_ES" locale: Catalan (Spain) 5 | // ============================================================ 6 | 7 | var longDayNamesCaES = map[string]string{ 8 | "Sunday": "diumenge", 9 | "Monday": "dilluns", 10 | "Tuesday": "dimarts", 11 | "Wednesday": "dimecres", 12 | "Thursday": "dijous", 13 | "Friday": "divendres", 14 | "Saturday": "dissabte", 15 | } 16 | 17 | var shortDayNamesCaES = map[string]string{ 18 | "Sun": "dg", 19 | "Mon": "dl", 20 | "Tue": "dt", 21 | "Wed": "dc", 22 | "Thu": "dj", 23 | "Fri": "dv", 24 | "Sat": "ds", 25 | } 26 | 27 | var longMonthNamesCaES = map[string]string{ 28 | "January": "gener", 29 | "February": "febrer", 30 | "March": "març", 31 | "April": "abril", 32 | "May": "maig", 33 | "June": "juny", 34 | "July": "juliol", 35 | "August": "agost", 36 | "September": "setembre", 37 | "October": "octubre", 38 | "November": "novembre", 39 | "December": "desembre", 40 | } 41 | 42 | var shortMonthNamesCaES = map[string]string{ 43 | "Jan": "gen", 44 | "Feb": "febr", 45 | "Mar": "març", 46 | "Apr": "abr", 47 | "May": "maig", 48 | "Jun": "juny", 49 | "Jul": "jul", 50 | "Aug": "ag", 51 | "Sep": "set", 52 | "Oct": "oct", 53 | "Nov": "nov", 54 | "Dec": "des", 55 | } 56 | -------------------------------------------------------------------------------- /format_common.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "strings" 4 | 5 | func findInString(where string, what string, foundIndex *int, trimRight *int) (found bool) { 6 | ind := strings.Index(strings.ToLower(where), strings.ToLower(what)) 7 | if ind != -1 { 8 | *foundIndex = ind 9 | *trimRight = len(where) - ind - len(what) 10 | return true 11 | } 12 | 13 | return false 14 | } 15 | 16 | // commonFormatFunc is used for languages which don't have changed forms of month names dependent 17 | // on their position (after day or standalone) 18 | func commonFormatFunc(value, format string, 19 | knownDaysShort, knownDaysLong, knownMonthsShort, knownMonthsLong, knownPeriods map[string]string) string { 20 | l := stringToLayoutItems(value) 21 | f := stringToLayoutItems(format) 22 | if len(l) != len(f) { 23 | return value // layouts does not matches 24 | } 25 | 26 | sb := &strings.Builder{} 27 | sb.Grow(32) // Reasonable default size that should fit most strings. 28 | 29 | for i, v := range l { 30 | 31 | var knw map[string]string 32 | 33 | // number of symbols before replaced term 34 | foundIndex := 0 35 | trimRight := 0 36 | lowerCase := false 37 | switch { 38 | case findInString(f[i].item, "Monday", &foundIndex, &trimRight): 39 | knw = knownDaysLong 40 | case findInString(f[i].item, "Mon", &foundIndex, &trimRight): 41 | knw = knownDaysShort 42 | case findInString(f[i].item, "January", &foundIndex, &trimRight): 43 | knw = knownMonthsLong 44 | case findInString(f[i].item, "Jan", &foundIndex, &trimRight): 45 | knw = knownMonthsShort 46 | case findInString(f[i].item, "PM", &foundIndex, &trimRight): 47 | knw = knownPeriods 48 | case findInString(f[i].item, "pm", &foundIndex, &trimRight): 49 | lowerCase = true 50 | knw = knownPeriods 51 | } 52 | 53 | knw = mapToLowerCase(knw) 54 | 55 | if knw != nil { 56 | trimmedItem := strings.ToLower(v.item[foundIndex : len(v.item)-trimRight]) 57 | 58 | tr, ok := knw[trimmedItem] 59 | if lowerCase == true { 60 | tr = strings.ToLower(tr) 61 | } 62 | 63 | if ok { 64 | sb.WriteString(v.item[:foundIndex]) 65 | sb.WriteString(tr) 66 | sb.WriteString(v.item[len(v.item)-trimRight:]) 67 | } else { 68 | sb.WriteString(v.item) 69 | } 70 | } else { 71 | sb.WriteString(v.item) 72 | } 73 | } 74 | return sb.String() 75 | } 76 | 77 | func hasDigitBefore(l []dateStringLayoutItem, position int) bool { 78 | if position >= 2 { 79 | return l[position-2].isDigit && len(l[position-2].item) <= 2 80 | } 81 | return false 82 | } 83 | 84 | // commonGenitiveFormatFunc is used for languages with genitive forms of names, like Russian. 85 | func commonGenitiveFormatFunc(value, format string, 86 | knownDaysShort, knownDaysLong, knownMonthsShort, knownMonthsLong, 87 | knownMonthsGenShort, knownMonthsGenLong, knownPeriods map[string]string) string { 88 | 89 | l := stringToLayoutItems(value) 90 | f := stringToLayoutItems(format) 91 | 92 | if len(l) != len(f) { 93 | return value // layouts does not matches 94 | } 95 | 96 | sb := &strings.Builder{} 97 | sb.Grow(32) // Reasonable default size that should fit most strings. 98 | 99 | for i, v := range l { 100 | lowerCase := false 101 | var knw map[string]string 102 | switch f[i].item { 103 | case "Mon": 104 | knw = knownDaysShort 105 | case "Monday": 106 | knw = knownDaysLong 107 | case "Jan": 108 | if hasDigitBefore(l, i) { 109 | knw = knownMonthsGenShort 110 | } else { 111 | knw = knownMonthsShort 112 | } 113 | case "January": 114 | if hasDigitBefore(l, i) { 115 | knw = knownMonthsGenLong 116 | } else { 117 | knw = knownMonthsLong 118 | } 119 | case "PM": 120 | knw = knownPeriods 121 | case "pm": 122 | lowerCase = true 123 | knw = knownPeriods 124 | } 125 | 126 | knw = mapToLowerCase(knw) 127 | 128 | if knw != nil { 129 | tr, ok := knw[strings.ToLower(v.item)] 130 | if !ok { 131 | sb.WriteString(v.item) 132 | continue 133 | } 134 | if lowerCase == true { 135 | tr = strings.ToLower(tr) 136 | } 137 | sb.WriteString(tr) 138 | } else { 139 | sb.WriteString(v.item) 140 | } 141 | } 142 | return sb.String() 143 | } 144 | 145 | func createCommonFormatFunc(locale Locale) internalFormatFunc { 146 | return func(value, layout string) (res string) { 147 | return commonFormatFunc(value, layout, 148 | knownDaysShort[locale], knownDaysLong[locale], knownMonthsShort[locale], knownMonthsLong[locale], knownPeriods[locale]) 149 | } 150 | } 151 | 152 | func createCommonFormatFuncWithGenitive(locale Locale) internalFormatFunc { 153 | return func(value, layout string) (res string) { 154 | return commonGenitiveFormatFunc(value, layout, 155 | knownDaysShort[locale], knownDaysLong[locale], knownMonthsShort[locale], knownMonthsLong[locale], 156 | knownMonthsGenitiveShort[locale], knownMonthsGenitiveLong[locale], knownPeriods[locale]) 157 | } 158 | } 159 | 160 | func createCommonParseFunc(locale Locale) internalParseFunc { 161 | return func(layout, value string) string { 162 | return commonFormatFunc(value, layout, 163 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 164 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriodsReverse[locale]) 165 | } 166 | } 167 | 168 | func createCommonParseFuncWithGenitive(locale Locale) internalParseFunc { 169 | return func(layout, value string) (res string) { 170 | return commonGenitiveFormatFunc(value, layout, 171 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 172 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], 173 | knownMonthsGenitiveShortReverse[locale], knownMonthsGenitiveLongReverse[locale], knownPeriodsReverse[locale]) 174 | } 175 | } 176 | 177 | func mapToLowerCase(source map[string]string) map[string]string { 178 | result := make(map[string]string, len(source)) 179 | for k, v := range source { 180 | result[strings.ToLower(k)] = v 181 | } 182 | return result 183 | } 184 | -------------------------------------------------------------------------------- /format_cs_cz.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "cs_CZ" locale: Czech (Czech Republic) 5 | // ============================================================ 6 | 7 | var longDayNamesCsCZ = map[string]string{ 8 | "Sunday": "neděle", 9 | "Monday": "pondělí", 10 | "Tuesday": "úterý", 11 | "Wednesday": "středa", 12 | "Thursday": "čtvrtek", 13 | "Friday": "pátek", 14 | "Saturday": "sobota", 15 | } 16 | 17 | var shortDayNamesCsCZ = map[string]string{ 18 | "Sun": "ne", 19 | "Mon": "po", 20 | "Tue": "út", 21 | "Wed": "st", 22 | "Thu": "čt", 23 | "Fri": "pá", 24 | "Sat": "so", 25 | } 26 | 27 | var longMonthNamesCsCZ = map[string]string{ 28 | "January": "leden", 29 | "February": "únor", 30 | "March": "březen", 31 | "April": "duben", 32 | "May": "květen", 33 | "June": "červen", 34 | "July": "červenec", 35 | "August": "srpen", 36 | "September": "září", 37 | "October": "říjen", 38 | "November": "listopad", 39 | "December": "prosinec", 40 | } 41 | 42 | var shortMonthNamesCsCZ = map[string]string{ 43 | "Jan": "led", 44 | "Feb": "úno", 45 | "Mar": "bře", 46 | "Apr": "dub", 47 | "May": "kvě", 48 | "Jun": "čvn", 49 | "Jul": "čvc", 50 | "Aug": "srp", 51 | "Sep": "zář", 52 | "Oct": "říj", 53 | "Nov": "lis", 54 | "Dec": "pro", 55 | } 56 | 57 | var longMonthNamesGenitiveCsCZ = map[string]string{ 58 | "January": "ledna", 59 | "February": "února", 60 | "March": "března", 61 | "April": "dubna", 62 | "May": "května", 63 | "June": "června", 64 | "July": "července", 65 | "August": "srpna", 66 | "September": "září", 67 | "October": "října", 68 | "November": "listopadu", 69 | "December": "prosince", 70 | } 71 | 72 | var shortMonthNamesGenitiveCsCZ = map[string]string{ 73 | "Jan": "led", 74 | "Feb": "úno", 75 | "Mar": "bře", 76 | "Apr": "dub", 77 | "May": "kvě", 78 | "Jun": "čvn", 79 | "Jul": "čvc", 80 | "Aug": "srp", 81 | "Sep": "zář", 82 | "Oct": "říj", 83 | "Nov": "lis", 84 | "Dec": "pro", 85 | } 86 | -------------------------------------------------------------------------------- /format_da_dk.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "da_DK" locale: Danish (Denmark) 5 | // ============================================================ 6 | 7 | var longDayNamesDaDK = map[string]string{ 8 | "Sunday": "søndag", 9 | "Monday": "mandag", 10 | "Tuesday": "tirsdag", 11 | "Wednesday": "onsdag", 12 | "Thursday": "torsdag", 13 | "Friday": "fredag", 14 | "Saturday": "lørdag", 15 | } 16 | 17 | var shortDayNamesDaDK = map[string]string{ 18 | "Sun": "søn", 19 | "Mon": "man", 20 | "Tue": "tir", 21 | "Wed": "ons", 22 | "Thu": "tor", 23 | "Fri": "fre", 24 | "Sat": "lør", 25 | } 26 | 27 | var longMonthNamesDaDK = map[string]string{ 28 | "January": "januar", 29 | "February": "februar", 30 | "March": "marts", 31 | "April": "april", 32 | "May": "maj", 33 | "June": "juni", 34 | "July": "juli", 35 | "August": "august", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesDaDK = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "maj", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_de_de.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "de_DE" locale: German (Germany) 5 | // ============================================================ 6 | 7 | var longDayNamesDeDE = map[string]string{ 8 | "Sunday": "Sonntag", 9 | "Monday": "Montag", 10 | "Tuesday": "Dienstag", 11 | "Wednesday": "Mittwoch", 12 | "Thursday": "Donnerstag", 13 | "Friday": "Freitag", 14 | "Saturday": "Samstag", 15 | } 16 | 17 | var shortDayNamesDeDE = map[string]string{ 18 | "Sun": "So", 19 | "Mon": "Mo", 20 | "Tue": "Di", 21 | "Wed": "Mi", 22 | "Thu": "Do", 23 | "Fri": "Fr", 24 | "Sat": "Sa", 25 | } 26 | 27 | var longMonthNamesDeDE = map[string]string{ 28 | "January": "Januar", 29 | "February": "Februar", 30 | "March": "März", 31 | "April": "April", 32 | "May": "Mai", 33 | "June": "Juni", 34 | "July": "Juli", 35 | "August": "August", 36 | "September": "September", 37 | "October": "Oktober", 38 | "November": "November", 39 | "December": "Dezember", 40 | } 41 | 42 | var shortMonthNamesDeDE = map[string]string{ 43 | "Jan": "Jan", 44 | "Feb": "Feb", 45 | "Mar": "Mär", 46 | "Apr": "Apr", 47 | "May": "Mai", 48 | "Jun": "Juni", 49 | "Jul": "Juli", 50 | "Aug": "Aug", 51 | "Sep": "Sep", 52 | "Oct": "Okt", 53 | "Nov": "Nov", 54 | "Dec": "Dez", 55 | } 56 | -------------------------------------------------------------------------------- /format_el_gr.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "el_GR" locale: Greek (Greece) 5 | // ============================================================ 6 | 7 | var longDayNamesElGR = map[string]string{ 8 | "Sunday": "Κυριακή", 9 | "Monday": "Δευτέρα", 10 | "Tuesday": "Τρίτη", 11 | "Wednesday": "Τετάρτη", 12 | "Thursday": "Πέμπτη", 13 | "Friday": "Παρασκευή", 14 | "Saturday": "Σάββατο", 15 | } 16 | 17 | var shortDayNamesElGR = map[string]string{ 18 | "Sun": "Κυρ", 19 | "Mon": "Δευ", 20 | "Tue": "Τρι", 21 | "Wed": "Τετ", 22 | "Thu": "Πεμ", 23 | "Fri": "Παρ", 24 | "Sat": "Σαβ", 25 | } 26 | 27 | var longMonthNamesElGR = map[string]string{ 28 | "January": "Ιανουάριος", 29 | "February": "Φεβρουάριος", 30 | "March": "Μάρτιος", 31 | "April": "Απρίλιος", 32 | "May": "Μάιος", 33 | "June": "Ιούνιος", 34 | "July": "Ιούλιος", 35 | "August": "Αύγουστος", 36 | "September": "Σεπτέμβριος", 37 | "October": "Οκτώβριος", 38 | "November": "Νοέμβριος", 39 | "December": "Δεκέμβριος", 40 | } 41 | 42 | var longMonthNamesGenitiveElGR = map[string]string{ 43 | "January": "Ιανουαρίου", 44 | "February": "Φεβρουαρίου", 45 | "March": "Μαρτίου", 46 | "April": "Απριλίου", 47 | "May": "Μαΐου", 48 | "June": "Ιουνίου", 49 | "July": "Ιουλίου", 50 | "August": "Αυγούστου", 51 | "September": "Σεπτεμβρίου", 52 | "October": "Οκτωβρίου", 53 | "November": "Νοεμβρίου", 54 | "December": "Δεκεμβρίου", 55 | } 56 | 57 | var shortMonthNamesElGR = map[string]string{ 58 | "Jan": "Ιαν", 59 | "Feb": "Φεβ", 60 | "Mar": "Μαρ", 61 | "Apr": "Απρ", 62 | "May": "Μαϊ", 63 | "Jun": "Ιουν", 64 | "Jul": "Ιουλ", 65 | "Aug": "Αυγ", 66 | "Sep": "Σεπ", 67 | "Oct": "Οκτ", 68 | "Nov": "Νοε", 69 | "Dec": "Δεκ", 70 | } 71 | 72 | var periodsElGR = map[string]string{ 73 | "am": "πμ", 74 | "pm": "μμ", 75 | "AM": "ΠΜ", 76 | "PM": "ΜΜ", 77 | } 78 | -------------------------------------------------------------------------------- /format_en_gb.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "en_GB" locale: English (Great Britain) 5 | // ============================================================ 6 | 7 | var longDayNamesEnGB = map[string]string{ 8 | "Sunday": "Sunday", 9 | "Monday": "Monday", 10 | "Tuesday": "Tuesday", 11 | "Wednesday": "Wednesday", 12 | "Thursday": "Thursday", 13 | "Friday": "Friday", 14 | "Saturday": "Saturday", 15 | } 16 | 17 | var shortDayNamesEnGB = map[string]string{ 18 | "Sun": "Sun", 19 | "Mon": "Mon", 20 | "Tue": "Tue", 21 | "Wed": "Wed", 22 | "Thu": "Thu", 23 | "Fri": "Fri", 24 | "Sat": "Sat", 25 | } 26 | 27 | var longMonthNamesEnGB = map[string]string{ 28 | "January": "January", 29 | "February": "February", 30 | "March": "March", 31 | "April": "April", 32 | "May": "May", 33 | "June": "June", 34 | "July": "July", 35 | "August": "August", 36 | "September": "September", 37 | "October": "October", 38 | "November": "November", 39 | "December": "December", 40 | } 41 | 42 | var shortMonthNamesEnGB = map[string]string{ 43 | "Jan": "Jan", 44 | "Feb": "Feb", 45 | "Mar": "Mar", 46 | "Apr": "Apr", 47 | "May": "May", 48 | "Jun": "Jun", 49 | "Jul": "Jul", 50 | "Aug": "Aug", 51 | "Sep": "Sep", 52 | "Oct": "Oct", 53 | "Nov": "Nov", 54 | "Dec": "Dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_en_us.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "en_US" locale: English (United States) 5 | // ============================================================ 6 | 7 | var longDayNamesEnUS = map[string]string{ 8 | "Sunday": "Sunday", 9 | "Monday": "Monday", 10 | "Tuesday": "Tuesday", 11 | "Wednesday": "Wednesday", 12 | "Thursday": "Thursday", 13 | "Friday": "Friday", 14 | "Saturday": "Saturday", 15 | } 16 | 17 | var shortDayNamesEnUS = map[string]string{ 18 | "Sun": "Sun", 19 | "Mon": "Mon", 20 | "Tue": "Tue", 21 | "Wed": "Wed", 22 | "Thu": "Thu", 23 | "Fri": "Fri", 24 | "Sat": "Sat", 25 | } 26 | 27 | var longMonthNamesEnUS = map[string]string{ 28 | "January": "January", 29 | "February": "February", 30 | "March": "March", 31 | "April": "April", 32 | "May": "May", 33 | "June": "June", 34 | "July": "July", 35 | "August": "August", 36 | "September": "September", 37 | "October": "October", 38 | "November": "November", 39 | "December": "December", 40 | } 41 | 42 | var shortMonthNamesEnUS = map[string]string{ 43 | "Jan": "Jan", 44 | "Feb": "Feb", 45 | "Mar": "Mar", 46 | "Apr": "Apr", 47 | "May": "May", 48 | "Jun": "Jun", 49 | "Jul": "Jul", 50 | "Aug": "Aug", 51 | "Sep": "Sep", 52 | "Oct": "Oct", 53 | "Nov": "Nov", 54 | "Dec": "Dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_es_es.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "es_ES" locale: Spanish (Spain) 5 | // ============================================================ 6 | 7 | var longDayNamesEsES = map[string]string{ 8 | "Sunday": "domingo", 9 | "Monday": "lunes", 10 | "Tuesday": "martes", 11 | "Wednesday": "miércoles", 12 | "Thursday": "jueves", 13 | "Friday": "viernes", 14 | "Saturday": "sábado", 15 | } 16 | 17 | var shortDayNamesEsES = map[string]string{ 18 | "Sun": "dom", 19 | "Mon": "lun", 20 | "Tue": "mar", 21 | "Wed": "mié", 22 | "Thu": "jue", 23 | "Fri": "vie", 24 | "Sat": "sáb", 25 | } 26 | 27 | var longMonthNamesEsES = map[string]string{ 28 | "January": "enero", 29 | "February": "febrero", 30 | "March": "marzo", 31 | "April": "abril", 32 | "May": "mayo", 33 | "June": "junio", 34 | "July": "julio", 35 | "August": "agosto", 36 | "September": "septiembre", 37 | "October": "octubre", 38 | "November": "noviembre", 39 | "December": "diciembre", 40 | } 41 | 42 | var shortMonthNamesEsES = map[string]string{ 43 | "Jan": "ene", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "abr", 47 | "May": "may", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "ago", 51 | "Sep": "sep", 52 | "Oct": "oct", 53 | "Nov": "nov", 54 | "Dec": "dic", 55 | } 56 | -------------------------------------------------------------------------------- /format_et_ee.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "et_EE" locale: Estonian (Estonia) 5 | // ============================================================ 6 | 7 | var longDayNamesEtEE = map[string]string{ 8 | "Sunday": "pühapäev", 9 | "Monday": "esmaspäev", 10 | "Tuesday": "teisipäev", 11 | "Wednesday": "kolmapäev", 12 | "Thursday": "neljapäev", 13 | "Friday": "reede", 14 | "Saturday": "laupäev", 15 | } 16 | 17 | var shortDayNamesEtEE = map[string]string{ 18 | "Sun": "P", 19 | "Mon": "E", 20 | "Tue": "T", 21 | "Wed": "K", 22 | "Thu": "N", 23 | "Fri": "R", 24 | "Sat": "L", 25 | } 26 | 27 | var longMonthNamesEtEE = map[string]string{ 28 | "January": "jaanuar", 29 | "February": "veebruar", 30 | "March": "märts", 31 | "April": "aprill", 32 | "May": "mai", 33 | "June": "juuni", 34 | "July": "juuli", 35 | "August": "august", 36 | "September": "september", 37 | "October": "oktoober", 38 | "November": "november", 39 | "December": "detsember", 40 | } 41 | 42 | var shortMonthNamesEtEE = map[string]string{ 43 | "Jan": "jaan", 44 | "Feb": "veebr", 45 | "Mar": "märts", 46 | "Apr": "apr", 47 | "May": "mai", 48 | "Jun": "juuni", 49 | "Jul": "juuli", 50 | "Aug": "aug", 51 | "Sep": "sept", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dets", 55 | } 56 | -------------------------------------------------------------------------------- /format_fi_fi.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "fi_FI" locale: Finnish (Finland) 5 | // ============================================================ 6 | 7 | var longDayNamesFiFI = map[string]string{ 8 | "Sunday": "sunnuntai", 9 | "Monday": "maanantai", 10 | "Tuesday": "tiistai", 11 | "Wednesday": "keskiviikko", 12 | "Thursday": "torstai", 13 | "Friday": "perjantai", 14 | "Saturday": "lauantai", 15 | } 16 | 17 | var shortDayNamesFiFI = map[string]string{ 18 | "Sun": "su", 19 | "Mon": "ma", 20 | "Tue": "ti", 21 | "Wed": "ke", 22 | "Thu": "to", 23 | "Fri": "pe", 24 | "Sat": "la", 25 | } 26 | 27 | var longMonthNamesFiFI = map[string]string{ 28 | "January": "tammikuu", 29 | "February": "helmikuu", 30 | "March": "maaliskuu", 31 | "April": "huhtikuu", 32 | "May": "toukokuu", 33 | "June": "kesäkuu", 34 | "July": "heinäkuu", 35 | "August": "elokuu", 36 | "September": "syyskuu", 37 | "October": "lokakuu", 38 | "November": "marraskuu", 39 | "December": "joulukuu", 40 | } 41 | 42 | var longMonthNamesGenitiveFiFI = map[string]string{ 43 | "January": "tammikuuta", 44 | "February": "helmikuuta", 45 | "March": "maaliskuuta", 46 | "April": "huhtikuuta", 47 | "May": "toukokuuta", 48 | "June": "kesäkuuta", 49 | "July": "heinäkuuta", 50 | "August": "elokuuta", 51 | "September": "syyskuuta", 52 | "October": "lokakuuta", 53 | "November": "marraskuuta", 54 | "December": "joulukuuta", 55 | } 56 | 57 | var shortMonthNamesFiFI = map[string]string{ 58 | "Jan": "tammi", 59 | "Feb": "helmi", 60 | "Mar": "maalis", 61 | "Apr": "huhti", 62 | "May": "touko", 63 | "Jun": "kesä", 64 | "Jul": "heinä", 65 | "Aug": "elo", 66 | "Sep": "syys", 67 | "Oct": "loka", 68 | "Nov": "marras", 69 | "Dec": "joulu", 70 | } 71 | -------------------------------------------------------------------------------- /format_fr_fr.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "fr_FR" locale: French (France) 5 | // ============================================================ 6 | 7 | var longDayNamesFrFR = map[string]string{ 8 | "Sunday": "dimanche", 9 | "Monday": "lundi", 10 | "Tuesday": "mardi", 11 | "Wednesday": "mercredi", 12 | "Thursday": "jeudi", 13 | "Friday": "vendredi", 14 | "Saturday": "samedi", 15 | } 16 | 17 | var shortDayNamesFrFR = map[string]string{ 18 | "Sun": "dim", 19 | "Mon": "lun", 20 | "Tue": "mar", 21 | "Wed": "mer", 22 | "Thu": "jeu", 23 | "Fri": "ven", 24 | "Sat": "sam", 25 | } 26 | 27 | var longMonthNamesFrFR = map[string]string{ 28 | "January": "janvier", 29 | "February": "février", 30 | "March": "mars", 31 | "April": "avril", 32 | "May": "mai", 33 | "June": "juin", 34 | "July": "juillet", 35 | "August": "août", 36 | "September": "septembre", 37 | "October": "octobre", 38 | "November": "novembre", 39 | "December": "décembre", 40 | } 41 | 42 | var shortMonthNamesFrFR = map[string]string{ 43 | "Jan": "janv", 44 | "Feb": "févr", 45 | "Mar": "mars", 46 | "Apr": "avr", 47 | "May": "mai", 48 | "Jun": "juin", 49 | "Jul": "juil", 50 | "Aug": "août", 51 | "Sep": "sept", 52 | "Oct": "oct", 53 | "Nov": "nov", 54 | "Dec": "déc", 55 | } 56 | -------------------------------------------------------------------------------- /format_hr_hr.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "hr_HR" locale: Croatian (Croatia) 5 | // ============================================================ 6 | 7 | var longDayNamesHrHR = map[string]string{ 8 | "Sunday": "nedjelja", 9 | "Monday": "ponedjeljak", 10 | "Tuesday": "utorak", 11 | "Wednesday": "srijeda", 12 | "Thursday": "četvrtak", 13 | "Friday": "petak", 14 | "Saturday": "subota", 15 | } 16 | 17 | var shortDayNamesHrHR = map[string]string{ 18 | "Sun": "ned", 19 | "Mon": "pon", 20 | "Tue": "uto", 21 | "Wed": "sri", 22 | "Thu": "čet", 23 | "Fri": "pet", 24 | "Sat": "sub", 25 | } 26 | 27 | var longMonthNamesHrHR = map[string]string{ 28 | "January": "siječanj", 29 | "February": "veljača", 30 | "March": "ožujak", 31 | "April": "travanj", 32 | "May": "svibanj", 33 | "June": "lipanj", 34 | "July": "srpanj", 35 | "August": "kolovoz", 36 | "September": "rujan", 37 | "October": "listopad", 38 | "November": "studeni", 39 | "December": "prosinac", 40 | } 41 | 42 | var shortMonthNamesHrHR = map[string]string{ 43 | "Jan": "sij", 44 | "Feb": "velj", 45 | "Mar": "ožu", 46 | "Apr": "tra", 47 | "May": "svi", 48 | "Jun": "lip", 49 | "Jul": "srp", 50 | "Aug": "kol", 51 | "Sep": "ruj", 52 | "Oct": "lis", 53 | "Nov": "stu", 54 | "Dec": "pro", 55 | } 56 | -------------------------------------------------------------------------------- /format_hu_hu.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "hu_HU" locale: Hungarian (Hungary) 5 | // ============================================================ 6 | 7 | var longDayNamesHuHU = map[string]string{ 8 | "Sunday": "vasárnap", 9 | "Monday": "hétfő", 10 | "Tuesday": "kedd", 11 | "Wednesday": "szerda", 12 | "Thursday": "csütörtök", 13 | "Friday": "péntek", 14 | "Saturday": "szombat", 15 | } 16 | 17 | var shortDayNamesHuHU = map[string]string{ 18 | "Sun": "V", 19 | "Mon": "H", 20 | "Tue": "K", 21 | "Wed": "Sze", 22 | "Thu": "Cs", 23 | "Fri": "P", 24 | "Sat": "Szo", 25 | } 26 | 27 | var longMonthNamesHuHU = map[string]string{ 28 | "January": "január", 29 | "February": "február", 30 | "March": "március", 31 | "April": "április", 32 | "May": "május", 33 | "June": "június", 34 | "July": "július", 35 | "August": "augusztus", 36 | "September": "szeptember", 37 | "October": "október", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesHuHU = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "febr", 45 | "Mar": "márc", 46 | "Apr": "ápr", 47 | "May": "máj", 48 | "Jun": "jún", 49 | "Jul": "júl", 50 | "Aug": "aug", 51 | "Sep": "szept", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_id_id.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "id_ID" locale: Indonesian (Indonesia) 5 | // ============================================================ 6 | 7 | var longDayNamesIdID = map[string]string{ 8 | "Sunday": "Minggu", 9 | "Monday": "Senin", 10 | "Tuesday": "Selasa", 11 | "Wednesday": "Rabu", 12 | "Thursday": "Kamis", 13 | "Friday": "Jumat", 14 | "Saturday": "Sabtu", 15 | } 16 | 17 | var shortDayNamesIdID = map[string]string{ 18 | "Sun": "Min", 19 | "Mon": "Sen", 20 | "Tue": "Sel", 21 | "Wed": "Rab", 22 | "Thu": "Kam", 23 | "Fri": "Jum", 24 | "Sat": "Sab", 25 | } 26 | 27 | var longMonthNamesIdID = map[string]string{ 28 | "January": "Januari", 29 | "February": "Februari", 30 | "March": "Maret", 31 | "April": "April", 32 | "May": "Mei", 33 | "June": "Juni", 34 | "July": "Juli", 35 | "August": "Agustus", 36 | "September": "September", 37 | "October": "Oktober", 38 | "November": "November", 39 | "December": "Desember", 40 | } 41 | 42 | var shortMonthNamesIdID = map[string]string{ 43 | "Jan": "Jan", 44 | "Feb": "Feb", 45 | "Mar": "Mar", 46 | "Apr": "Apr", 47 | "May": "Mei", 48 | "Jun": "Jun", 49 | "Jul": "Jul", 50 | "Aug": "Agu", 51 | "Sep": "Sep", 52 | "Oct": "Okt", 53 | "Nov": "Nov", 54 | "Dec": "Des", 55 | } 56 | -------------------------------------------------------------------------------- /format_it_it.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "it_IT" locale: Italian (Italy) 5 | // ============================================================ 6 | 7 | var longDayNamesItIT = map[string]string{ 8 | "Sunday": "domenica", 9 | "Monday": "lunedì", 10 | "Tuesday": "martedì", 11 | "Wednesday": "mercoledì", 12 | "Thursday": "giovedì", 13 | "Friday": "venerdì", 14 | "Saturday": "sabato", 15 | } 16 | 17 | var shortDayNamesItIT = map[string]string{ 18 | "Sun": "dom", 19 | "Mon": "lun", 20 | "Tue": "mar", 21 | "Wed": "mer", 22 | "Thu": "gio", 23 | "Fri": "ven", 24 | "Sat": "sab", 25 | } 26 | 27 | var longMonthNamesItIT = map[string]string{ 28 | "January": "gennaio", 29 | "February": "febbraio", 30 | "March": "marzo", 31 | "April": "aprile", 32 | "May": "maggio", 33 | "June": "giugno", 34 | "July": "luglio", 35 | "August": "agosto", 36 | "September": "settembre", 37 | "October": "ottobre", 38 | "November": "novembre", 39 | "December": "dicembre", 40 | } 41 | 42 | var shortMonthNamesItIT = map[string]string{ 43 | "Jan": "gen", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "mag", 48 | "Jun": "giu", 49 | "Jul": "lug", 50 | "Aug": "ago", 51 | "Sep": "set", 52 | "Oct": "ott", 53 | "Nov": "nov", 54 | "Dec": "dic", 55 | } 56 | -------------------------------------------------------------------------------- /format_ja_jp.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // ============================================================ 8 | // Format rules for "ja_JP" locale: Japanese 9 | // ============================================================ 10 | 11 | var longDayNamesJaJP = map[string]string{ 12 | "Sunday": "日曜日", 13 | "Monday": "月曜日", 14 | "Tuesday": "火曜日", 15 | "Wednesday": "水曜日", 16 | "Thursday": "木曜日", 17 | "Friday": "金曜日", 18 | "Saturday": "土曜日", 19 | } 20 | 21 | var shortDayNamesJaJP = map[string]string{ 22 | "Sun": "日", 23 | "Mon": "月", 24 | "Tue": "火", 25 | "Wed": "水", 26 | "Thu": "木", 27 | "Fri": "金", 28 | "Sat": "土", 29 | } 30 | 31 | var longMonthNamesJaJP = map[string]string{ 32 | "January": "1月", 33 | "February": "2月", 34 | "March": "3月", 35 | "April": "4月", 36 | "May": "5月", 37 | "June": "6月", 38 | "July": "7月", 39 | "August": "8月", 40 | "September": "9月", 41 | "October": "10月", 42 | "November": "11月", 43 | "December": "12月", 44 | } 45 | 46 | var shortMonthNamesJaJP = map[string]string{ 47 | "Jan": "1月", 48 | "Feb": "2月", 49 | "Mar": "3月", 50 | "Apr": "4月", 51 | "May": "5月", 52 | "Jun": "6月", 53 | "Jul": "7月", 54 | "Aug": "8月", 55 | "Sep": "9月", 56 | "Oct": "10月", 57 | "Nov": "11月", 58 | "Dec": "12月", 59 | } 60 | 61 | var periodsJaJP = map[string]string{ 62 | "am": "午前", 63 | "pm": "午後", 64 | "AM": "午前", 65 | "PM": "午後", 66 | } 67 | 68 | func parseFuncJaCommon(locale Locale) internalParseFunc { 69 | return func(layout, value string) string { 70 | // This special case is needed because ja_JP... contains month names 71 | // that consist of a number, a delimiter, and '月'. Example: "October" = "10 月" 72 | // 73 | // This means that probably default time package layout IDs like 'January' or 'Jan' 74 | // shouldn't be used in ja_JP. But this is a time-compatible package, so someone 75 | // might actually use those and we need to replace those before doing standard procedures. 76 | for k, v := range knownMonthsLongReverse[locale] { 77 | value = strings.Replace(value, k, v, -1) 78 | } 79 | 80 | value = commonFormatFunc(value, layout, 81 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 82 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale]) 83 | 84 | // knownPeriodsReverse has hash collisions 85 | for k, v := range knownPeriodsReverse[locale] { 86 | targetValue := strings.ToLower(v) 87 | if strings.Index(layout, "PM") != -1 { 88 | targetValue = strings.ToUpper(v) 89 | } 90 | value = strings.Replace(value, k, targetValue, -1) 91 | } 92 | 93 | return value 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /format_kk_kz.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "kk_KZ" locale: Kazakh (Kazakhstan) 5 | // ============================================================ 6 | 7 | var longDayNamesKkKZ = map[string]string{ 8 | "Sunday": "Жексенбі", 9 | "Monday": "Дүйсенбі", 10 | "Tuesday": "Сейсенбі", 11 | "Wednesday": "Сәрсенбі", 12 | "Thursday": "Бейсенбі", 13 | "Friday": "Жұма", 14 | "Saturday": "Сенбі", 15 | } 16 | 17 | var shortDayNamesKkKZ = map[string]string{ 18 | "Sun": "Жс", 19 | "Mon": "Дс", 20 | "Tue": "Сс", 21 | "Wed": "Ср", 22 | "Thu": "Бс", 23 | "Fri": "Жм", 24 | "Sat": "Сб", 25 | } 26 | 27 | var longMonthNamesKkKZ = map[string]string{ 28 | "January": "Қаңтар", 29 | "February": "Ақпан", 30 | "March": "Наурыз", 31 | "April": "Сәуір", 32 | "May": "Мамыр", 33 | "June": "Маусым", 34 | "July": "Шілде", 35 | "August": "Тамыз", 36 | "September": "Қыркүйек", 37 | "October": "Қазан", 38 | "November": "Қараша", 39 | "December": "Желтоқсан", 40 | } 41 | 42 | var longMonthNamesGenitiveKkKZ = map[string]string{ 43 | "January": "қаңтар", 44 | "February": "ақпан", 45 | "March": "наурыз", 46 | "April": "сәуір", 47 | "May": "мамыр", 48 | "June": "маусым", 49 | "July": "шілде", 50 | "August": "тамыз", 51 | "September": "қыркүйек", 52 | "October": "қазан", 53 | "November": "қараша", 54 | "December": "желтоқсан", 55 | } 56 | 57 | var shortMonthNamesKkKZ = map[string]string{ 58 | "Jan": "Қаң", 59 | "Feb": "Ақп", 60 | "Mar": "Нау", 61 | "Apr": "Сәу", 62 | "May": "Мам", 63 | "Jun": "Мау", 64 | "Jul": "Шіл", 65 | "Aug": "Там", 66 | "Sep": "Қыр", 67 | "Oct": "Қаз", 68 | "Nov": "Қар", 69 | "Dec": "Жел", 70 | } 71 | 72 | var shortMonthNamesGenitiveKkKZ = map[string]string{ 73 | "Jan": "қаң", 74 | "Feb": "ақп", 75 | "Mar": "нау", 76 | "Apr": "сәу", 77 | "May": "мам", 78 | "Jun": "мау", 79 | "Jul": "шіл", 80 | "Aug": "там", 81 | "Sep": "қыр", 82 | "Oct": "қаз", 83 | "Nov": "қар", 84 | "Dec": "жел", 85 | } 86 | -------------------------------------------------------------------------------- /format_ko_kr.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "strings" 4 | 5 | // ============================================================ 6 | // Format rules for "ko_KR" locale: Korean (Korea) 7 | // ============================================================ 8 | 9 | var longDayNamesKoKR = map[string]string{ 10 | "Sunday": "일요일", 11 | "Monday": "월요일", 12 | "Tuesday": "화요일", 13 | "Wednesday": "수요일", 14 | "Thursday": "목요일", 15 | "Friday": "금요일", 16 | "Saturday": "토요일", 17 | } 18 | 19 | var shortDayNamesKoKR = map[string]string{ 20 | "Sun": "일", 21 | "Mon": "월", 22 | "Tue": "화", 23 | "Wed": "수", 24 | "Thu": "목", 25 | "Fri": "금", 26 | "Sat": "토", 27 | } 28 | 29 | var longMonthNamesKoKR = map[string]string{ 30 | "January": "1월", 31 | "February": "2월", 32 | "March": "3월", 33 | "April": "4월", 34 | "May": "5월", 35 | "June": "6월", 36 | "July": "7월", 37 | "August": "8월", 38 | "September": "9월", 39 | "October": "10월", 40 | "November": "11월", 41 | "December": "12월", 42 | } 43 | 44 | var shortMonthNamesKoKR = map[string]string{ 45 | "Jan": "1월", 46 | "Feb": "2월", 47 | "Mar": "3월", 48 | "Apr": "4월", 49 | "May": "5월", 50 | "Jun": "6월", 51 | "Jul": "7월", 52 | "Aug": "8월", 53 | "Sep": "9월", 54 | "Oct": "10월", 55 | "Nov": "11월", 56 | "Dec": "12월", 57 | } 58 | 59 | var periodsKoKR = map[string]string{ 60 | "am": "오전", 61 | "pm": "오후", 62 | "AM": "오전", 63 | "PM": "오후", 64 | } 65 | 66 | func parseFuncKoCommon(locale Locale) internalParseFunc { 67 | return func(layout, value string) string { 68 | // This special case is needed because ko_KR... contains month names 69 | // that consist of a number, a delimiter, and '월'. Example: "September" = "9 월" 70 | // 71 | // This means that probably default time package layout IDs like 'January' or 'Jan' 72 | // shouldn't be used in ko_KR. But this is a time-compatible package, so someone 73 | // might actually use those and we need to replace those before doing standard procedures. 74 | 75 | for k, v := range knownMonthsLongReverse[locale] { 76 | value = strings.Replace(value, k, v, -1) 77 | } 78 | 79 | value = commonFormatFunc(value, layout, 80 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 81 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale]) 82 | 83 | // knownPeriodsReverse has hash collisions 84 | for k, v := range knownPeriodsReverse[locale] { 85 | targetValue := strings.ToLower(v) 86 | if strings.Index(layout, "PM") != -1 { 87 | targetValue = strings.ToUpper(v) 88 | } 89 | value = strings.Replace(value, k, targetValue, -1) 90 | } 91 | 92 | return value 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /format_lt_lt.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "lt_LT" locale: Lithuanian (Lithuania) 5 | // ============================================================ 6 | 7 | var longDayNamesLtLT = map[string]string{ 8 | "Sunday": "sekmadienis", 9 | "Monday": "pirmadienis", 10 | "Tuesday": "antradienis", 11 | "Wednesday": "trečiadienis", 12 | "Thursday": "ketvirtadienis", 13 | "Friday": "penktadienis", 14 | "Saturday": "šeštadienis", 15 | } 16 | 17 | var shortDayNamesLtLT = map[string]string{ 18 | "Sun": "VII", 19 | "Mon": "I", 20 | "Tue": "II", 21 | "Wed": "III", 22 | "Thu": "IV", 23 | "Fri": "V", 24 | "Sat": "VI", 25 | } 26 | 27 | var longMonthNamesLtLT = map[string]string{ 28 | "January": "sausis", 29 | "February": "vasaris", 30 | "March": "kovas", 31 | "April": "balandis", 32 | "May": "gegužė", 33 | "June": "birželis", 34 | "July": "liepa", 35 | "August": "rugpjūtis", 36 | "September": "rugsėjis", 37 | "October": "spalis", 38 | "November": "lapkritis", 39 | "December": "gruodis", 40 | } 41 | 42 | var longMonthNamesGenitiveLtLT = map[string]string{ 43 | "January": "sausio", 44 | "February": "vasario", 45 | "March": "kovo", 46 | "April": "balandžio", 47 | "May": "gegužės", 48 | "June": "birželio", 49 | "July": "liepos", 50 | "August": "rugpjūčio", 51 | "September": "rugsėjio", 52 | "October": "spalio", 53 | "November": "lapkričio", 54 | "December": "gruodžio", 55 | } 56 | 57 | var shortMonthNamesLtLT = map[string]string{ 58 | "Jan": "sausis", 59 | "Feb": "vas", 60 | "Mar": "kovas", 61 | "Apr": "bal", 62 | "May": "geg", 63 | "Jun": "birž", 64 | "Jul": "liepa", 65 | "Aug": "rugpj", 66 | "Sep": "rugs", 67 | "Oct": "spalis", 68 | "Nov": "lapkr", 69 | "Dec": "gruodis", 70 | } 71 | 72 | var shortMonthNamesGenitiveLtLT = map[string]string{ 73 | "Jan": "sausio", 74 | "Feb": "vas", 75 | "Mar": "kovo", 76 | "Apr": "bal", 77 | "May": "geg", 78 | "Jun": "birž", 79 | "Jul": "liepos", 80 | "Aug": "rugpj", 81 | "Sep": "rugs", 82 | "Oct": "spalio", 83 | "Nov": "lapkr", 84 | "Dec": "gruodžio", 85 | } 86 | -------------------------------------------------------------------------------- /format_lv_lv.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "lv_LV" locale: Latvian (Latvia) 5 | // ============================================================ 6 | 7 | var longDayNamesLvLV = map[string]string{ 8 | "Sunday": "Svētdiena", 9 | "Monday": "Pirmdiena", 10 | "Tuesday": "Otrdiena", 11 | "Wednesday": "Trešdiena", 12 | "Thursday": "Ceturtdiena", 13 | "Friday": "Piektdiena", 14 | "Saturday": "Sestdiena", 15 | } 16 | 17 | var shortDayNamesLvLV = map[string]string{ 18 | "Sun": "Svētd", 19 | "Mon": "Pirmd", 20 | "Tue": "Otrd", 21 | "Wed": "Trešd", 22 | "Thu": "Ceturtd", 23 | "Fri": "Piektd", 24 | "Sat": "Sestd", 25 | } 26 | 27 | var longMonthNamesLvLV = map[string]string{ 28 | "January": "janvāris", 29 | "February": "februāris", 30 | "March": "marts", 31 | "April": "aprīlis", 32 | "May": "maijs", 33 | "June": "jūnijs", 34 | "July": "jūlijs", 35 | "August": "augusts", 36 | "September": "septembris", 37 | "October": "oktobris", 38 | "November": "novembris", 39 | "December": "decembris", 40 | } 41 | 42 | var shortMonthNamesLvLV = map[string]string{ 43 | "Jan": "janv", 44 | "Feb": "febr", 45 | "Mar": "marts", 46 | "Apr": "apr", 47 | "May": "maijs", 48 | "Jun": "jūn", 49 | "Jul": "jūl", 50 | "Aug": "aug", 51 | "Sep": "sept", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_nb_no.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "nb_NO" locale: Norwegian Bokmål (Norway) 5 | // ============================================================ 6 | 7 | var longDayNamesNbNO = map[string]string{ 8 | "Sunday": "søndag", 9 | "Monday": "mandag", 10 | "Tuesday": "tirsdag", 11 | "Wednesday": "onsdag", 12 | "Thursday": "torsdag", 13 | "Friday": "fredag", 14 | "Saturday": "lørdag", 15 | } 16 | 17 | var shortDayNamesNbNO = map[string]string{ 18 | "Sun": "sø", 19 | "Mon": "ma", 20 | "Tue": "ti", 21 | "Wed": "on", 22 | "Thu": "to", 23 | "Fri": "fr", 24 | "Sat": "lø", 25 | } 26 | 27 | var longMonthNamesNbNO = map[string]string{ 28 | "January": "januar", 29 | "February": "februar", 30 | "March": "mars", 31 | "April": "april", 32 | "May": "mai", 33 | "June": "juni", 34 | "July": "juli", 35 | "August": "august", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "desember", 40 | } 41 | 42 | var shortMonthNamesNbNO = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "mai", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "des", 55 | } 56 | -------------------------------------------------------------------------------- /format_nl_be.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "nl_BE" locale: Dutch (Belgium) 5 | // ============================================================ 6 | 7 | var longDayNamesNlBE = map[string]string{ 8 | "Sunday": "zondag", 9 | "Monday": "maandag", 10 | "Tuesday": "dinsdag", 11 | "Wednesday": "woensdag", 12 | "Thursday": "donderdag", 13 | "Friday": "vrijdag", 14 | "Saturday": "zaterdag", 15 | } 16 | 17 | var shortDayNamesNlBE = map[string]string{ 18 | "Sun": "zo", 19 | "Mon": "ma", 20 | "Tue": "di", 21 | "Wed": "wo", 22 | "Thu": "do", 23 | "Fri": "vr", 24 | "Sat": "za", 25 | } 26 | 27 | var longMonthNamesNlBE = map[string]string{ 28 | "January": "januari", 29 | "February": "februari", 30 | "March": "maart", 31 | "April": "april", 32 | "May": "mei", 33 | "June": "juni", 34 | "July": "juli", 35 | "August": "augustus", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesNlBE = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mrt", 46 | "Apr": "apr", 47 | "May": "mei", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_nn_no.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "nn_NO" locale: Norwegian Nynorsk (Norway) 5 | // ============================================================ 6 | 7 | var longDayNamesNnNO = map[string]string{ 8 | "Sunday": "søndag", 9 | "Monday": "måndag", 10 | "Tuesday": "tysdag", 11 | "Wednesday": "onsdag", 12 | "Thursday": "torsdag", 13 | "Friday": "fredag", 14 | "Saturday": "laurdag", 15 | } 16 | 17 | var shortDayNamesNnNO = map[string]string{ 18 | "Sun": "sø", 19 | "Mon": "må", 20 | "Tue": "ty", 21 | "Wed": "on", 22 | "Thu": "to", 23 | "Fri": "fr", 24 | "Sat": "la", 25 | } 26 | 27 | var longMonthNamesNnNO = map[string]string{ 28 | "January": "januar", 29 | "February": "februar", 30 | "March": "mars", 31 | "April": "april", 32 | "May": "mai", 33 | "June": "juni", 34 | "July": "juli", 35 | "August": "august", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "desember", 40 | } 41 | 42 | var shortMonthNamesNnNO = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mars", 46 | "Apr": "apr", 47 | "May": "mai", 48 | "Jun": "juni", 49 | "Jul": "juli", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "des", 55 | } 56 | -------------------------------------------------------------------------------- /format_pl_pl.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "pl_PL" locale: Polish (Poland) 5 | // ============================================================ 6 | 7 | var longDayNamesPlPL = map[string]string{ 8 | "Sunday": "Niedziela", 9 | "Monday": "Poniedziałek", 10 | "Tuesday": "Wtorek", 11 | "Wednesday": "Środa", 12 | "Thursday": "Czwartek", 13 | "Friday": "Piątek", 14 | "Saturday": "Sobota", 15 | } 16 | 17 | // http://sjp.pwn.pl/poradnia/haslo/skracanie-nazw-dni-tygodnia-i-miesiecy;8124.html 18 | var shortDayNamesPlPL = map[string]string{ 19 | "Sun": "Nie", 20 | "Mon": "Pon", 21 | "Tue": "Wto", 22 | "Wed": "Śro", 23 | "Thu": "Czw", 24 | "Fri": "Pią", 25 | "Sat": "Sob", 26 | } 27 | 28 | var longMonthNamesPlPL = map[string]string{ 29 | "January": "Styczeń", 30 | "February": "Luty", 31 | "March": "Marzec", 32 | "April": "Kwiecień", 33 | "May": "Maj", 34 | "June": "Czerwiec", 35 | "July": "Lipiec", 36 | "August": "Sierpień", 37 | "September": "Wrzesień", 38 | "October": "Październik", 39 | "November": "Listopad", 40 | "December": "Grudzień", 41 | } 42 | 43 | var longMonthNamesGenitivePlPL = map[string]string{ 44 | "January": "stycznia", 45 | "February": "lutego", 46 | "March": "marca", 47 | "April": "kwietnia", 48 | "May": "maja", 49 | "June": "czerwca", 50 | "July": "lipca", 51 | "August": "sierpnia", 52 | "September": "września", 53 | "October": "października", 54 | "November": "listopada", 55 | "December": "grudnia", 56 | } 57 | 58 | var shortMonthNamesPlPL = map[string]string{ 59 | "Jan": "Sty", 60 | "Feb": "Lut", 61 | "Mar": "Mar", 62 | "Apr": "Kwi", 63 | "May": "Maj", 64 | "Jun": "Cze", 65 | "Jul": "Lip", 66 | "Aug": "Sie", 67 | "Sep": "Wrz", 68 | "Oct": "Paź", 69 | "Nov": "Lis", 70 | "Dec": "Gru", 71 | } 72 | 73 | var shortMonthNamesGenitivePlPL = map[string]string{ 74 | "Jan": "sty", 75 | "Feb": "lut", 76 | "Mar": "mar", 77 | "Apr": "kwi", 78 | "May": "maj", 79 | "Jun": "cze", 80 | "Jul": "lip", 81 | "Aug": "sie", 82 | "Sep": "wrz", 83 | "Oct": "paź", 84 | "Nov": "lis", 85 | "Dec": "gru", 86 | } 87 | -------------------------------------------------------------------------------- /format_pt_br.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "pt_BR" locale: Portuguese (Brazil) 5 | // ============================================================ 6 | 7 | var longDayNamesPtBR = map[string]string{ 8 | "Sunday": "domingo", 9 | "Monday": "segunda-feira", 10 | "Tuesday": "terça-feira", 11 | "Wednesday": "quarta-feira", 12 | "Thursday": "quinta-feira", 13 | "Friday": "sexta-feira", 14 | "Saturday": "sábado", 15 | } 16 | 17 | var shortDayNamesPtBR = map[string]string{ 18 | "Sun": "dom", 19 | "Mon": "seg", 20 | "Tue": "ter", 21 | "Wed": "qua", 22 | "Thu": "qui", 23 | "Fri": "sex", 24 | "Sat": "sáb", 25 | } 26 | 27 | var longMonthNamesPtBR = map[string]string{ 28 | "January": "janeiro", 29 | "February": "fevereiro", 30 | "March": "março", 31 | "April": "abril", 32 | "May": "maio", 33 | "June": "junho", 34 | "July": "julho", 35 | "August": "agosto", 36 | "September": "setembro", 37 | "October": "outubro", 38 | "November": "novembro", 39 | "December": "dezembro", 40 | } 41 | 42 | var shortMonthNamesPtBR = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "fev", 45 | "Mar": "mar", 46 | "Apr": "abr", 47 | "May": "mai", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "ago", 51 | "Sep": "set", 52 | "Oct": "out", 53 | "Nov": "nov", 54 | "Dec": "dez", 55 | } 56 | -------------------------------------------------------------------------------- /format_pt_pt.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "strings" 4 | 5 | // ============================================================ 6 | // Format rules for "pt_PT" locale: Portuguese (Portugal) 7 | // ============================================================ 8 | 9 | var longDayNamesPtPT = map[string]string{ 10 | "Sunday": "Domingo", 11 | "Monday": "Segunda-feira", 12 | "Tuesday": "Terça-feira", 13 | "Wednesday": "Quarta-feira", 14 | "Thursday": "Quinta-feira", 15 | "Friday": "Sexta-feira", 16 | "Saturday": "Sábado", 17 | } 18 | 19 | var shortDayNamesPtPT = map[string]string{ 20 | "Sun": "dom", 21 | "Mon": "seg", 22 | "Tue": "ter", 23 | "Wed": "qua", 24 | "Thu": "qui", 25 | "Fri": "sex", 26 | "Sat": "sáb", 27 | } 28 | 29 | var longMonthNamesPtPT = map[string]string{ 30 | "January": "Janeiro", 31 | "February": "Fevereiro", 32 | "March": "Março", 33 | "April": "Abril", 34 | "May": "Maio", 35 | "June": "Junho", 36 | "July": "Julho", 37 | "August": "Agosto", 38 | "September": "Setembro", 39 | "October": "Outubro", 40 | "November": "Novembro", 41 | "December": "Dezembro", 42 | } 43 | 44 | var shortMonthNamesPtPT = map[string]string{ 45 | "Jan": "Jan", 46 | "Feb": "Fev", 47 | "Mar": "Mar", 48 | "Apr": "Abr", 49 | "May": "Mai", 50 | "Jun": "Jun", 51 | "Jul": "Jul", 52 | "Aug": "Ago", 53 | "Sep": "Set", 54 | "Oct": "Out", 55 | "Nov": "Nov", 56 | "Dec": "Dez", 57 | } 58 | 59 | func parseFuncPtCommon(locale Locale) internalParseFunc { 60 | return func(layout, value string) string { 61 | // This special case is needed because Pt_PT/Pt_BR/... contains day-of-week names 62 | // that consist of two words and a delimiter (like 'terça-feira'). These 63 | // should be replaced before using the standard procedure correctly. 64 | for k, v := range knownDaysLongReverse[locale] { 65 | value = strings.Replace(value, k, v, -1) 66 | } 67 | 68 | return commonFormatFunc(value, layout, 69 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 70 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale]) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /format_ro_RO.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "ro_RO" locale: Romanian (Romania) 5 | // ============================================================ 6 | 7 | var longDayNamesRoRO = map[string]string{ 8 | "Sunday": "duminică", 9 | "Monday": "luni", 10 | "Tuesday": "marți", 11 | "Wednesday": "miercuri", 12 | "Thursday": "joi", 13 | "Friday": "vineri", 14 | "Saturday": "sâmbătă", 15 | } 16 | 17 | var shortDayNamesRoRO = map[string]string{ 18 | "Sun": "Du", 19 | "Mon": "Lu", 20 | "Tue": "Ma", 21 | "Wed": "Mi", 22 | "Thu": "Jo", 23 | "Fri": "Vi", 24 | "Sat": "Sâ", 25 | } 26 | 27 | var longMonthNamesRoRO = map[string]string{ 28 | "January": "ianuarie", 29 | "February": "februarie", 30 | "March": "martie", 31 | "April": "aprilie", 32 | "May": "mai", 33 | "June": "iunie", 34 | "July": "iulie", 35 | "August": "august", 36 | "September": "septembrie", 37 | "October": "octombrie", 38 | "November": "noiembrie", 39 | "December": "decembrie", 40 | } 41 | 42 | var shortMonthNamesRoRO = map[string]string{ 43 | "Jan": "ian", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "mai", 48 | "Jun": "iun", 49 | "Jul": "iul", 50 | "Aug": "aug", 51 | "Sep": "sept", 52 | "Oct": "oct", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_ru_ru.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "ru_RU" locale: Russian (Russia) 5 | // ============================================================ 6 | 7 | var longDayNamesRuRU = map[string]string{ 8 | "Sunday": "Воскресенье", 9 | "Monday": "Понедельник", 10 | "Tuesday": "Вторник", 11 | "Wednesday": "Среда", 12 | "Thursday": "Четверг", 13 | "Friday": "Пятница", 14 | "Saturday": "Суббота", 15 | } 16 | 17 | var shortDayNamesRuRU = map[string]string{ 18 | "Sun": "Вс", 19 | "Mon": "Пн", 20 | "Tue": "Вт", 21 | "Wed": "Ср", 22 | "Thu": "Чт", 23 | "Fri": "Пт", 24 | "Sat": "Сб", 25 | } 26 | 27 | var longMonthNamesRuRU = map[string]string{ 28 | "January": "Январь", 29 | "February": "Февраль", 30 | "March": "Март", 31 | "April": "Апрель", 32 | "May": "Май", 33 | "June": "Июнь", 34 | "July": "Июль", 35 | "August": "Август", 36 | "September": "Сентябрь", 37 | "October": "Октябрь", 38 | "November": "Ноябрь", 39 | "December": "Декабрь", 40 | } 41 | 42 | var longMonthNamesGenitiveRuRU = map[string]string{ 43 | "January": "января", 44 | "February": "февраля", 45 | "March": "марта", 46 | "April": "апреля", 47 | "May": "мая", 48 | "June": "июня", 49 | "July": "июля", 50 | "August": "августа", 51 | "September": "сентября", 52 | "October": "октября", 53 | "November": "ноября", 54 | "December": "декабря", 55 | } 56 | 57 | var shortMonthNamesRuRU = map[string]string{ 58 | "Jan": "Янв", 59 | "Feb": "Фев", 60 | "Mar": "Мар", 61 | "Apr": "Апр", 62 | "May": "Май", 63 | "Jun": "Июн", 64 | "Jul": "Июл", 65 | "Aug": "Авг", 66 | "Sep": "Сен", 67 | "Oct": "Окт", 68 | "Nov": "Ноя", 69 | "Dec": "Дек", 70 | } 71 | 72 | var shortMonthNamesGenitiveRuRU = map[string]string{ 73 | "Jan": "янв", 74 | "Feb": "фев", 75 | "Mar": "мар", 76 | "Apr": "апр", 77 | "May": "мая", 78 | "Jun": "июн", 79 | "Jul": "июл", 80 | "Aug": "авг", 81 | "Sep": "сен", 82 | "Oct": "окт", 83 | "Nov": "ноя", 84 | "Dec": "дек", 85 | } 86 | -------------------------------------------------------------------------------- /format_sk_sk.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "sk_SK" locale: Slovak (Slovakia) 5 | // ============================================================ 6 | 7 | var longDayNamesSkSK = map[string]string{ 8 | "Sunday": "nedeľa", 9 | "Monday": "pondelok", 10 | "Tuesday": "utorok", 11 | "Wednesday": "streda", 12 | "Thursday": "štvrtok", 13 | "Friday": "piatok", 14 | "Saturday": "sobota", 15 | } 16 | 17 | var shortDayNamesSkSK = map[string]string{ 18 | "Sun": "ne", 19 | "Mon": "po", 20 | "Tue": "ut", 21 | "Wed": "st", 22 | "Thu": "št", 23 | "Fri": "pi", 24 | "Sat": "so", 25 | } 26 | 27 | var longMonthNamesSkSK = map[string]string{ 28 | "January": "január", 29 | "February": "február", 30 | "March": "marec", 31 | "April": "apríl", 32 | "May": "máj", 33 | "June": "jún", 34 | "July": "júl", 35 | "August": "august", 36 | "September": "september", 37 | "October": "október", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesSkSK = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "máj", 48 | "Jun": "jún", 49 | "Jul": "júl", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_sl_si.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "sl_SI" locale: Slovenian 5 | // ============================================================ 6 | 7 | var longDayNamesSlSI = map[string]string{ 8 | "Sunday": "nedelja", 9 | "Monday": "ponedeljek", 10 | "Tuesday": "toret", 11 | "Wednesday": "sreda", 12 | "Thursday": "četrtek", 13 | "Friday": "petek", 14 | "Saturday": "sobota", 15 | } 16 | 17 | var shortDayNamesSlSI = map[string]string{ 18 | "Sun": "ned", 19 | "Mon": "pon", 20 | "Tue": "tor", 21 | "Wed": "sre", 22 | "Thu": "čet", 23 | "Fri": "pet", 24 | "Sat": "sob", 25 | } 26 | 27 | var longMonthNamesSlSI = map[string]string{ 28 | "January": "januar", 29 | "February": "februar", 30 | "March": "marec", 31 | "April": "april", 32 | "May": "maj", 33 | "June": "junij", 34 | "July": "julij", 35 | "August": "avgust", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesSlSI = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "maj", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "avg", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_sv_se.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "sv_SE" locale: Swedish (Sweden) 5 | // ============================================================ 6 | 7 | var longDayNamesSvSE = map[string]string{ 8 | "Sunday": "söndag", 9 | "Monday": "måndag", 10 | "Tuesday": "tisdag", 11 | "Wednesday": "onsdag", 12 | "Thursday": "torsdag", 13 | "Friday": "fredag", 14 | "Saturday": "lördag", 15 | } 16 | 17 | var shortDayNamesSvSE = map[string]string{ 18 | "Sun": "sön", 19 | "Mon": "mån", 20 | "Tue": "tis", 21 | "Wed": "ons", 22 | "Thu": "tors", 23 | "Fri": "fre", 24 | "Sat": "lör", 25 | } 26 | 27 | var longMonthNamesSvSE = map[string]string{ 28 | "January": "januari", 29 | "February": "februari", 30 | "March": "mars", 31 | "April": "april", 32 | "May": "maj", 33 | "June": "juni", 34 | "July": "juli", 35 | "August": "augusti", 36 | "September": "september", 37 | "October": "oktober", 38 | "November": "november", 39 | "December": "december", 40 | } 41 | 42 | var shortMonthNamesSvSE = map[string]string{ 43 | "Jan": "jan", 44 | "Feb": "feb", 45 | "Mar": "mar", 46 | "Apr": "apr", 47 | "May": "maj", 48 | "Jun": "jun", 49 | "Jul": "jul", 50 | "Aug": "aug", 51 | "Sep": "sep", 52 | "Oct": "okt", 53 | "Nov": "nov", 54 | "Dec": "dec", 55 | } 56 | -------------------------------------------------------------------------------- /format_th_th.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "strings" 4 | 5 | // ============================================================ 6 | // Format rules for "th_TH" locale: Thai (Thailand) 7 | // ============================================================ 8 | 9 | var longDayNamesThTH = map[string]string{ 10 | "Sunday": "วันอาทิตย์", 11 | "Monday": "วันจันทร์", 12 | "Tuesday": "วันอังคาร", 13 | "Wednesday": "วันพุธ", 14 | "Thursday": "วันพฤหัสบดี", 15 | "Friday": "วันศุกร์", 16 | "Saturday": "วันเสาร์", 17 | } 18 | 19 | var shortDayNamesThTH = map[string]string{ 20 | "Sun": "อา.", 21 | "Mon": "จ.", 22 | "Tue": "อ.", 23 | "Wed": "พ.", 24 | "Thu": "พฤ.", 25 | "Fri": "ศ.", 26 | "Sat": "ส.", 27 | } 28 | 29 | var longMonthNamesThTH = map[string]string{ 30 | "January": "มกราคม", 31 | "February": "กุมภาพันธ์", 32 | "March": "มีนาคม", 33 | "April": "เมษายน", 34 | "May": "พฤษภาคม", 35 | "June": "มิถุนายน", 36 | "July": "กรกฎาคม", 37 | "August": "สิงหาคม", 38 | "September": "กันยายน", 39 | "October": "ตุลาคม", 40 | "November": "พฤศจิกายน", 41 | "December": "ธันวาคม", 42 | } 43 | 44 | var shortMonthNamesThTH = map[string]string{ 45 | "Jan": "ม.ค.", 46 | "Feb": "ก.พ.", 47 | "Mar": "มี.ค.", 48 | "Apr": "เม.ย.", 49 | "May": "พ.ค.", 50 | "Jun": "มิ.ย.", 51 | "Jul": "ก.ค.", 52 | "Aug": "ส.ค.", 53 | "Sep": "ก.ย.", 54 | "Oct": "ต.ค.", 55 | "Nov": "พ.ย.", 56 | "Dec": "ธ.ค.", 57 | } 58 | 59 | func parseFuncThCommon(locale Locale) internalParseFunc { 60 | return func(layout, value string) string { 61 | // This special case is needed because th_TH... contains month and day names 62 | // that consist of dots, and special character. Example: "February" = "กุมภาพันธ์", "Feb" = "ก.พ." 63 | // 64 | // This means that probably default time package layout IDs like 'January' or 'Jan' 65 | // shouldn't be used in th_TH. But this is a time-compatible package, so someone 66 | // might actually use those and we need to replace those before doing standard procedures. 67 | for k, v := range knownMonthsShortReverse[locale] { 68 | value = strings.Replace(value, k, v, -1) 69 | } 70 | for k, v := range knownDaysShortReverse[locale] { 71 | value = strings.Replace(value, k, v, -1) 72 | } 73 | for k, v := range knownMonthsLongReverse[locale] { 74 | value = strings.Replace(value, k, v, -1) 75 | } 76 | for k, v := range knownDaysLongReverse[locale] { 77 | value = strings.Replace(value, k, v, -1) 78 | } 79 | 80 | return commonFormatFunc(value, layout, 81 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 82 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale]) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /format_tr_tr.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "tr_TR" locale: Turkish (Turkey) 5 | // ============================================================ 6 | 7 | var longDayNamesTrTR = map[string]string{ 8 | "Sunday": "Pazar", 9 | "Monday": "Pazartesi", 10 | "Tuesday": "Salı", 11 | "Wednesday": "Çarşamba", 12 | "Thursday": "Perşembe", 13 | "Friday": "Cuma", 14 | "Saturday": "Cumartesi", 15 | } 16 | 17 | var shortDayNamesTrTR = map[string]string{ 18 | "Sun": "Paz", 19 | "Mon": "Pzt", 20 | "Tue": "Sal", 21 | "Wed": "Çar", 22 | "Thu": "Per", 23 | "Fri": "Cum", 24 | "Sat": "Cmt", 25 | } 26 | 27 | var longMonthNamesTrTR = map[string]string{ 28 | "January": "Ocak", 29 | "February": "Şubat", 30 | "March": "Mart", 31 | "April": "Nisan", 32 | "May": "Mayıs", 33 | "June": "Haziran", 34 | "July": "Temmuz", 35 | "August": "Ağustos", 36 | "September": "Eylül", 37 | "October": "Ekim", 38 | "November": "Kasım", 39 | "December": "Aralık", 40 | } 41 | 42 | var shortMonthNamesTrTR = map[string]string{ 43 | "Jan": "Oca", 44 | "Feb": "Şub", 45 | "Mar": "Mar", 46 | "Apr": "Nis", 47 | "May": "May", 48 | "Jun": "Haz", 49 | "Jul": "Tem", 50 | "Aug": "Ağu", 51 | "Sep": "Eyl", 52 | "Oct": "Eki", 53 | "Nov": "Kas", 54 | "Dec": "Ara", 55 | } 56 | -------------------------------------------------------------------------------- /format_uk_ua.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "uk_UA" locale: Ukrainian (Ukraine) 5 | // ============================================================ 6 | 7 | var longDayNamesUkUA = map[string]string{ 8 | "Sunday": "Неділя", 9 | "Monday": "Понеділок", 10 | "Tuesday": "Вівторок", 11 | "Wednesday": "Середа", 12 | "Thursday": "Четвер", 13 | "Friday": "П’ятниця", 14 | "Saturday": "Субота", 15 | } 16 | 17 | var shortDayNamesUkUA = map[string]string{ 18 | "Sun": "Нд", 19 | "Mon": "Пн", 20 | "Tue": "Вт", 21 | "Wed": "Ср", 22 | "Thu": "Чт", 23 | "Fri": "Пт", 24 | "Sat": "Сб", 25 | } 26 | 27 | var longMonthNamesUkUA = map[string]string{ 28 | "January": "Січень", 29 | "February": "Лютий", 30 | "March": "Березень", 31 | "April": "Квітень", 32 | "May": "Травень", 33 | "June": "Червень", 34 | "July": "Липень", 35 | "August": "Серпень", 36 | "September": "Вересень", 37 | "October": "Жовтень", 38 | "November": "Листопад", 39 | "December": "Грудень", 40 | } 41 | 42 | var longMonthNamesGenitiveUkUA = map[string]string{ 43 | "January": "січня", 44 | "February": "лютого", 45 | "March": "березня", 46 | "April": "квітня", 47 | "May": "травня", 48 | "June": "червня", 49 | "July": "липня", 50 | "August": "серпня", 51 | "September": "вересня", 52 | "October": "жовтня", 53 | "November": "листопада", 54 | "December": "грудня", 55 | } 56 | 57 | var shortMonthNamesUkUA = map[string]string{ 58 | "Jan": "Січ", 59 | "Feb": "Лют", 60 | "Mar": "Бер", 61 | "Apr": "Кві", 62 | "May": "Тра", 63 | "Jun": "Чер", 64 | "Jul": "Лип", 65 | "Aug": "Сер", 66 | "Sep": "Вер", 67 | "Oct": "Жов", 68 | "Nov": "Лис", 69 | "Dec": "Гру", 70 | } 71 | 72 | var shortMonthNamesGenitiveUkUA = map[string]string{ 73 | "Jan": "січ", 74 | "Feb": "лют", 75 | "Mar": "бер", 76 | "Apr": "кві", 77 | "May": "тра", 78 | "Jun": "чер", 79 | "Jul": "лип", 80 | "Aug": "сер", 81 | "Sep": "вер", 82 | "Oct": "жов", 83 | "Nov": "лис", 84 | "Dec": "гру", 85 | } 86 | -------------------------------------------------------------------------------- /format_uz_uz.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "uz_UZ" locale: Uzbek (Uzbeksitan) 5 | // ============================================================ 6 | 7 | var longDayNamesUzUZ = map[string]string{ 8 | "Sunday": "Yakshanba", 9 | "Monday": "Dushanba", 10 | "Tuesday": "Seshanba", 11 | "Wednesday": "Chorshanba", 12 | "Thursday": "Payshanba", 13 | "Friday": "Juma", 14 | "Saturday": "Shanba", 15 | } 16 | 17 | var shortDayNamesUzUZ = map[string]string{ 18 | "Sun": "Ya", 19 | "Mon": "Du", 20 | "Tue": "Se", 21 | "Wed": "Ch", 22 | "Thu": "Pa", 23 | "Fri": "Ju", 24 | "Sat": "Sh", 25 | } 26 | 27 | var longMonthNamesUzUZ = map[string]string{ 28 | "January": "Yanvar", 29 | "February": "Fevral", 30 | "March": "Mart", 31 | "April": "Aprel", 32 | "May": "May", 33 | "June": "Iyun", 34 | "July": "Iyul", 35 | "August": "Avgust", 36 | "September": "Sentyabr", 37 | "October": "Oktyabr", 38 | "November": "Noyabr", 39 | "December": "Dekabr", 40 | } 41 | 42 | var longMonthNamesGenitiveUzUZ = map[string]string{ 43 | "January": "yanvar", 44 | "February": "fevral", 45 | "March": "mart", 46 | "April": "aprel", 47 | "May": "may", 48 | "June": "iyun", 49 | "July": "iyul", 50 | "August": "avgust", 51 | "September": "sentyabr", 52 | "October": "oktyabr", 53 | "November": "noyabr", 54 | "December": "dekabr", 55 | } 56 | 57 | var shortMonthNamesUzUZ = map[string]string{ 58 | "Jan": "Yan", 59 | "Feb": "Fev", 60 | "Mar": "Mar", 61 | "Apr": "Apr", 62 | "May": "May", 63 | "Jun": "Iyun", 64 | "Jul": "Iyul", 65 | "Aug": "Avg", 66 | "Sep": "Sen", 67 | "Oct": "Okt", 68 | "Nov": "Noy", 69 | "Dec": "Dek", 70 | } 71 | 72 | var shortMonthNamesGenitiveUzUZ = map[string]string{ 73 | "Jan": "yan", 74 | "Feb": "fev", 75 | "Mar": "mar", 76 | "Apr": "apr", 77 | "May": "may", 78 | "Jun": "iyun", 79 | "Jul": "iyul", 80 | "Aug": "avg", 81 | "Sep": "sen", 82 | "Oct": "okt", 83 | "Nov": "noy", 84 | "Dec": "dek", 85 | } 86 | -------------------------------------------------------------------------------- /format_zh_cn.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "strings" 4 | 5 | // ============================================================ 6 | // Format rules for "zh_CN" locale: Chinese (Mainland) 7 | // ============================================================ 8 | 9 | var longDayNamesZhCN = map[string]string{ 10 | "Sunday": "星期日", 11 | "Monday": "星期一", 12 | "Tuesday": "星期二", 13 | "Wednesday": "星期三", 14 | "Thursday": "星期四", 15 | "Friday": "星期五", 16 | "Saturday": "星期六", 17 | } 18 | 19 | var shortDayNamesZhCN = map[string]string{ 20 | "Sun": "日", 21 | "Mon": "一", 22 | "Tue": "二", 23 | "Wed": "三", 24 | "Thu": "四", 25 | "Fri": "五", 26 | "Sat": "六", 27 | } 28 | 29 | var longMonthNamesZhCN = map[string]string{ 30 | "January": "1 月", 31 | "February": "2 月", 32 | "March": "3 月", 33 | "April": "4 月", 34 | "May": "5 月", 35 | "June": "6 月", 36 | "July": "7 月", 37 | "August": "8 月", 38 | "September": "9 月", 39 | "October": "10 月", 40 | "November": "11 月", 41 | "December": "12 月", 42 | } 43 | 44 | var shortMonthNamesZhCN = map[string]string{ 45 | "Jan": "1", 46 | "Feb": "2", 47 | "Mar": "3", 48 | "Apr": "4", 49 | "May": "5", 50 | "Jun": "6", 51 | "Jul": "7", 52 | "Aug": "8", 53 | "Sep": "9", 54 | "Oct": "10", 55 | "Nov": "11", 56 | "Dec": "12", 57 | } 58 | 59 | func parseFuncZhCommon(locale Locale) internalParseFunc { 60 | return func(layout, value string) string { 61 | // This special case is needed because Zh_CN/Zh/HK/... contains month names 62 | // that consist of a number, a delimiter, and '月'. Example: "October" = "10 月" 63 | // 64 | // This means that probably default time package layout IDs like 'January' or 'Jan' 65 | // shouldn't be used in Zh_*. But this is a time-compatible package, so someone 66 | // might actually use those and we need to replace those before doing standard procedures. 67 | for k, v := range knownMonthsLongReverse[locale] { 68 | value = strings.Replace(value, k, v, -1) 69 | } 70 | 71 | return commonFormatFunc(value, layout, 72 | knownDaysShortReverse[locale], knownDaysLongReverse[locale], 73 | knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale]) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /format_zh_hk.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "zh_HK" locale: Chinese (Hong Kong) 5 | // ============================================================ 6 | 7 | var longDayNamesZhHK = map[string]string{ 8 | "Sunday": "星期日", 9 | "Monday": "星期一", 10 | "Tuesday": "星期二", 11 | "Wednesday": "星期三", 12 | "Thursday": "星期四", 13 | "Friday": "星期五", 14 | "Saturday": "星期六", 15 | } 16 | 17 | var shortDayNamesZhHK = map[string]string{ 18 | "Sun": "日", 19 | "Mon": "一", 20 | "Tue": "二", 21 | "Wed": "三", 22 | "Thu": "四", 23 | "Fri": "五", 24 | "Sat": "六", 25 | } 26 | 27 | var longMonthNamesZhHK = map[string]string{ 28 | "January": "1 月", 29 | "February": "2 月", 30 | "March": "3 月", 31 | "April": "4 月", 32 | "May": "5 月", 33 | "June": "6 月", 34 | "July": "7 月", 35 | "August": "8 月", 36 | "September": "9 月", 37 | "October": "10 月", 38 | "November": "11 月", 39 | "December": "12 月", 40 | } 41 | 42 | var shortMonthNamesZhHK = map[string]string{ 43 | "Jan": "1", 44 | "Feb": "2", 45 | "Mar": "3", 46 | "Apr": "4", 47 | "May": "5", 48 | "Jun": "6", 49 | "Jul": "7", 50 | "Aug": "8", 51 | "Sep": "9", 52 | "Oct": "10", 53 | "Nov": "11", 54 | "Dec": "12", 55 | } 56 | -------------------------------------------------------------------------------- /format_zh_tw.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // ============================================================ 4 | // Format rules for "zh_TW" locale: Chinese (Taiwan) 5 | // ============================================================ 6 | 7 | var longDayNamesZhTW = map[string]string{ 8 | "Sunday": "星期日", 9 | "Monday": "星期一", 10 | "Tuesday": "星期二", 11 | "Wednesday": "星期三", 12 | "Thursday": "星期四", 13 | "Friday": "星期五", 14 | "Saturday": "星期六", 15 | } 16 | 17 | var shortDayNamesZhTW = map[string]string{ 18 | "Sun": "日", 19 | "Mon": "一", 20 | "Tue": "二", 21 | "Wed": "三", 22 | "Thu": "四", 23 | "Fri": "五", 24 | "Sat": "六", 25 | } 26 | 27 | var longMonthNamesZhTW = map[string]string{ 28 | "January": "1 月", 29 | "February": "2 月", 30 | "March": "3 月", 31 | "April": "4 月", 32 | "May": "5 月", 33 | "June": "6 月", 34 | "July": "7 月", 35 | "August": "8 月", 36 | "September": "9 月", 37 | "October": "10 月", 38 | "November": "11 月", 39 | "December": "12 月", 40 | } 41 | 42 | var shortMonthNamesZhTW = map[string]string{ 43 | "Jan": "1", 44 | "Feb": "2", 45 | "Mar": "3", 46 | "Apr": "4", 47 | "May": "5", 48 | "Jun": "6", 49 | "Jul": "7", 50 | "Aug": "8", 51 | "Sep": "9", 52 | "Oct": "10", 53 | "Nov": "11", 54 | "Dec": "12", 55 | } 56 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/goodsign/monday 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /locale.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | // Locale identifies locales supported by 'monday' package. 4 | // Monday uses ICU locale identifiers. See http://userguide.icu-project.org/locale 5 | type Locale string 6 | 7 | // Locale constants represent all locales that are currently supported by 8 | // this package. 9 | const ( 10 | LocaleEnUS = "en_US" // English (United States) 11 | LocaleEnGB = "en_GB" // English (United Kingdom) 12 | LocaleDaDK = "da_DK" // Danish (Denmark) 13 | LocaleNlBE = "nl_BE" // Dutch (Belgium) 14 | LocaleNlNL = "nl_NL" // Dutch (Netherlands) 15 | LocaleFiFI = "fi_FI" // Finnish (Finland) 16 | LocaleFrFR = "fr_FR" // French (France) 17 | LocaleFrCA = "fr_CA" // French (Canada) 18 | LocaleDeDE = "de_DE" // German (Germany) 19 | LocaleHuHU = "hu_HU" // Hungarian (Hungary) 20 | LocaleItIT = "it_IT" // Italian (Italy) 21 | LocaleNnNO = "nn_NO" // Norwegian Nynorsk (Norway) 22 | LocaleNbNO = "nb_NO" // Norwegian Bokmål (Norway) 23 | LocalePlPL = "pl_PL" // Polish (Poland) 24 | LocalePtPT = "pt_PT" // Portuguese (Portugal) 25 | LocalePtBR = "pt_BR" // Portuguese (Brazil) 26 | LocaleRoRO = "ro_RO" // Romanian (Romania) 27 | LocaleRuRU = "ru_RU" // Russian (Russia) 28 | LocaleEsES = "es_ES" // Spanish (Spain) 29 | LocaleCaES = "ca_ES" // Catalan (Spain) 30 | LocaleSvSE = "sv_SE" // Swedish (Sweden) 31 | LocaleTrTR = "tr_TR" // Turkish (Turkey) 32 | LocaleUkUA = "uk_UA" // Ukrainian (Ukraine) 33 | LocaleBgBG = "bg_BG" // Bulgarian (Bulgaria) 34 | LocaleZhCN = "zh_CN" // Chinese (Mainland) 35 | LocaleZhTW = "zh_TW" // Chinese (Taiwan) 36 | LocaleZhHK = "zh_HK" // Chinese (Hong Kong) 37 | LocaleKoKR = "ko_KR" // Korean (Korea) 38 | LocaleJaJP = "ja_JP" // Japanese (Japan) 39 | LocaleElGR = "el_GR" // Greek (Greece) 40 | LocaleIdID = "id_ID" // Indonesian (Indonesia) 41 | LocaleFrGP = "fr_GP" // French (Guadeloupe) 42 | LocaleFrLU = "fr_LU" // French (Luxembourg) 43 | LocaleFrMQ = "fr_MQ" // French (Martinique) 44 | LocaleFrRE = "fr_RE" // French (Reunion) 45 | LocaleFrGF = "fr_GF" // French (French Guiana) 46 | LocaleCsCZ = "cs_CZ" // Czech (Czech Republic) 47 | LocaleSlSI = "sl_SI" // Slovenian (Slovenia) 48 | LocaleLtLT = "lt_LT" // Lithuanian (Lithuania) 49 | LocaleEtEE = "et_EE" // Estonian (Estonia) 50 | LocaleHrHR = "hr_HR" // Croatian (Croatia) 51 | LocaleLvLV = "lv_LV" // Latvian (Latvia) 52 | LocaleSkSK = "sk_SK" // Slovak (Slovakia) 53 | LocaleThTH = "th_TH" // Thai (Thailand) 54 | LocaleUzUZ = "uz_UZ" // Uzbek (Uzbekistan) 55 | LocaleKkKZ = "kk_KZ" // Kazakh (Kazakhstan) 56 | ) 57 | 58 | // ListLocales returns all locales supported by the package. 59 | func ListLocales() []Locale { 60 | return []Locale{ 61 | LocaleEnUS, 62 | LocaleEnGB, 63 | LocaleDaDK, 64 | LocaleNlBE, 65 | LocaleNlNL, 66 | LocaleFiFI, 67 | LocaleFrFR, 68 | LocaleFrCA, 69 | LocaleDeDE, 70 | LocaleHuHU, 71 | LocaleItIT, 72 | LocaleNnNO, 73 | LocaleNbNO, 74 | LocalePlPL, 75 | LocalePtPT, 76 | LocalePtBR, 77 | LocaleRoRO, 78 | LocaleRuRU, 79 | LocaleEsES, 80 | LocaleCaES, 81 | LocaleSvSE, 82 | LocaleTrTR, 83 | LocaleUkUA, 84 | LocaleBgBG, 85 | LocaleZhCN, 86 | LocaleZhTW, 87 | LocaleZhHK, 88 | LocaleKoKR, 89 | LocaleJaJP, 90 | LocaleElGR, 91 | LocaleFrGP, 92 | LocaleFrLU, 93 | LocaleFrMQ, 94 | LocaleFrRE, 95 | LocaleFrGF, 96 | LocaleCsCZ, 97 | LocaleSlSI, 98 | LocaleLtLT, 99 | LocaleEtEE, 100 | LocaleHrHR, 101 | LocaleLvLV, 102 | LocaleSkSK, 103 | LocaleThTH, 104 | LocaleUzUZ, 105 | LocaleKkKZ, 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /monday.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // internalFormatFunc is a preprocessor for default time.Format func 9 | type internalFormatFunc func(value, layout string) string 10 | 11 | var internalFormatFuncs = map[Locale]internalFormatFunc{ 12 | LocaleEnUS: createCommonFormatFunc(LocaleEnUS), 13 | LocaleEnGB: createCommonFormatFunc(LocaleEnGB), 14 | LocaleDaDK: createCommonFormatFunc(LocaleDaDK), 15 | LocaleNlBE: createCommonFormatFunc(LocaleNlBE), 16 | LocaleNlNL: createCommonFormatFunc(LocaleNlNL), 17 | LocaleFrFR: createCommonFormatFunc(LocaleFrFR), 18 | LocaleFrCA: createCommonFormatFunc(LocaleFrFR), 19 | LocaleFrGP: createCommonFormatFunc(LocaleFrFR), 20 | LocaleFrLU: createCommonFormatFunc(LocaleFrFR), 21 | LocaleFrMQ: createCommonFormatFunc(LocaleFrFR), 22 | LocaleFrGF: createCommonFormatFunc(LocaleFrFR), 23 | LocaleFrRE: createCommonFormatFunc(LocaleFrFR), 24 | LocaleRuRU: createCommonFormatFuncWithGenitive(LocaleRuRU), 25 | LocaleFiFI: createCommonFormatFuncWithGenitive(LocaleFiFI), 26 | LocaleDeDE: createCommonFormatFunc(LocaleDeDE), 27 | LocaleHuHU: createCommonFormatFunc(LocaleHuHU), 28 | LocaleItIT: createCommonFormatFunc(LocaleItIT), 29 | LocaleNnNO: createCommonFormatFunc(LocaleNnNO), 30 | LocaleNbNO: createCommonFormatFunc(LocaleNbNO), 31 | LocalePlPL: createCommonFormatFuncWithGenitive(LocalePlPL), 32 | LocalePtPT: createCommonFormatFunc(LocalePtPT), 33 | LocalePtBR: createCommonFormatFunc(LocalePtBR), 34 | LocaleRoRO: createCommonFormatFunc(LocaleRoRO), 35 | LocaleEsES: createCommonFormatFunc(LocaleEsES), 36 | LocaleCaES: createCommonFormatFunc(LocaleCaES), 37 | LocaleSvSE: createCommonFormatFunc(LocaleSvSE), 38 | LocaleTrTR: createCommonFormatFunc(LocaleTrTR), 39 | LocaleUkUA: createCommonFormatFuncWithGenitive(LocaleUkUA), 40 | LocaleBgBG: createCommonFormatFunc(LocaleBgBG), 41 | LocaleZhCN: createCommonFormatFunc(LocaleZhCN), 42 | LocaleZhTW: createCommonFormatFunc(LocaleZhTW), 43 | LocaleZhHK: createCommonFormatFunc(LocaleZhHK), 44 | LocaleKoKR: createCommonFormatFunc(LocaleKoKR), 45 | LocaleJaJP: createCommonFormatFunc(LocaleJaJP), 46 | LocaleElGR: createCommonFormatFuncWithGenitive(LocaleElGR), 47 | LocaleIdID: createCommonFormatFunc(LocaleIdID), 48 | LocaleCsCZ: createCommonFormatFunc(LocaleCsCZ), 49 | LocaleSlSI: createCommonFormatFunc(LocaleSlSI), 50 | LocaleLtLT: createCommonFormatFuncWithGenitive(LocaleLtLT), 51 | LocaleEtEE: createCommonFormatFunc(LocaleEtEE), 52 | LocaleHrHR: createCommonFormatFunc(LocaleHrHR), 53 | LocaleLvLV: createCommonFormatFunc(LocaleLvLV), 54 | LocaleSkSK: createCommonFormatFunc(LocaleSkSK), 55 | LocaleThTH: createCommonFormatFunc(LocaleThTH), 56 | LocaleUzUZ: createCommonFormatFuncWithGenitive(LocaleUzUZ), 57 | LocaleKkKZ: createCommonFormatFuncWithGenitive(LocaleKkKZ), 58 | } 59 | 60 | // internalParseFunc is a preprocessor for default time.ParseInLocation func 61 | type internalParseFunc func(layout, value string) string 62 | 63 | var internalParseFuncs = map[Locale]internalParseFunc{ 64 | LocaleEnUS: createCommonParseFunc(LocaleEnUS), 65 | LocaleEnGB: createCommonParseFunc(LocaleEnGB), 66 | LocaleDaDK: createCommonParseFunc(LocaleDaDK), 67 | LocaleNlBE: createCommonParseFunc(LocaleNlBE), 68 | LocaleNlNL: createCommonParseFunc(LocaleNlNL), 69 | LocaleFrFR: createCommonParseFunc(LocaleFrFR), 70 | LocaleFrCA: createCommonParseFunc(LocaleFrFR), 71 | LocaleFrGP: createCommonParseFunc(LocaleFrFR), 72 | LocaleFrLU: createCommonParseFunc(LocaleFrFR), 73 | LocaleFrMQ: createCommonParseFunc(LocaleFrFR), 74 | LocaleFrGF: createCommonParseFunc(LocaleFrFR), 75 | LocaleFrRE: createCommonParseFunc(LocaleFrFR), 76 | LocaleRuRU: createCommonParseFuncWithGenitive(LocaleRuRU), 77 | LocaleFiFI: createCommonParseFuncWithGenitive(LocaleFiFI), 78 | LocaleDeDE: createCommonParseFunc(LocaleDeDE), 79 | LocaleHuHU: createCommonParseFunc(LocaleHuHU), 80 | LocaleItIT: createCommonParseFunc(LocaleItIT), 81 | LocaleNnNO: createCommonParseFunc(LocaleNnNO), 82 | LocaleNbNO: createCommonParseFunc(LocaleNbNO), 83 | LocalePlPL: createCommonParseFuncWithGenitive(LocalePlPL), 84 | LocalePtPT: parseFuncPtCommon(LocalePtPT), 85 | LocalePtBR: parseFuncPtCommon(LocalePtBR), 86 | LocaleRoRO: createCommonParseFunc(LocaleRoRO), 87 | LocaleEsES: createCommonParseFunc(LocaleEsES), 88 | LocaleCaES: createCommonParseFunc(LocaleCaES), 89 | LocaleSvSE: createCommonParseFunc(LocaleSvSE), 90 | LocaleTrTR: createCommonParseFunc(LocaleTrTR), 91 | LocaleUkUA: createCommonParseFuncWithGenitive(LocaleUkUA), 92 | LocaleBgBG: createCommonParseFunc(LocaleBgBG), 93 | LocaleZhCN: parseFuncZhCommon(LocaleZhCN), 94 | LocaleZhTW: parseFuncZhCommon(LocaleZhTW), 95 | LocaleZhHK: parseFuncZhCommon(LocaleZhHK), 96 | LocaleKoKR: parseFuncKoCommon(LocaleKoKR), 97 | LocaleJaJP: parseFuncJaCommon(LocaleJaJP), 98 | LocaleElGR: createCommonParseFuncWithGenitive(LocaleElGR), 99 | LocaleIdID: createCommonParseFunc(LocaleIdID), 100 | LocaleCsCZ: createCommonParseFunc(LocaleCsCZ), 101 | LocaleSlSI: createCommonParseFunc(LocaleSlSI), 102 | LocaleLtLT: createCommonParseFuncWithGenitive(LocaleLtLT), 103 | LocaleEtEE: createCommonParseFunc(LocaleEtEE), 104 | LocaleHrHR: createCommonParseFunc(LocaleHrHR), 105 | LocaleLvLV: createCommonParseFunc(LocaleLvLV), 106 | LocaleSkSK: createCommonParseFunc(LocaleSkSK), 107 | LocaleThTH: parseFuncThCommon(LocaleThTH), 108 | LocaleUzUZ: createCommonParseFuncWithGenitive(LocaleUzUZ), 109 | LocaleKkKZ: createCommonParseFuncWithGenitive(LocaleKkKZ), 110 | } 111 | 112 | var knownDaysShort = map[Locale]map[string]string{} // Mapping for 'Format', days of week, short form 113 | var knownDaysLong = map[Locale]map[string]string{} // Mapping for 'Format', days of week, long form 114 | var knownMonthsLong = map[Locale]map[string]string{} // Mapping for 'Format', months: long form 115 | var knownMonthsShort = map[Locale]map[string]string{} // Mapping for 'Format', months: short form 116 | var knownMonthsGenitiveShort = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, short form 117 | var knownMonthsGenitiveLong = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, long form 118 | var knownPeriods = map[Locale]map[string]string{} // Mapping for 'Format', AM/PM 119 | 120 | // Reverse maps for the same 121 | 122 | var knownDaysShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', days of week, short form 123 | var knownDaysLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', days of week, long form 124 | var knownMonthsLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', months: long form 125 | var knownMonthsShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', months: short form 126 | var knownMonthsGenitiveShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, short form 127 | var knownMonthsGenitiveLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, long form 128 | var knownPeriodsReverse = map[Locale]map[string]string{} // Mapping for 'Format', AM/PM 129 | 130 | func init() { 131 | fillKnownWords() 132 | } 133 | 134 | func fillKnownWords() { 135 | 136 | // En_US: English (United States) 137 | fillKnownDaysLong(longDayNamesEnUS, LocaleEnUS) 138 | fillKnownDaysShort(shortDayNamesEnUS, LocaleEnUS) 139 | fillKnownMonthsLong(longMonthNamesEnUS, LocaleEnUS) 140 | fillKnownMonthsShort(shortMonthNamesEnUS, LocaleEnUS) 141 | 142 | // En_GB: English (United Kingdom) 143 | fillKnownDaysLong(longDayNamesEnUS, LocaleEnGB) 144 | fillKnownDaysShort(shortDayNamesEnUS, LocaleEnGB) 145 | fillKnownMonthsLong(longMonthNamesEnUS, LocaleEnGB) 146 | fillKnownMonthsShort(shortMonthNamesEnUS, LocaleEnGB) 147 | 148 | // Da_DK: Danish (Denmark) 149 | fillKnownDaysLong(longDayNamesDaDK, LocaleDaDK) 150 | fillKnownDaysShort(shortDayNamesDaDK, LocaleDaDK) 151 | fillKnownMonthsLong(longMonthNamesDaDK, LocaleDaDK) 152 | fillKnownMonthsShort(shortMonthNamesDaDK, LocaleDaDK) 153 | 154 | // Nl_BE: Dutch (Belgium) 155 | fillKnownDaysLong(longDayNamesNlBE, LocaleNlBE) 156 | fillKnownDaysShort(shortDayNamesNlBE, LocaleNlBE) 157 | fillKnownMonthsLong(longMonthNamesNlBE, LocaleNlBE) 158 | fillKnownMonthsShort(shortMonthNamesNlBE, LocaleNlBE) 159 | 160 | // Nl_NL: Dutch (Netherlands) 161 | fillKnownDaysLong(longDayNamesNlBE, LocaleNlNL) 162 | fillKnownDaysShort(shortDayNamesNlBE, LocaleNlNL) 163 | fillKnownMonthsLong(longMonthNamesNlBE, LocaleNlNL) 164 | fillKnownMonthsShort(shortMonthNamesNlBE, LocaleNlNL) 165 | 166 | // Fi_FI: Finnish (Finland) 167 | fillKnownDaysLong(longDayNamesFiFI, LocaleFiFI) 168 | fillKnownDaysShort(shortDayNamesFiFI, LocaleFiFI) 169 | fillKnownMonthsLong(longMonthNamesFiFI, LocaleFiFI) 170 | fillKnownMonthsShort(shortMonthNamesFiFI, LocaleFiFI) 171 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveFiFI, LocaleFiFI) 172 | fillKnownMonthsGenitiveShort(shortMonthNamesFiFI, LocaleFiFI) 173 | 174 | // Fr_FR: French (France) 175 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrFR) 176 | fillKnownDaysShort(shortDayNamesFrFR, LocaleFrFR) 177 | fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrFR) 178 | fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrFR) 179 | 180 | // Fr_CA: French (Canada) 181 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrCA) 182 | fillKnownDaysShort(shortDayNamesFrFR, LocaleFrCA) 183 | fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrCA) 184 | fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrCA) 185 | 186 | // Fr_GP: French (Guadeloupe) 187 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrGP) 188 | fillKnownDaysShort(shortDayNamesFrFR, LocaleFrGP) 189 | fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrGP) 190 | fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrGP) 191 | 192 | // Fr_LU: French (Luxembourg) 193 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrLU) 194 | fillKnownDaysShort(longDayNamesFrFR, LocaleFrLU) 195 | fillKnownMonthsLong(longDayNamesFrFR, LocaleFrLU) 196 | fillKnownMonthsShort(longDayNamesFrFR, LocaleFrLU) 197 | 198 | // Fr_MQ: French (Martinique) 199 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrMQ) 200 | fillKnownDaysShort(longDayNamesFrFR, LocaleFrMQ) 201 | fillKnownMonthsLong(longDayNamesFrFR, LocaleFrMQ) 202 | fillKnownMonthsShort(longDayNamesFrFR, LocaleFrMQ) 203 | 204 | // Fr_GF: French (French Guiana) 205 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrGF) 206 | fillKnownDaysShort(longDayNamesFrFR, LocaleFrGF) 207 | fillKnownMonthsLong(longDayNamesFrFR, LocaleFrGF) 208 | fillKnownMonthsShort(longDayNamesFrFR, LocaleFrGF) 209 | 210 | // Fr_RE: French (French Reunion) 211 | fillKnownDaysLong(longDayNamesFrFR, LocaleFrRE) 212 | fillKnownDaysShort(longDayNamesFrFR, LocaleFrRE) 213 | fillKnownMonthsLong(longDayNamesFrFR, LocaleFrRE) 214 | fillKnownMonthsShort(longDayNamesFrFR, LocaleFrRE) 215 | 216 | // De_DE: German (Germany) 217 | fillKnownDaysLong(longDayNamesDeDE, LocaleDeDE) 218 | fillKnownDaysShort(shortDayNamesDeDE, LocaleDeDE) 219 | fillKnownMonthsLong(longMonthNamesDeDE, LocaleDeDE) 220 | fillKnownMonthsShort(shortMonthNamesDeDE, LocaleDeDE) 221 | 222 | // Hu_HU: Hungarian (Hungary) 223 | fillKnownDaysLong(longDayNamesHuHU, LocaleHuHU) 224 | fillKnownDaysShort(shortDayNamesHuHU, LocaleHuHU) 225 | fillKnownMonthsLong(longMonthNamesHuHU, LocaleHuHU) 226 | fillKnownMonthsShort(shortMonthNamesHuHU, LocaleHuHU) 227 | 228 | // It_IT: Italian (Italy) 229 | fillKnownDaysLong(longDayNamesItIT, LocaleItIT) 230 | fillKnownDaysShort(shortDayNamesItIT, LocaleItIT) 231 | fillKnownMonthsLong(longMonthNamesItIT, LocaleItIT) 232 | fillKnownMonthsShort(shortMonthNamesItIT, LocaleItIT) 233 | 234 | // Nn_NO: Norwegian Nynorsk (Norway) 235 | fillKnownDaysLong(longDayNamesNnNO, LocaleNnNO) 236 | fillKnownDaysShort(shortDayNamesNnNO, LocaleNnNO) 237 | fillKnownMonthsLong(longMonthNamesNnNO, LocaleNnNO) 238 | fillKnownMonthsShort(shortMonthNamesNnNO, LocaleNnNO) 239 | 240 | // Nb_NO: Norwegian Bokmål (Norway) 241 | fillKnownDaysLong(longDayNamesNbNO, LocaleNbNO) 242 | fillKnownDaysShort(shortDayNamesNbNO, LocaleNbNO) 243 | fillKnownMonthsLong(longMonthNamesNbNO, LocaleNbNO) 244 | fillKnownMonthsShort(shortMonthNamesNbNO, LocaleNbNO) 245 | 246 | // Pl_PL: Polish (Poland) 247 | fillKnownDaysLong(longDayNamesPlPL, LocalePlPL) 248 | fillKnownDaysShort(shortDayNamesPlPL, LocalePlPL) 249 | fillKnownMonthsLong(longMonthNamesPlPL, LocalePlPL) 250 | fillKnownMonthsShort(shortMonthNamesPlPL, LocalePlPL) 251 | fillKnownMonthsGenitiveLong(longMonthNamesGenitivePlPL, LocalePlPL) 252 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitivePlPL, LocalePlPL) 253 | 254 | // Pt_PT: Portuguese (Portugal) 255 | fillKnownDaysLong(longDayNamesPtPT, LocalePtPT) 256 | fillKnownDaysShort(shortDayNamesPtPT, LocalePtPT) 257 | fillKnownMonthsLong(longMonthNamesPtPT, LocalePtPT) 258 | fillKnownMonthsShort(shortMonthNamesPtPT, LocalePtPT) 259 | 260 | // Pt_BR: Portuguese (Brazil) 261 | fillKnownDaysLong(longDayNamesPtBR, LocalePtBR) 262 | fillKnownDaysShort(shortDayNamesPtBR, LocalePtBR) 263 | fillKnownMonthsLong(longMonthNamesPtBR, LocalePtBR) 264 | fillKnownMonthsShort(shortMonthNamesPtBR, LocalePtBR) 265 | 266 | // Ro_RO: Romanian (Romania) 267 | fillKnownDaysLong(longDayNamesRoRO, LocaleRoRO) 268 | fillKnownDaysShort(shortDayNamesRoRO, LocaleRoRO) 269 | fillKnownMonthsLong(longMonthNamesRoRO, LocaleRoRO) 270 | fillKnownMonthsShort(shortMonthNamesRoRO, LocaleRoRO) 271 | 272 | // Ru_RU: Russian (Russia) 273 | fillKnownDaysLong(longDayNamesRuRU, LocaleRuRU) 274 | fillKnownDaysShort(shortDayNamesRuRU, LocaleRuRU) 275 | fillKnownMonthsLong(longMonthNamesRuRU, LocaleRuRU) 276 | fillKnownMonthsShort(shortMonthNamesRuRU, LocaleRuRU) 277 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveRuRU, LocaleRuRU) 278 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveRuRU, LocaleRuRU) 279 | 280 | // Es_ES: Spanish (Spain) 281 | fillKnownDaysLong(longDayNamesEsES, LocaleEsES) 282 | fillKnownDaysShort(shortDayNamesEsES, LocaleEsES) 283 | fillKnownMonthsLong(longMonthNamesEsES, LocaleEsES) 284 | fillKnownMonthsShort(shortMonthNamesEsES, LocaleEsES) 285 | 286 | // Ca_ES: Catalan (Spain) 287 | fillKnownDaysLong(longDayNamesCaES, LocaleCaES) 288 | fillKnownDaysShort(shortDayNamesCaES, LocaleCaES) 289 | fillKnownMonthsLong(longMonthNamesCaES, LocaleCaES) 290 | fillKnownMonthsShort(shortMonthNamesCaES, LocaleCaES) 291 | 292 | // Sv_SE: Swedish (Sweden) 293 | fillKnownDaysLong(longDayNamesSvSE, LocaleSvSE) 294 | fillKnownDaysShort(shortDayNamesSvSE, LocaleSvSE) 295 | fillKnownMonthsLong(longMonthNamesSvSE, LocaleSvSE) 296 | fillKnownMonthsShort(shortMonthNamesSvSE, LocaleSvSE) 297 | 298 | // Tr_TR: Turkish (Turkey) 299 | fillKnownDaysLong(longDayNamesTrTR, LocaleTrTR) 300 | fillKnownDaysShort(shortDayNamesTrTR, LocaleTrTR) 301 | fillKnownMonthsLong(longMonthNamesTrTR, LocaleTrTR) 302 | fillKnownMonthsShort(shortMonthNamesTrTR, LocaleTrTR) 303 | 304 | // Uk_UA: Ukrainian (Ukraine) 305 | fillKnownDaysLong(longDayNamesUkUA, LocaleUkUA) 306 | fillKnownDaysShort(shortDayNamesUkUA, LocaleUkUA) 307 | fillKnownMonthsLong(longMonthNamesUkUA, LocaleUkUA) 308 | fillKnownMonthsShort(shortMonthNamesUkUA, LocaleUkUA) 309 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveUkUA, LocaleUkUA) 310 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveUkUA, LocaleUkUA) 311 | 312 | // Bg_BG: Bulgarian (Bulgaria) 313 | fillKnownDaysLong(longDayNamesBgBG, LocaleBgBG) 314 | fillKnownDaysShort(shortDayNamesBgBG, LocaleBgBG) 315 | fillKnownMonthsLong(longMonthNamesBgBG, LocaleBgBG) 316 | fillKnownMonthsShort(shortMonthNamesBgBG, LocaleBgBG) 317 | 318 | // Zh_CN: Chinese (Mainland) 319 | fillKnownDaysLong(longDayNamesZhCN, LocaleZhCN) 320 | fillKnownDaysShort(shortDayNamesZhCN, LocaleZhCN) 321 | fillKnownMonthsLong(longMonthNamesZhCN, LocaleZhCN) 322 | fillKnownMonthsShort(shortMonthNamesZhCN, LocaleZhCN) 323 | 324 | // Zh_TW: Chinese (Taiwan) 325 | fillKnownDaysLong(longDayNamesZhTW, LocaleZhTW) 326 | fillKnownDaysShort(shortDayNamesZhTW, LocaleZhTW) 327 | fillKnownMonthsLong(longMonthNamesZhTW, LocaleZhTW) 328 | fillKnownMonthsShort(shortMonthNamesZhTW, LocaleZhTW) 329 | 330 | // Zh_HK: Chinese (Hong Kong) 331 | fillKnownDaysLong(longDayNamesZhHK, LocaleZhHK) 332 | fillKnownDaysShort(shortDayNamesZhHK, LocaleZhHK) 333 | fillKnownMonthsLong(longMonthNamesZhHK, LocaleZhHK) 334 | fillKnownMonthsShort(shortMonthNamesZhHK, LocaleZhHK) 335 | 336 | // Ko_KR: Korean (Korea) 337 | fillKnownDaysLong(longDayNamesKoKR, LocaleKoKR) 338 | fillKnownDaysShort(shortDayNamesKoKR, LocaleKoKR) 339 | fillKnownMonthsLong(longMonthNamesKoKR, LocaleKoKR) 340 | fillKnownMonthsShort(shortMonthNamesKoKR, LocaleKoKR) 341 | fillKnownPeriods(periodsKoKR, LocaleKoKR) 342 | 343 | // Ja_JP: Japanese (Japan) 344 | fillKnownDaysLong(longDayNamesJaJP, LocaleJaJP) 345 | fillKnownDaysShort(shortDayNamesJaJP, LocaleJaJP) 346 | fillKnownMonthsLong(longMonthNamesJaJP, LocaleJaJP) 347 | fillKnownMonthsShort(shortMonthNamesJaJP, LocaleJaJP) 348 | fillKnownPeriods(periodsJaJP, LocaleJaJP) 349 | 350 | // El_GR: Greek (Greece) 351 | fillKnownDaysLong(longDayNamesElGR, LocaleElGR) 352 | fillKnownDaysShort(shortDayNamesElGR, LocaleElGR) 353 | fillKnownMonthsLong(longMonthNamesElGR, LocaleElGR) 354 | fillKnownMonthsShort(shortMonthNamesElGR, LocaleElGR) 355 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveElGR, LocaleElGR) 356 | fillKnownMonthsGenitiveShort(shortMonthNamesElGR, LocaleElGR) 357 | fillKnownPeriods(periodsElGR, LocaleElGR) 358 | 359 | // Id_ID: Indonesia (Indonesia) 360 | fillKnownDaysLong(longDayNamesIdID, LocaleIdID) 361 | fillKnownDaysShort(shortDayNamesIdID, LocaleIdID) 362 | fillKnownMonthsLong(longMonthNamesIdID, LocaleIdID) 363 | fillKnownMonthsShort(shortMonthNamesIdID, LocaleIdID) 364 | 365 | // Cs_CZ: Czech (Czech Republic) 366 | fillKnownDaysLong(longDayNamesCsCZ, LocaleCsCZ) 367 | fillKnownDaysShort(shortDayNamesCsCZ, LocaleCsCZ) 368 | fillKnownMonthsLong(longMonthNamesCsCZ, LocaleCsCZ) 369 | fillKnownMonthsShort(shortMonthNamesCsCZ, LocaleCsCZ) 370 | 371 | // Sl_SI: Slovenian (Slovenia) 372 | fillKnownDaysLong(longDayNamesSlSI, LocaleSlSI) 373 | fillKnownDaysShort(shortDayNamesSlSI, LocaleSlSI) 374 | fillKnownMonthsLong(longMonthNamesSlSI, LocaleSlSI) 375 | fillKnownMonthsShort(shortMonthNamesSlSI, LocaleSlSI) 376 | 377 | // Lt_LT: Lithuanian (Lithuania) 378 | fillKnownDaysLong(longDayNamesLtLT, LocaleLtLT) 379 | fillKnownDaysShort(shortDayNamesLtLT, LocaleLtLT) 380 | fillKnownMonthsLong(longMonthNamesLtLT, LocaleLtLT) 381 | fillKnownMonthsShort(shortMonthNamesLtLT, LocaleLtLT) 382 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveLtLT, LocaleLtLT) 383 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveLtLT, LocaleLtLT) 384 | 385 | // Et_EE: Estonian (Estonia) 386 | fillKnownDaysLong(longDayNamesEtEE, LocaleEtEE) 387 | fillKnownDaysShort(shortDayNamesEtEE, LocaleEtEE) 388 | fillKnownMonthsLong(longMonthNamesEtEE, LocaleEtEE) 389 | fillKnownMonthsShort(shortMonthNamesEtEE, LocaleEtEE) 390 | 391 | // Hr_HR: Croatian (Croatia) 392 | fillKnownDaysLong(longDayNamesHrHR, LocaleHrHR) 393 | fillKnownDaysShort(shortDayNamesHrHR, LocaleHrHR) 394 | fillKnownMonthsLong(longMonthNamesHrHR, LocaleHrHR) 395 | fillKnownMonthsShort(shortMonthNamesHrHR, LocaleHrHR) 396 | 397 | // Lv_LV: Latvian (Latvia) 398 | fillKnownDaysLong(longDayNamesLvLV, LocaleLvLV) 399 | fillKnownDaysShort(shortDayNamesLvLV, LocaleLvLV) 400 | fillKnownMonthsLong(longMonthNamesLvLV, LocaleLvLV) 401 | fillKnownMonthsShort(shortMonthNamesLvLV, LocaleLvLV) 402 | 403 | // Sk_SK: Slovak (Slovakia) 404 | fillKnownDaysLong(longDayNamesSkSK, LocaleSkSK) 405 | fillKnownDaysShort(shortDayNamesSkSK, LocaleSkSK) 406 | fillKnownMonthsLong(longMonthNamesSkSK, LocaleSkSK) 407 | fillKnownMonthsShort(shortMonthNamesSkSK, LocaleSkSK) 408 | 409 | // Th_TH: Thai (Thailand) 410 | fillKnownDaysLong(longDayNamesThTH, LocaleThTH) 411 | fillKnownDaysShort(shortDayNamesThTH, LocaleThTH) 412 | fillKnownMonthsLong(longMonthNamesThTH, LocaleThTH) 413 | fillKnownMonthsShort(shortMonthNamesThTH, LocaleThTH) 414 | 415 | // Uz_UZ: Uzbek (Uzbekistan) 416 | fillKnownDaysLong(longDayNamesUzUZ, LocaleUzUZ) 417 | fillKnownDaysShort(shortDayNamesUzUZ, LocaleUzUZ) 418 | fillKnownMonthsLong(longMonthNamesUzUZ, LocaleUzUZ) 419 | fillKnownMonthsShort(shortMonthNamesUzUZ, LocaleUzUZ) 420 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveUzUZ, LocaleUzUZ) 421 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveUzUZ, LocaleUzUZ) 422 | 423 | // Kk_KZ: Kazakh (Kazakhstan) 424 | fillKnownDaysLong(longDayNamesKkKZ, LocaleKkKZ) 425 | fillKnownDaysShort(shortDayNamesKkKZ, LocaleKkKZ) 426 | fillKnownMonthsLong(longMonthNamesKkKZ, LocaleKkKZ) 427 | fillKnownMonthsShort(shortMonthNamesKkKZ, LocaleKkKZ) 428 | fillKnownMonthsGenitiveLong(longMonthNamesGenitiveKkKZ, LocaleKkKZ) 429 | fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveKkKZ, LocaleKkKZ) 430 | } 431 | 432 | func fill(src map[string]string, dest map[Locale]map[string]string, locale Locale) { 433 | loc, ok := dest[locale] 434 | 435 | if !ok { 436 | loc = make(map[string]string, len(src)) 437 | dest[locale] = loc 438 | } 439 | 440 | for k, v := range src { 441 | loc[k] = v 442 | } 443 | } 444 | 445 | func fillReverse(src map[string]string, dest map[Locale]map[string]string, locale Locale) { 446 | loc, ok := dest[locale] 447 | 448 | if !ok { 449 | loc = make(map[string]string, len(src)) 450 | dest[locale] = loc 451 | } 452 | 453 | for k, v := range src { 454 | loc[v] = k 455 | } 456 | } 457 | 458 | func fillKnownMonthsGenitiveShort(src map[string]string, locale Locale) { 459 | fillReverse(src, knownMonthsGenitiveShortReverse, locale) 460 | fill(src, knownMonthsGenitiveShort, locale) 461 | } 462 | 463 | func fillKnownMonthsGenitiveLong(src map[string]string, locale Locale) { 464 | fillReverse(src, knownMonthsGenitiveLongReverse, locale) 465 | fill(src, knownMonthsGenitiveLong, locale) 466 | } 467 | 468 | func fillKnownDaysShort(src map[string]string, locale Locale) { 469 | fillReverse(src, knownDaysShortReverse, locale) 470 | fill(src, knownDaysShort, locale) 471 | } 472 | 473 | func fillKnownDaysLong(src map[string]string, locale Locale) { 474 | fillReverse(src, knownDaysLongReverse, locale) 475 | fill(src, knownDaysLong, locale) 476 | } 477 | 478 | func fillKnownMonthsShort(src map[string]string, locale Locale) { 479 | fillReverse(src, knownMonthsShortReverse, locale) 480 | fill(src, knownMonthsShort, locale) 481 | } 482 | 483 | func fillKnownMonthsLong(src map[string]string, locale Locale) { 484 | fillReverse(src, knownMonthsLongReverse, locale) 485 | fill(src, knownMonthsLong, locale) 486 | } 487 | 488 | func fillKnownPeriods(src map[string]string, locale Locale) { 489 | fillReverse(src, knownPeriodsReverse, locale) 490 | fill(src, knownPeriods, locale) 491 | } 492 | 493 | // Format is the standard time.Format wrapper, that replaces known standard 'time' package 494 | // identifiers for months and days to their equivalents in the specified language. 495 | // 496 | // Values of variables 'longDayNames', 'shortDayNames', 'longMonthNames', 'shortMonthNames' 497 | // from file 'time/format.go' (revision 'go1') are chosen as the 'known' words. 498 | // 499 | // Some languages have specific behavior, e.g. in Russian language 500 | // month names have different suffix when they are presented stand-alone (i.e. in a list or something) 501 | // and yet another one when they are part of a formatted date. 502 | // So, even though March is "Март" in Russian, correctly formatted today's date would be: "7 марта 2007". 503 | // Thus, some transformations for some languages may be a bit more complex than just plain replacements. 504 | func Format(dt time.Time, layout string, locale Locale) string { 505 | fm := dt.Format(layout) 506 | intFunc, ok := internalFormatFuncs[locale] 507 | if !ok { 508 | return fm 509 | } 510 | return intFunc(fm, layout) 511 | } 512 | 513 | // ParseInLocation is the standard time.ParseInLocation wrapper, which replaces 514 | // known month/day translations for a specified locale back to English before 515 | // calling time.ParseInLocation. So, you can parse localized dates with this wrapper. 516 | func ParseInLocation(layout, value string, loc *time.Location, locale Locale) (time.Time, error) { 517 | intFunc, ok := internalParseFuncs[locale] 518 | if ok { 519 | value = intFunc(layout, value) 520 | } else { 521 | return time.Now(), fmt.Errorf("unsupported locale: %v", locale) 522 | } 523 | 524 | return time.ParseInLocation(layout, value, loc) 525 | } 526 | 527 | // Parse is the standard time.Parse wrapper, which replaces 528 | // known month/day translations for a specified locale back to English before 529 | // calling time.Parse. 530 | func Parse(layout, value string, locale Locale) (time.Time, error) { 531 | intFunc, ok := internalParseFuncs[locale] 532 | if ok { 533 | value = intFunc(layout, value) 534 | } else { 535 | return time.Now(), fmt.Errorf("unsupported locale: %v", locale) 536 | } 537 | 538 | return time.Parse(layout, value) 539 | } 540 | 541 | // GetShortDays retrieves the list of days for the given locale. 542 | // "Short" days are abbreviated versions of the full day names. In English, 543 | // for example, this might return "Tues" for "Tuesday". For certain locales, 544 | // the long and short form of the days of the week may be the same. 545 | // 546 | // If the locale cannot be found, the resulting slice will be nil. 547 | func GetShortDays(locale Locale) []string { 548 | days, ok := knownDaysShort[locale] 549 | if !ok { 550 | return nil 551 | } 552 | 553 | var dayOrder []string 554 | 555 | // according to https://www.timeanddate.com/calendar/days/monday.html 556 | // only Canada, USA and Japan use Sunday as first day of the week 557 | switch locale { 558 | case LocaleEnUS, LocaleJaJP: 559 | dayOrder = dayShortOrderSundayFirst 560 | default: 561 | dayOrder = dayShortOrderMondayFirst 562 | } 563 | 564 | ret := make([]string, 0, len(days)) 565 | for _, day := range dayOrder { 566 | ret = append(ret, days[day]) 567 | } 568 | return ret 569 | } 570 | 571 | // GetShortMonths retrieves the list of months for the given locale. 572 | // "Short" months are abbreviated versions of the full month names. In 573 | // English, for example, this might return "Jan" for "January". For 574 | // certain locales, the long and short form of the months may be the same. 575 | // 576 | // If the locale cannot be found, the resulting slice will be nil. 577 | func GetShortMonths(locale Locale) []string { 578 | months, ok := knownMonthsShort[locale] 579 | if !ok { 580 | return nil 581 | } 582 | 583 | ret := make([]string, 0, len(months)) 584 | for _, m := range monthShortOrder { 585 | ret = append(ret, months[m]) 586 | } 587 | return ret 588 | } 589 | 590 | // GetLongDays retrieves the list of days for the given locale. It will return 591 | // the full name of the days of the week. 592 | // 593 | // If the locale cannot be found, the resulting slice will be nil. 594 | func GetLongDays(locale Locale) []string { 595 | days, ok := knownDaysLong[locale] 596 | if !ok { 597 | return nil 598 | } 599 | 600 | var dayOrder []string 601 | 602 | // according to https://www.timeanddate.com/calendar/days/monday.html 603 | // only Canada, USA and Japan use Sunday as first day of the week 604 | switch locale { 605 | case LocaleEnUS, LocaleJaJP: 606 | dayOrder = dayLongOrderSundayFirst 607 | default: 608 | dayOrder = dayLongOrderMondayFirst 609 | } 610 | 611 | ret := make([]string, 0, len(days)) 612 | for _, day := range dayOrder { 613 | ret = append(ret, days[day]) 614 | } 615 | return ret 616 | } 617 | 618 | // GetLongMonths retrieves the list of months for the given locale. In 619 | // contrast to the "short" version of this function, this functions returns 620 | // the full name of the month. 621 | // 622 | // If the locale cannot be found, the resulting slice will be nil. 623 | func GetLongMonths(locale Locale) []string { 624 | months, ok := knownMonthsLong[locale] 625 | if !ok { 626 | return nil 627 | } 628 | 629 | ret := make([]string, 0, len(months)) 630 | for _, m := range monthLongOrder { 631 | ret = append(ret, months[m]) 632 | } 633 | 634 | return ret 635 | } 636 | -------------------------------------------------------------------------------- /monday_test.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | type FormatTest struct { 10 | locale Locale 11 | date time.Time 12 | layout string 13 | expected string 14 | } 15 | 16 | var formatTests = []FormatTest{ 17 | {LocaleEnUS, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Tue Sep 3 2013"}, 18 | {LocaleEnUS, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Wednesday Sep 4 2013"}, 19 | {LocaleEnUS, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Thursday October 03 2013"}, 20 | {LocaleEnUS, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Sunday. 3 November 2013"}, 21 | {LocaleEnUS, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 May. Monday"}, 22 | {LocaleEnUS, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 May 2013"}, 23 | {LocaleEnUS, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "May"}, 24 | {LocaleEnUS, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 May"}, 25 | 26 | {LocaleEnGB, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Tue Sep 3 2013"}, 27 | {LocaleEnGB, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Wednesday Sep 4 2013"}, 28 | {LocaleEnGB, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Thursday October 03 2013"}, 29 | {LocaleEnGB, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Sunday. 3 November 2013"}, 30 | {LocaleEnGB, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 May. Monday"}, 31 | {LocaleEnGB, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 May 2013"}, 32 | {LocaleEnGB, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "May"}, 33 | {LocaleEnGB, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 May"}, 34 | 35 | {LocaleDaDK, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "tir sep 3 2013"}, 36 | {LocaleDaDK, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "onsdag sep 4 2013"}, 37 | {LocaleDaDK, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "torsdag oktober 03 2013"}, 38 | {LocaleDaDK, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "søndag. 3 november 2013"}, 39 | {LocaleDaDK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maj. mandag"}, 40 | {LocaleDaDK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maj 2013"}, 41 | {LocaleDaDK, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maj"}, 42 | {LocaleDaDK, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maj"}, 43 | 44 | {LocaleNlBE, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "di sep 3 2013"}, 45 | {LocaleNlBE, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "woensdag sep 4 2013"}, 46 | {LocaleNlBE, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "donderdag oktober 03 2013"}, 47 | {LocaleNlBE, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "zondag. 3 november 2013"}, 48 | {LocaleNlBE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mei. maandag"}, 49 | {LocaleNlBE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mei 2013"}, 50 | {LocaleNlBE, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mei"}, 51 | {LocaleNlBE, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mei"}, 52 | 53 | {LocaleNlNL, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "di sep 3 2013"}, 54 | {LocaleNlNL, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "woensdag sep 4 2013"}, 55 | {LocaleNlNL, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "donderdag oktober 03 2013"}, 56 | {LocaleNlNL, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "zondag. 3 november 2013"}, 57 | {LocaleNlNL, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mei. maandag"}, 58 | {LocaleNlNL, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mei 2013"}, 59 | {LocaleNlNL, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mei"}, 60 | {LocaleNlNL, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mei"}, 61 | 62 | {LocaleFiFI, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ti syys 3 2013"}, 63 | {LocaleFiFI, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "keskiviikko syys 4 2013"}, 64 | {LocaleFiFI, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "torstai lokakuu 03 2013"}, 65 | {LocaleFiFI, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "sunnuntai. 3 marraskuuta 2013"}, 66 | {LocaleFiFI, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 toukokuuta. maanantai"}, 67 | {LocaleFiFI, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 touko 2013"}, 68 | {LocaleFiFI, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "toukokuu"}, 69 | {LocaleFiFI, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 toukokuuta"}, 70 | 71 | {LocaleFrFR, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 72 | {LocaleFrFR, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 73 | {LocaleFrFR, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 74 | {LocaleFrFR, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 75 | {LocaleFrFR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 76 | {LocaleFrFR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 77 | {LocaleFrFR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 78 | {LocaleFrFR, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 79 | 80 | {LocaleFrCA, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 81 | {LocaleFrCA, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 82 | {LocaleFrCA, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 83 | {LocaleFrCA, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 84 | {LocaleFrCA, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 85 | {LocaleFrCA, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 86 | {LocaleFrCA, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 87 | {LocaleFrCA, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 88 | 89 | {LocaleFrGP, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 90 | {LocaleFrGP, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 91 | {LocaleFrGP, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 92 | {LocaleFrGP, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 93 | {LocaleFrGP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 94 | {LocaleFrGP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 95 | {LocaleFrGP, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 96 | {LocaleFrGP, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 97 | 98 | {LocaleFrLU, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 99 | {LocaleFrLU, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 100 | {LocaleFrLU, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 101 | {LocaleFrLU, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 102 | {LocaleFrLU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 103 | {LocaleFrLU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 104 | {LocaleFrLU, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 105 | {LocaleFrLU, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 106 | 107 | {LocaleFrMQ, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 108 | {LocaleFrMQ, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 109 | {LocaleFrMQ, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 110 | {LocaleFrMQ, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 111 | {LocaleFrMQ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 112 | {LocaleFrMQ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 113 | {LocaleFrMQ, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 114 | {LocaleFrMQ, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 115 | 116 | {LocaleFrGF, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 117 | {LocaleFrGF, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 118 | {LocaleFrGF, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 119 | {LocaleFrGF, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 120 | {LocaleFrGF, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 121 | {LocaleFrGF, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 122 | {LocaleFrGF, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 123 | {LocaleFrGF, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 124 | 125 | {LocaleFrRE, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sept 3 2013"}, 126 | {LocaleFrRE, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercredi sept 4 2013"}, 127 | {LocaleFrRE, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jeudi octobre 03 2013"}, 128 | {LocaleFrRE, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "dimanche. 3 novembre 2013"}, 129 | {LocaleFrRE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. lundi"}, 130 | {LocaleFrRE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 131 | {LocaleFrRE, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 132 | {LocaleFrRE, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 133 | 134 | {LocaleDeDE, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Di Sep 3 2013"}, 135 | {LocaleDeDE, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Mittwoch Sep 4 2013"}, 136 | {LocaleDeDE, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Donnerstag Oktober 03 2013"}, 137 | {LocaleDeDE, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Sonntag. 3 November 2013"}, 138 | {LocaleDeDE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Mai. Montag"}, 139 | {LocaleDeDE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 Mai 2013"}, 140 | {LocaleDeDE, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Mai"}, 141 | {LocaleDeDE, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Mai"}, 142 | 143 | {LocaleHuHU, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "K szept 3 2013"}, 144 | {LocaleHuHU, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "szerda szept 4 2013"}, 145 | {LocaleHuHU, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "csütörtök október 03 2013"}, 146 | {LocaleHuHU, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "vasárnap. 3 november 2013"}, 147 | {LocaleHuHU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 május. hétfő"}, 148 | {LocaleHuHU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 máj 2013"}, 149 | {LocaleHuHU, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "május"}, 150 | {LocaleHuHU, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 május"}, 151 | 152 | {LocaleItIT, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar set 3 2013"}, 153 | {LocaleItIT, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "mercoledì set 4 2013"}, 154 | {LocaleItIT, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "giovedì ottobre 03 2013"}, 155 | {LocaleItIT, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "domenica. 3 novembre 2013"}, 156 | {LocaleItIT, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maggio. lunedì"}, 157 | {LocaleItIT, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mag 2013"}, 158 | {LocaleItIT, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maggio"}, 159 | {LocaleItIT, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maggio"}, 160 | 161 | {LocaleNnNO, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ty sep 3 2013"}, 162 | {LocaleNnNO, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "onsdag sep 4 2013"}, 163 | {LocaleNnNO, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "torsdag oktober 03 2013"}, 164 | {LocaleNnNO, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "søndag. 3 november 2013"}, 165 | {LocaleNnNO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. måndag"}, 166 | {LocaleNnNO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 167 | {LocaleNnNO, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 168 | {LocaleNnNO, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 169 | 170 | {LocaleNbNO, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ti sep 3 2013"}, 171 | {LocaleNbNO, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "onsdag sep 4 2013"}, 172 | {LocaleNbNO, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "torsdag oktober 03 2013"}, 173 | {LocaleNbNO, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "søndag. 3 november 2013"}, 174 | {LocaleNbNO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. mandag"}, 175 | {LocaleNbNO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 176 | {LocaleNbNO, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 177 | {LocaleNbNO, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 178 | 179 | {LocalePlPL, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Wto Wrz 3 2013"}, 180 | {LocalePlPL, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Środa Wrz 4 2013"}, 181 | {LocalePlPL, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Czwartek Październik 03 2013"}, 182 | {LocalePlPL, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Niedziela. 3 listopada 2013"}, 183 | {LocalePlPL, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maja. Poniedziałek"}, 184 | {LocalePlPL, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maj 2013"}, 185 | {LocalePlPL, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Maj"}, 186 | {LocalePlPL, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maja"}, 187 | 188 | {LocalePtPT, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ter Set 3 2013"}, 189 | {LocalePtPT, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Quarta-feira Set 4 2013"}, 190 | {LocalePtPT, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Quinta-feira Outubro 03 2013"}, 191 | {LocalePtPT, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Domingo. 3 Novembro 2013"}, 192 | {LocalePtPT, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Maio. Segunda-feira"}, 193 | {LocalePtPT, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 Mai 2013"}, 194 | {LocalePtPT, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Maio"}, 195 | {LocalePtPT, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Maio"}, 196 | 197 | {LocalePtBR, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ter set 3 2013"}, 198 | {LocalePtBR, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "quarta-feira set 4 2013"}, 199 | {LocalePtBR, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "quinta-feira outubro 03 2013"}, 200 | {LocalePtBR, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "domingo. 3 novembro 2013"}, 201 | {LocalePtBR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maio. segunda-feira"}, 202 | {LocalePtBR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 203 | {LocalePtBR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maio"}, 204 | {LocalePtBR, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maio"}, 205 | 206 | {LocaleRoRO, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Ma sept 3 2013"}, 207 | {LocaleRoRO, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "miercuri sept 4 2013"}, 208 | {LocaleRoRO, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "joi octombrie 03 2013"}, 209 | {LocaleRoRO, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "duminică. 3 noiembrie 2013"}, 210 | {LocaleRoRO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. luni"}, 211 | {LocaleRoRO, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 212 | {LocaleRoRO, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 213 | {LocaleRoRO, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 214 | 215 | {LocaleRuRU, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Вт Сен 3 2013"}, 216 | {LocaleRuRU, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Среда Сен 4 2013"}, 217 | {LocaleRuRU, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Четверг Октябрь 03 2013"}, 218 | {LocaleRuRU, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Воскресенье. 3 ноября 2013"}, 219 | {LocaleRuRU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 мая. Понедельник"}, 220 | {LocaleRuRU, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 мая 2013"}, 221 | {LocaleRuRU, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Май"}, 222 | {LocaleRuRU, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 мая"}, 223 | 224 | {LocaleEsES, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "mar sep 3 2013"}, 225 | {LocaleEsES, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "miércoles sep 4 2013"}, 226 | {LocaleEsES, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "jueves octubre 03 2013"}, 227 | {LocaleEsES, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "domingo. 3 noviembre 2013"}, 228 | {LocaleEsES, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mayo. lunes"}, 229 | {LocaleEsES, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 may 2013"}, 230 | {LocaleEsES, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mayo"}, 231 | {LocaleEsES, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mayo"}, 232 | 233 | {LocaleCaES, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "dt set 3 2013"}, 234 | {LocaleCaES, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "dimecres set 4 2013"}, 235 | {LocaleCaES, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "dijous octubre 03 2013"}, 236 | {LocaleCaES, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "diumenge. 3 novembre 2013"}, 237 | {LocaleCaES, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maig. dilluns"}, 238 | {LocaleCaES, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maig 2013"}, 239 | {LocaleCaES, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maig"}, 240 | {LocaleCaES, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maig"}, 241 | 242 | {LocaleSvSE, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "tis sep 3 2013"}, 243 | {LocaleSvSE, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "onsdag sep 4 2013"}, 244 | {LocaleSvSE, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "torsdag oktober 03 2013"}, 245 | {LocaleSvSE, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "söndag. 3 november 2013"}, 246 | {LocaleSvSE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maj. måndag"}, 247 | {LocaleSvSE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maj 2013"}, 248 | {LocaleSvSE, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maj"}, 249 | {LocaleSvSE, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maj"}, 250 | 251 | {LocaleTrTR, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Sal Eyl 3 2013"}, 252 | {LocaleTrTR, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Çarşamba Eyl 4 2013"}, 253 | {LocaleTrTR, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Perşembe Ekim 03 2013"}, 254 | {LocaleTrTR, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Pazar. 3 Kasım 2013"}, 255 | {LocaleTrTR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Mayıs. Pazartesi"}, 256 | {LocaleTrTR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 May 2013"}, 257 | {LocaleTrTR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Mayıs"}, 258 | {LocaleTrTR, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Mayıs"}, 259 | 260 | {LocaleUkUA, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Вт Вер 3 2013"}, 261 | {LocaleUkUA, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Середа Вер 4 2013"}, 262 | {LocaleUkUA, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Четвер Жовтень 03 2013"}, 263 | {LocaleUkUA, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Неділя. 3 листопада 2013"}, 264 | {LocaleUkUA, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 травня. Понеділок"}, 265 | {LocaleUkUA, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 тра 2013"}, 266 | {LocaleUkUA, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Травень"}, 267 | {LocaleUkUA, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 травня"}, 268 | 269 | {LocaleBgBG, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Вт Сеп 3 2013"}, 270 | {LocaleBgBG, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Сряда Сеп 4 2013"}, 271 | {LocaleBgBG, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Четвъртък Октомври 03 2013"}, 272 | {LocaleBgBG, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Неделя. 3 Ноември 2013"}, 273 | {LocaleBgBG, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Май. Понеделник"}, 274 | {LocaleBgBG, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 Май 2013"}, 275 | {LocaleBgBG, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Май"}, 276 | {LocaleBgBG, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Май"}, 277 | 278 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006-01-2", "2013-05-13"}, 279 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/1/2 Monday", "2013/5/13 星期一"}, 280 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日 Monday", "2013年5月13日 星期一"}, 281 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日", "2013年5月13日"}, 282 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 Jan 2日", "2013年 5 13日"}, 283 | {LocaleZhCN, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 January 2日", "2013年 5 月 13日"}, 284 | {LocaleZhCN, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "5 月"}, 285 | 286 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006-01-2", "2013-05-13"}, 287 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/1/2 Monday", "2013/5/13 星期一"}, 288 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日 Monday", "2013年5月13日 星期一"}, 289 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日", "2013年5月13日"}, 290 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 Jan 2日", "2013年 5 13日"}, 291 | {LocaleZhTW, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 January 2日", "2013年 5 月 13日"}, 292 | {LocaleZhTW, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "5 月"}, 293 | 294 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006-01-2", "2013-05-13"}, 295 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/1/2 Monday", "2013/5/13 星期一"}, 296 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日 Monday", "2013年5月13日 星期一"}, 297 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年1月2日", "2013年5月13日"}, 298 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 Jan 2日", "2013年 5 13日"}, 299 | {LocaleZhHK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006年 January 2日", "2013年 5 月 13日"}, 300 | {LocaleZhHK, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "5 月"}, 301 | 302 | {LocaleKoKR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/01/2", "2013/05/13"}, 303 | {LocaleKoKR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/1/2 Monday", "2013/5/13 월요일"}, 304 | {LocaleKoKR, time.Date(2013, 5, 13, 10, 30, 0, 0, time.UTC), "2006/1/2 Monday 3:04pm", "2013/5/13 월요일 10:30오전"}, 305 | {LocaleKoKR, time.Date(2013, 5, 13, 23, 30, 0, 0, time.UTC), "2006/1/2 Monday 3:04PM", "2013/5/13 월요일 11:30오후"}, 306 | {LocaleKoKR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 Jan 2 Monday", "2013 5월 13 월요일"}, 307 | {LocaleKoKR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 Jan 2", "2013 5월 13"}, 308 | {LocaleKoKR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 January 2", "2013 5월 13"}, 309 | {LocaleKoKR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "5월"}, 310 | 311 | {LocaleJaJP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/01/2", "2013/05/13"}, 312 | {LocaleJaJP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006/1/2 Monday", "2013/5/13 月曜日"}, 313 | {LocaleJaJP, time.Date(2013, 5, 13, 10, 30, 0, 0, time.UTC), "2006/1/2 Monday 3:04pm", "2013/5/13 月曜日 10:30午前"}, 314 | {LocaleJaJP, time.Date(2013, 5, 13, 23, 30, 0, 0, time.UTC), "2006/1/2 Monday 3:04PM", "2013/5/13 月曜日 11:30午後"}, 315 | {LocaleJaJP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 Jan 2 Monday", "2013 5月 13 月曜日"}, 316 | {LocaleJaJP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 Jan 2", "2013 5月 13"}, 317 | {LocaleJaJP, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006 January 2", "2013 5月 13"}, 318 | {LocaleJaJP, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "5月"}, 319 | 320 | {LocaleElGR, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Τρι Σεπ 3 2013"}, 321 | {LocaleElGR, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Τετάρτη Σεπ 4 2013"}, 322 | {LocaleElGR, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Πέμπτη Οκτώβριος 03 2013"}, 323 | {LocaleElGR, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Κυριακή. 3 Νοεμβρίου 2013"}, 324 | {LocaleElGR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Μαΐου. Δευτέρα"}, 325 | {LocaleElGR, time.Date(2015, 5, 23, 22, 7, 0, 0, time.UTC), "2 Jan 2006 3:04pm", "23 Μαϊ 2015 10:07μμ"}, 326 | {LocaleElGR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Μάιος"}, 327 | {LocaleElGR, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Μαΐου"}, 328 | 329 | {LocaleIdID, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Sel Sep 3 2013"}, 330 | {LocaleIdID, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Rabu Sep 4 2013"}, 331 | {LocaleIdID, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Kamis Oktober 03 2013"}, 332 | {LocaleIdID, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Minggu. 3 November 2013"}, 333 | {LocaleIdID, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 Mei. Senin"}, 334 | {LocaleIdID, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 Mei 2013"}, 335 | {LocaleIdID, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Mei"}, 336 | {LocaleIdID, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 Mei"}, 337 | 338 | {LocaleCsCZ, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "út zář 3 2013"}, 339 | {LocaleCsCZ, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "středa zář 4 2013"}, 340 | {LocaleCsCZ, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "čtvrtek říjen 03 2013"}, 341 | {LocaleCsCZ, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "neděle. 3 listopad 2013"}, 342 | {LocaleCsCZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 květen. pondělí"}, 343 | {LocaleCsCZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 kvě 2013"}, 344 | {LocaleCsCZ, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "květen"}, 345 | {LocaleCsCZ, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 květen"}, 346 | 347 | {LocaleSlSI, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "tor sep 3 2013"}, 348 | {LocaleSlSI, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "sreda sep 4 2013"}, 349 | {LocaleSlSI, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "četrtek oktober 03 2013"}, 350 | {LocaleSlSI, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "nedelja. 3 november 2013"}, 351 | {LocaleSlSI, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maj. ponedeljek"}, 352 | {LocaleSlSI, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maj 2013"}, 353 | {LocaleSlSI, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maj"}, 354 | {LocaleSlSI, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maj"}, 355 | 356 | {LocaleEtEE, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "T sept 3 2013"}, 357 | {LocaleEtEE, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "kolmapäev sept 4 2013"}, 358 | {LocaleEtEE, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "neljapäev oktoober 03 2013"}, 359 | {LocaleEtEE, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "pühapäev. 3 november 2013"}, 360 | {LocaleEtEE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 mai. esmaspäev"}, 361 | {LocaleEtEE, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 mai 2013"}, 362 | {LocaleEtEE, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "mai"}, 363 | {LocaleEtEE, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 mai"}, 364 | 365 | {LocaleHrHR, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "uto ruj 3 2013"}, 366 | {LocaleHrHR, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "srijeda ruj 4 2013"}, 367 | {LocaleHrHR, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "četvrtak listopad 03 2013"}, 368 | {LocaleHrHR, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "nedjelja. 3 studeni 2013"}, 369 | {LocaleHrHR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 svibanj. ponedjeljak"}, 370 | {LocaleHrHR, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 svi 2013"}, 371 | {LocaleHrHR, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "svibanj"}, 372 | {LocaleHrHR, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 svibanj"}, 373 | 374 | {LocaleLvLV, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Otrd sept 3 2013"}, 375 | {LocaleLvLV, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Trešdiena sept 4 2013"}, 376 | {LocaleLvLV, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Ceturtdiena oktobris 03 2013"}, 377 | {LocaleLvLV, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Svētdiena. 3 novembris 2013"}, 378 | {LocaleLvLV, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 maijs. Pirmdiena"}, 379 | {LocaleLvLV, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 maijs 2013"}, 380 | {LocaleLvLV, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "maijs"}, 381 | {LocaleLvLV, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 maijs"}, 382 | 383 | {LocaleSkSK, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ut sep 3 2013"}, 384 | {LocaleSkSK, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "streda sep 4 2013"}, 385 | {LocaleSkSK, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "štvrtok október 03 2013"}, 386 | {LocaleSkSK, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "nedeľa. 3 november 2013"}, 387 | {LocaleSkSK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 máj. pondelok"}, 388 | {LocaleSkSK, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 máj 2013"}, 389 | {LocaleSkSK, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "máj"}, 390 | {LocaleSkSK, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 máj"}, 391 | 392 | {LocaleThTH, time.Date(2022, 7, 8, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "ศ. ก.ค. 8 2022"}, 393 | {LocaleThTH, time.Date(2022, 7, 8, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "วันศุกร์ ก.ค. 8 2022"}, 394 | {LocaleThTH, time.Date(2022, 2, 1, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "วันอังคาร กุมภาพันธ์ 01 2022"}, 395 | {LocaleThTH, time.Date(2022, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January.", "2022. 13 พฤษภาคม."}, 396 | {LocaleThTH, time.Date(2022, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 พ.ค. 2022"}, 397 | {LocaleThTH, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "พฤษภาคม"}, 398 | {LocaleThTH, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 พฤษภาคม"}, 399 | 400 | {LocaleUzUZ, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Se Sen 3 2013"}, 401 | {LocaleUzUZ, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Chorshanba Sen 4 2013"}, 402 | {LocaleUzUZ, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Payshanba Oktyabr 03 2013"}, 403 | {LocaleUzUZ, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Yakshanba. 3 noyabr 2013"}, 404 | {LocaleUzUZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 may. Dushanba"}, 405 | {LocaleUzUZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 may 2013"}, 406 | {LocaleUzUZ, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "May"}, 407 | {LocaleUzUZ, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 may"}, 408 | 409 | {LocaleKkKZ, time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "Сс Қыр 3 2013"}, 410 | {LocaleKkKZ, time.Date(2013, 9, 4, 0, 0, 0, 0, time.UTC), "Monday Jan 2 2006", "Сәрсенбі Қыр 4 2013"}, 411 | {LocaleKkKZ, time.Date(2013, 10, 3, 0, 0, 0, 0, time.UTC), "Monday January 02 2006", "Бейсенбі Қазан 03 2013"}, 412 | {LocaleKkKZ, time.Date(2013, 11, 3, 0, 0, 0, 0, time.UTC), "Monday. 2 January 2006", "Жексенбі. 3 қараша 2013"}, 413 | {LocaleKkKZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2006. 2 January. Monday", "2013. 13 мамыр. Дүйсенбі"}, 414 | {LocaleKkKZ, time.Date(2013, 5, 13, 0, 0, 0, 0, time.UTC), "2 Jan 2006", "13 мам 2013"}, 415 | {LocaleKkKZ, time.Date(0, 5, 1, 0, 0, 0, 0, time.UTC), "January", "Мамыр"}, 416 | {LocaleKkKZ, time.Date(0, 5, 13, 0, 0, 0, 0, time.UTC), "2 January", "13 мамыр"}, 417 | } 418 | 419 | func TestFormat(t *testing.T) { 420 | for i, ts := range formatTests { 421 | txt := Format(ts.date, ts.layout, ts.locale) 422 | 423 | if txt != ts.expected { 424 | t.Errorf("Test #%d (%s: %s) => Format failed.\n Got: %s\n Expected: %s\n", i, ts.locale, ts.layout, txt, ts.expected) 425 | continue 426 | } 427 | 428 | reverseDate, err := ParseInLocation(ts.layout, txt, time.UTC, ts.locale) 429 | 430 | if err != nil { 431 | t.Errorf("Test #%d (%s: %s) => Reverse parse from '%s' error: %s", i, ts.locale, ts.layout, txt, err) 432 | continue 433 | } 434 | 435 | if reverseDate != ts.date { 436 | t.Errorf("Test #%d (%s: %s) => Reverse parse from '%s' failed.\n Got: %s\n Expected: %s\n", 437 | i, ts.locale, ts.layout, txt, reverseDate.Format(time.RFC850), ts.date.Format(time.RFC850)) 438 | continue 439 | } 440 | } 441 | } 442 | 443 | func BenchmarkFormat(b *testing.B) { 444 | for i := 0; i < b.N; i++ { 445 | for _, ts := range formatTests { 446 | txt := Format(ts.date, ts.layout, ts.locale) 447 | 448 | if txt != ts.expected { 449 | b.Errorf("failed") 450 | continue 451 | } 452 | } 453 | } 454 | } 455 | 456 | func TestBadLocale(t *testing.T) { 457 | txt := Format(time.Date(2013, 9, 3, 0, 0, 0, 0, time.UTC), "Mon Jan 2 2006", "aa_AA") 458 | if txt != "Tue Sep 3 2013" { 459 | t.Error("Failed to test with bad locale. ", txt) 460 | } 461 | 462 | _, err := ParseInLocation("Mon January 2006", "Sun April 2013", time.UTC, "aa_AA") 463 | if err.Error() != "unsupported locale: aa_AA" { 464 | t.Error("Failed to test with unsupported locale.") 465 | } 466 | } 467 | 468 | func TestGetShortDays(t *testing.T) { 469 | locales := ListLocales() 470 | for _, locale := range locales { 471 | days := GetShortDays(locale) 472 | if days == nil || len(days) != 7 { 473 | t.Error("Not expected result. ", days) 474 | } 475 | 476 | // according to https://www.timeanddate.com/calendar/days/monday.html 477 | // only Canada, USA and Japan use Sunday as first day of the week 478 | switch locale { 479 | case LocaleEnUS: 480 | if days[0] != shortDayNamesEnUS["Sun"] { 481 | t.Error("first day of week in US should be Sunday", days) 482 | } 483 | case LocaleJaJP: 484 | if days[0] != shortDayNamesJaJP["Sun"] { 485 | t.Error("first day of week in JP should be Sunday", days) 486 | } 487 | 488 | default: 489 | if days[0] != knownDaysShort[locale]["Mon"] { 490 | t.Error("first day of week should be Monday", days, locale) 491 | } 492 | } 493 | } 494 | } 495 | 496 | func TestGetLongDays(t *testing.T) { 497 | locales := ListLocales() 498 | for _, locale := range locales { 499 | days := GetLongDays(locale) 500 | if days == nil || len(days) != 7 { 501 | t.Error("Not expected result. ", days) 502 | } 503 | 504 | // according to https://www.timeanddate.com/calendar/days/monday.html 505 | // only Canada, USA and Japan use Sunday as first day of the week 506 | switch locale { 507 | case LocaleEnUS: 508 | if days[0] != longDayNamesEnUS["Sunday"] { 509 | t.Error("first day of week in US should be Sunday", days) 510 | } 511 | case LocaleJaJP: 512 | if days[0] != longDayNamesJaJP["Sunday"] { 513 | t.Error("first day of week in JP should be Sunday", days) 514 | } 515 | 516 | default: 517 | if days[0] != knownDaysLong[locale]["Monday"] { 518 | t.Error("first day of week should be Monday", days, locale) 519 | } 520 | } 521 | } 522 | } 523 | 524 | func ExampleFormat() { 525 | t := time.Date(2013, 4, 25, 0, 0, 0, 0, time.UTC) 526 | 527 | locales := ListLocales() 528 | for _, loc := range locales { 529 | fmt.Printf("Locale: %s\n", loc) 530 | 531 | // Full date format 532 | fmt.Printf(" Full: %s\n", Format(t, FullFormatsByLocale[loc], loc)) 533 | // Long date format 534 | fmt.Printf(" Long: %s\n", Format(t, LongFormatsByLocale[loc], loc)) 535 | // Medium date format 536 | fmt.Printf(" Medium: %s\n", Format(t, MediumFormatsByLocale[loc], loc)) 537 | // Short date format 538 | fmt.Printf(" Short: %s\n", Format(t, ShortFormatsByLocale[loc], loc)) 539 | // DateTime format 540 | fmt.Printf(" DateTime: %s\n", Format(t, DateTimeFormatsByLocale[loc], loc)) 541 | } 542 | } 543 | 544 | func ExampleParseInLocation() { 545 | layout := "2 January 2006 15:04:05 MST" 546 | 547 | fmt.Println(ParseInLocation(layout, "12 April 2013 00:00:00 MST", time.UTC, LocaleEnUS)) 548 | fmt.Println(ParseInLocation(layout, "12 апреля 2013 00:00:00 MST", time.UTC, LocaleRuRU)) 549 | fmt.Println(ParseInLocation(layout, "12 квітня 2013 00:00:00 MST", time.UTC, LocaleUkUA)) 550 | } 551 | 552 | func ExampleParse() { 553 | layout := "2 January 2006 15:04:05 MST" 554 | 555 | fmt.Println(Parse(layout, "12 April 2013 00:00:00 MST", LocaleEnUS)) 556 | fmt.Println(Parse(layout, "12 апреля 2013 00:00:00 MST", LocaleRuRU)) 557 | fmt.Println(Parse(layout, "12 квітня 2013 00:00:00 MST", LocaleUkUA)) 558 | } 559 | -------------------------------------------------------------------------------- /set.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import "sync" 4 | 5 | var keyExists = struct{}{} 6 | 7 | // Set is a thread safe set data structure. 8 | // 9 | // It is ported from https://github.com/fatih/set with only the required functionality. 10 | type set struct { 11 | m map[Locale]struct{} 12 | l sync.RWMutex 13 | } 14 | 15 | // NewSet allocates and returns a new Set. It accepts a variable number of 16 | // arguments to populate the initial set. If nothing is passed a Set with zero 17 | // size is created. 18 | func newSet(items ...Locale) *set { 19 | s := set{ 20 | m: make(map[Locale]struct{}), 21 | } 22 | s.Add(items...) 23 | return &s 24 | } 25 | 26 | // Add adds the specified items (one or more) to the set. The underlying 27 | // Set s is modified. If no items are passed it silently returns. 28 | func (s *set) Add(items ...Locale) { 29 | if len(items) == 0 { 30 | return 31 | } 32 | s.l.Lock() 33 | defer s.l.Unlock() 34 | for _, item := range items { 35 | s.m[item] = keyExists 36 | } 37 | } 38 | 39 | // Each traverses the items in the Set, calling the provided function f for 40 | // each set member. Traversal will continue until all items in the Set have 41 | // been visited, or if the closure returns false. 42 | func (s *set) Each(f func(item Locale) bool) { 43 | s.l.RLock() 44 | defer s.l.RUnlock() 45 | for item := range s.m { 46 | if !f(item) { 47 | break 48 | } 49 | } 50 | } 51 | 52 | // Has looks for the existence of items passed. It returns false if nothing is 53 | // passed. For multiple items it returns true only if all of the items exist. 54 | func (s *set) Has(items ...Locale) bool { 55 | if len(items) == 0 { 56 | return false 57 | } 58 | s.l.RLock() 59 | defer s.l.RUnlock() 60 | has := true 61 | for _, item := range items { 62 | if _, has = s.m[item]; !has { 63 | break 64 | } 65 | } 66 | return has 67 | } 68 | -------------------------------------------------------------------------------- /set_test.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "strconv" 5 | "testing" 6 | ) 7 | 8 | func TestSet_Add(t *testing.T) { 9 | s := newSet() 10 | s.Add(LocaleEnUS) 11 | s.Add(LocaleEnGB) 12 | s.Add(LocaleEnGB) // duplicate 13 | if !s.Has(LocaleEnGB) { 14 | t.Error("Add: added item not available in the set") 15 | } 16 | if !s.Has(LocaleEnUS, LocaleEnGB) { 17 | t.Error("Add: added items are not availabile in the set.") 18 | } 19 | } 20 | 21 | func TestSet_RaceAdd(t *testing.T) { 22 | // Create two sets. Add concurrently items to each of them. Remove from the 23 | // other one. 24 | // "go test -race" should detect this if the library is not thread-safe. 25 | s := newSet() 26 | u := newSet() 27 | 28 | go func() { 29 | for i := 0; i < 1000; i++ { 30 | item := "item" + strconv.Itoa(i) 31 | go func(i int) { 32 | s.Add(Locale(item)) 33 | u.Add(Locale(item)) 34 | }(i) 35 | } 36 | }() 37 | 38 | for i := 0; i < 1000; i++ { 39 | item := "item" + strconv.Itoa(i) 40 | go func(i int) { 41 | s.Add(Locale(item)) 42 | u.Add(Locale(item)) 43 | }(i) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /utils_layout.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "strings" 5 | "unicode" 6 | "unicode/utf8" 7 | ) 8 | 9 | // dateStringLayoutItem represents one word or set of delimiters between words. 10 | // This is an abstraction level above date raw character string of date representation. 11 | // 12 | // Example: "1 February / 2013" -> 13 | // dateStringLayoutItem { item: "1", isWord: true } 14 | // dateStringLayoutItem { item: " ", isWord: false } 15 | // dateStringLayoutItem { item: "February", isWord: true } 16 | // dateStringLayoutItem { item: " / ", isWord: false } 17 | // dateStringLayoutItem { item: "2013", isWord: true } 18 | type dateStringLayoutItem struct { 19 | item string 20 | isWord bool // true if this is a sequence of letters/digits (as opposed to a sequence of non-letters like delimiters) 21 | isDigit bool // true if this is a sequence only containing digits 22 | } 23 | 24 | // extractLetterSequence extracts first word (sequence of letters ending with a non-letter) 25 | // starting with the specified index and wraps it to dateStringLayoutItem according to the type 26 | // of the word. 27 | func extractLetterSequence(originalStr string, index int) (it dateStringLayoutItem) { 28 | letters := &strings.Builder{} 29 | 30 | bytesToParse := []byte(originalStr[index:]) 31 | runeCount := utf8.RuneCount(bytesToParse) 32 | 33 | var isWord bool 34 | var isDigit bool 35 | 36 | letters.Grow(runeCount) 37 | for i := 0; i < runeCount; i++ { 38 | rne, runeSize := utf8.DecodeRune(bytesToParse) 39 | bytesToParse = bytesToParse[runeSize:] 40 | 41 | if i == 0 { 42 | isWord = unicode.IsLetter(rne) 43 | isDigit = unicode.IsDigit(rne) 44 | } else { 45 | if (isWord && (!unicode.IsLetter(rne) && !unicode.IsDigit(rne))) || 46 | (isDigit && !unicode.IsDigit(rne)) || 47 | (!isWord && unicode.IsLetter(rne)) || 48 | (!isDigit && unicode.IsDigit(rne)) { 49 | break 50 | } 51 | } 52 | 53 | letters.WriteRune(rne) 54 | } 55 | 56 | it.item = letters.String() 57 | it.isWord = isWord 58 | it.isDigit = isDigit 59 | return 60 | } 61 | 62 | // stringToLayoutItems transforms raw date string (like "2 Mar 2012") into 63 | // a set of dateStringLayoutItems, which are more convenient to work with 64 | // in other analysis modules. 65 | func stringToLayoutItems(dateStr string) (seqs []dateStringLayoutItem) { 66 | i := 0 67 | 68 | for i < len(dateStr) { 69 | seq := extractLetterSequence(dateStr, i) 70 | i += len(seq.item) 71 | seqs = append(seqs, seq) 72 | } 73 | 74 | return 75 | } 76 | 77 | func layoutToString(li []dateStringLayoutItem) string { 78 | // This function is expensive enough to be worth counting 79 | // bytes and allocating all in one go. 80 | numChars := 0 81 | for _, v := range li { 82 | numChars += len(v.item) 83 | } 84 | 85 | sb := &strings.Builder{} 86 | sb.Grow(numChars) 87 | for _, v := range li { 88 | sb.WriteString(v.item) 89 | } 90 | 91 | return sb.String() 92 | } 93 | -------------------------------------------------------------------------------- /utils_layout_test.go: -------------------------------------------------------------------------------- 1 | package monday 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | type DateLayoutTest struct { 9 | name string 10 | input string 11 | expected []dateStringLayoutItem 12 | } 13 | 14 | var dateLayoutTests = []DateLayoutTest{ 15 | {"ANSIC", "Thu Feb 4 21:00:57 2010", []dateStringLayoutItem{ 16 | {"Thu", true, false}, 17 | {" ", false, false}, 18 | {"Feb", true, false}, 19 | {" ", false, false}, 20 | {"4", false, true}, 21 | {" ", false, false}, 22 | {"21", false, true}, 23 | {":", false, false}, 24 | {"00", false, true}, 25 | {":", false, false}, 26 | {"57", false, true}, 27 | {" ", false, false}, 28 | {"2010", false, true}, 29 | }}, 30 | {"RFC1123Z", "Wed, 04 Feb 2013 21:00:57 -0800", []dateStringLayoutItem{ 31 | {"Wed", true, false}, 32 | {", ", false, false}, 33 | {"04", false, true}, 34 | {" ", false, false}, 35 | {"Feb", true, false}, 36 | {" ", false, false}, 37 | {"2013", false, true}, 38 | {" ", false, false}, 39 | {"21", false, true}, 40 | {":", false, false}, 41 | {"00", false, true}, 42 | {":", false, false}, 43 | {"57", false, true}, 44 | {" -", false, false}, 45 | {"0800", false, true}, 46 | }}, 47 | } 48 | 49 | func TestLayoutParser(t *testing.T) { 50 | for i, ts := range dateLayoutTests { 51 | items := stringToLayoutItems(ts.input) 52 | 53 | if !reflect.DeepEqual(items, ts.expected) { 54 | t.Errorf("Test #%d (%s) failed.\n Got: %#v\n Expected: %#v\n", i, ts.name, items, ts.expected) 55 | } 56 | } 57 | } 58 | --------------------------------------------------------------------------------