Add github.com/goodsign/monday for locale-specific date formatting

pull/206/head
Simon Roberts 3 years ago
parent 95c2973657
commit 24f1286067
No known key found for this signature in database
GPG Key ID: 0F30F99E6B771FD4

@ -10,6 +10,7 @@ require (
github.com/fatih/color v1.13.0
github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1
github.com/gliderlabs/ssh v0.3.3
github.com/goodsign/monday v1.0.0
github.com/maruel/panicparse v1.6.1
github.com/mattn/go-runewidth v0.0.13
github.com/miguelmota/go-coinmarketcap v0.1.8

@ -129,6 +129,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/goodsign/monday v1.0.0 h1:Yyk/s/WgudMbAJN6UWSU5xAs8jtNewfqtVblAlw0yoc=
github.com/goodsign/monday v1.0.0/go.mod h1:r4T4breXpoFwspQNM+u2sLxJb2zyTaxVGqUfTBjWOu8=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=

@ -0,0 +1,24 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
/monday.iml
/.idea/

@ -0,0 +1,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.

@ -0,0 +1,161 @@
Description
====
Monday is a minimalistic translator for month and day of week names in time.Date objects. Supports 20+ different locales.
Written in pure [Go](http://golang.org).
![Go](https://github.com/goodsign/monday/workflows/Go/badge.svg)
Installing
====
```
go get github.com/goodsign/monday
```
Usage
====
Format
---------------------
Given that you already use [time.Format](http://golang.org/pkg/time/#Time.Format) somewhere in your code,
to translate your output you should import monday and replace
```go
yourTime.Format(yourLayout)
```
with
```go
// Change LocaleEnUS to the locale you want to use for translation
monday.Format(yourTime, yourLayout, monday.LocaleEnUS)
```
Parse
---------------------
Given that you already use [time.ParseInLocation](http://golang.org/pkg/time/#ParseInLocation) somewhere in your code,
to parse input string in a different language you should import monday and replace
```go
time.ParseInLocation(yourLayout, yourString, yourLocation)
```
with
```go
// Change LocaleEnUS to the locale you want to use for translation
monday.ParseInLocation(yourLayout, yourString, yourLocation, monday.LocaleEnUS)
```
Predefined formats
---------------------
Monday declares some predefined formats: Full, Long, Medium, Short, DateTime formats for each locale. E.g. to get
short format for any locale you can use map:
```go
monday.ShortFormatsByLocale[locale]
```
Usage notes
-----------
**Monday** is not an alternative to standard **time** package. It is a temporary solution to use while
the internationalization features are not ready.
That's why **monday** doesn't create any additional parsing algorithms, layout identifiers. It is just
a wrapper for time.Format and time.ParseInLocation and uses all the same layout IDs, constants, etc.
So, the changes you need to temporarily switch to **monday** (while the internationalization features are being developed)
are minimal: you preserve your layout, your time object, your parsed date string formats and the only change is
the func call itself.
Locales
----
Supported locales are listed in **locale.go** file.
```
const (
LocaleEnUS = "en_US" // English (United States)
LocaleEnGB = "en_GB" // English (United Kingdom)
LocaleDaDK = "da_DK" // Danish (Denmark)
LocaleNlBE = "nl_BE" // Dutch (Belgium)
LocaleNlNL = "nl_NL" // Dutch (Netherlands)
LocaleFiFI = "fi_FI" // Finnish (Finland)
LocaleFrFR = "fr_FR" // French (France)
LocaleFrCA = "fr_CA" // French (Canada)
LocaleDeDE = "de_DE" // German (Germany)
LocaleHuHU = "hu_HU" // Hungarian (Hungary)
LocaleItIT = "it_IT" // Italian (Italy)
LocaleNnNO = "nn_NO" // Norwegian Nynorsk (Norway)
LocaleNbNO = "nb_NO" // Norwegian Bokmål (Norway)
LocalePlPL = "pl_PL" // Polish (Poland)
LocalePtPT = "pt_PT" // Portuguese (Portugal)
LocalePtBR = "pt_BR" // Portuguese (Brazil)
LocaleRoRO = "ro_RO" // Romanian (Romania)
LocaleRuRU = "ru_RU" // Russian (Russia)
LocaleEsES = "es_ES" // Spanish (Spain)
LocaleCaES = "ca_ES" // Catalan (Spain)
LocaleSvSE = "sv_SE" // Swedish (Sweden)
LocaleTrTR = "tr_TR" // Turkish (Turkey)
LocaleUkUA = "uk_UA" // Ukrainian (Ukraine)
LocaleBgBG = "bg_BG" // Bulgarian (Bulgaria)
LocaleZhCN = "zh_CN" // Chinese (Mainland)
LocaleZhTW = "zh_TW" // Chinese (Taiwan)
LocaleZhHK = "zh_HK" // Chinese (Hong Kong)
LocaleKoKR = "ko_KR" // Korean (Korea)
LocaleJaJP = "ja_JP" // Japanese (Japan)
LocaleElGR = "el_GR" // Greek (Greece)
LocaleIdID = "id_ID" // Indonesian (Indonesia)
LocaleFrGP = "fr_GP" // French (Guadeloupe)
LocaleFrLU = "fr_LU" // French (Luxembourg)
LocaleFrMQ = "fr_MQ" // French (Martinique)
LocaleFrGF = "fr_GF" // French (French Guiana)
LocaleFrGF = "fr_RE" // French (Reunion)
LocaleCsCZ = "cs_CZ" // Czech (Czech Republic)
LocaleSlSI = "sl_SI" // Slovenian (Slovenia)
)
```
LocaleDetector
====
```go
var timeLocaleDetector *monday.LocaleDetector = monday.NewLocaleDetector()
dateTime, err := timeLocaleDetector.Parse(layout,datestr)
```
parses datetime with **unknown** locale (for now - layout must be defined, as for time.Parse())
useful for text parsing tools/crawlers (f.e.: rss-feeds crawler)
TODO:
* make LocaleDetector insensitive to whitespaces count
Thread-safety
====
**Monday** initializes all its data once in the **init** func and then uses only
func calls and local vars. Thus, it's thread-safe and doesn't need any mutexes to be
used with.
Monday Licence
==========
The **Monday** library is released under the [BSD Licence](http://opensource.org/licenses/bsd-license.php)
[LICENCE file](https://github.com/goodsign/monday/blob/master/LICENCE)
Thanks
==========
* [Martin Angers](https://github.com/PuerkitoBio)
* Andrey Mirtchovski
* [mikespook](https://github.com/mikespook)
* [Luis Azevedo](https://github.com/braceta)
* [imikod](https://github.com/imikod)
* [Renato Serra](https://github.com/RenatoSerra22)
* [Zachary Stewart](https://github.com/ztstewart)

@ -0,0 +1,345 @@
package monday
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"text/scanner"
"time"
)
var (
wordsRx = regexp.MustCompile("(\\p{L}+)")
debugLayoutDef = false
)
// An InvalidTypeError indicates that data was parsed incorrectly as a result
// of a type mismatch.
type InvalidTypeError struct {
error
}
// An InvalidLengthError is returned when an item's length was longer or
// shorter than expected for a particular token.
type InvalidLengthError struct {
error
}
// NewInvalidTypeError instantiates an InvalidTypeError.
func NewInvalidTypeError() InvalidTypeError {
return InvalidTypeError{error: errors.New("invalid type for token")}
}
// NewInvalidLengthError instantiates an InvalidLengthError.
func NewInvalidLengthError() InvalidLengthError {
return InvalidLengthError{error: errors.New("invalid length for token")}
}
type layoutSpanI interface {
scanInt(s *scanner.Scanner) (int, error)
scanString(s *scanner.Scanner) (string, error)
isString() bool
isDelimiter() bool
}
type lengthLimitSpan struct {
minLength int
maxLength int
}
func (lls lengthLimitSpan) scanInt(s *scanner.Scanner) (int, error) {
return -1, NewInvalidTypeError()
}
func (lls lengthLimitSpan) scanString(s *scanner.Scanner) (string, error) {
return "", NewInvalidTypeError()
}
func (lls lengthLimitSpan) isString() bool { return false }
func (lls lengthLimitSpan) isDelimiter() bool { return false }
func initLengthLimitSpan(min, max int) lengthLimitSpan {
return lengthLimitSpan{
minLength: min,
maxLength: max,
}
}
type limitedStringSpan struct {
lengthLimitSpan
}
func initLimitedStringSpan(minLength, maxLength int) limitedStringSpan {
return limitedStringSpan{lengthLimitSpan: initLengthLimitSpan(minLength, maxLength)}
}
func (lss limitedStringSpan) scanString(s *scanner.Scanner) (string, error) {
tok := s.Scan()
if tok != scanner.EOF && tok == -2 {
return s.TokenText(), nil
}
return "", NewInvalidTypeError()
}
func (lss limitedStringSpan) isString() bool { return true }
func (lss limitedStringSpan) String() string {
return fmt.Sprintf("[limitedStringSpan:%v]", lss.lengthLimitSpan)
}
type rangeIntSpan struct {
lengthLimitSpan
min int
max int
}
func initRangeIntSpan(minValue, maxValue, minLength, maxLength int) rangeIntSpan {
return rangeIntSpan{
lengthLimitSpan: initLengthLimitSpan(minLength, maxLength),
min: minValue,
max: maxValue,
}
}
func (rs rangeIntSpan) scanInt(s *scanner.Scanner) (int, error) {
var tok = s.Scan()
var negative bool
if tok == 45 {
negative = true
if debugLayoutDef {
fmt.Printf("scan negative:'%s'\n", s.TokenText())
}
tok = s.Scan()
} else if tok == 43 { // positive
tok = s.Scan()
}
if tok == -3 {
str := s.TokenText()
i, err := strconv.Atoi(str)
if err != nil {
return 0, err
}
if negative {
i = i * -1
}
return i, nil
}
if debugLayoutDef {
fmt.Printf("invalid tok: %v '%s'\n", tok, s.TokenText())
}
return 0, NewInvalidTypeError()
}
func (rs rangeIntSpan) String() string {
return fmt.Sprintf("[rangeIntSpan:%v]", rs.lengthLimitSpan)
}
type delimiterSpan struct {
lengthLimitSpan
character string
}
func initDelimiterSpan(character string, minLength, maxLength int) delimiterSpan {
return delimiterSpan{
lengthLimitSpan: initLengthLimitSpan(minLength, maxLength),
character: character,
}
}
func (ds delimiterSpan) scanString(s *scanner.Scanner) (string, error) {
tok := s.Scan()
if tok != scanner.EOF && tok != -2 && tok != 45 && tok != -3 {
return s.TokenText(), nil
}
if debugLayoutDef {
fmt.Printf("expected tok:=!(-2,-3,45), received:%d ('%s')\n", tok, s.TokenText())
}
return "", NewInvalidTypeError()
}
func (ds delimiterSpan) isString() bool { return false }
func (ds delimiterSpan) isDelimiter() bool { return true }
func (ds delimiterSpan) String() string {
return fmt.Sprintf("[delimiterSpan '%s':%v]", ds.character, ds.lengthLimitSpan)
}
type layoutDef struct {
spans []layoutSpanI
errorPosition int
}
func (ld *layoutDef) validate(value string) bool {
s := &scanner.Scanner{}
s.Init(strings.NewReader(value))
s.Whitespace = 0
for _, span := range ld.spans {
if span.isString() || span.isDelimiter() {
if _, err := span.scanString(s); err != nil {
ld.errorPosition = s.Pos().Offset
if debugLayoutDef {
fmt.Printf("error at pos: %d: %s (span=%+v) - expected string or delimiter\n", s.Pos().Offset, err.Error(), span)
}
return false
}
} else if _, err := span.scanInt(s); err != nil {
if debugLayoutDef {
fmt.Printf("error at pos: %d: %s (span=%+v) - expected integer\n", s.Pos().Offset, err.Error(), span)
}
ld.errorPosition = s.Pos().Offset
return false
}
}
ld.errorPosition = s.Pos().Offset
return s.Pos().Offset == len(value)
}
// A LocaleDetector parses time.Time values by using various heuristics and
// techniques to determine which locale should be used to parse the
// time.Time value. As not all possible locales and formats are supported,
// this process can be somewhat lossy and inaccurate.
type LocaleDetector struct {
localeMap map[string]*set
lastLocale Locale
layoutsMap map[string]layoutDef
lastErrorPosition int
}
func (ld *LocaleDetector) prepareLayout(layout string) layoutDef {
s := scanner.Scanner{}
s.Init(strings.NewReader(layout))
s.Whitespace = 0
result := make([]layoutSpanI, 0)
var tok rune
// var pos int = 0
var span layoutSpanI
var sign bool
// var neg bool = false
for tok != scanner.EOF {
tok = s.Scan()
switch tok {
case -2: // text
span = initLimitedStringSpan(1, -1)
case -3: // digit
span = initRangeIntSpan(-1, -1, 1, -1)
if sign {
sign = false
}
case 45: // negative sign
sign = true
// neg = s.TokenText() == "-"
continue
case 43: // positive sign
sign = true
continue
case scanner.EOF:
continue
default: // fixed character
span = initDelimiterSpan(s.TokenText(), 1, 1)
}
result = append(result, span)
// length := s.Pos().Offset - pos
// pos = s.Pos().Offset
// fmt.Printf("tok'%s' [%d %d] length=%d\n", s.TokenText(), pos, s.Pos().Offset, length)
}
if debugLayoutDef {
fmt.Printf("layout:'%s'\n", layout)
fmt.Printf("layout:%v\n", result)
}
ret := layoutDef{spans: result}
ld.layoutsMap[layout] = ret
return ret
}
func (ld *LocaleDetector) validateValue(layout string, value string) bool {
l, ok := ld.layoutsMap[layout]
if !ok {
l = ld.prepareLayout(layout)
}
result := l.validate(value)
ld.lastErrorPosition = l.errorPosition
return result
}
func (ld *LocaleDetector) errorPosition() int { return ld.lastErrorPosition }
func (ld *LocaleDetector) addWords(words []string, v Locale) {
for _, w := range words {
l := strings.ToLower(w)
if _, ok := ld.localeMap[w]; !ok {
ld.localeMap[w] = newSet(v)
if l != w {
ld.localeMap[l] = newSet(v)
}
} else {
ld.localeMap[w].Add(v)
if l != w {
ld.localeMap[l].Add(v)
}
}
}
}
// NewLocaleDetector instances a LocaleDetector instance.
func NewLocaleDetector() *LocaleDetector {
ld := &LocaleDetector{localeMap: make(map[string]*set), lastLocale: LocaleEnGB, layoutsMap: make(map[string]layoutDef)}
for _, v := range ListLocales() {
days := GetShortDays(v)
ld.addWords(days, v)
days = GetLongDays(v)
ld.addWords(days, v)
months := GetShortMonths(v)
ld.addWords(months, v)
months = GetLongMonths(v)
ld.addWords(months, v)
}
return ld
}
// Parse will attempt to parse a time.Time struct from a layout (format) and a
// value to parse from.
//
// If no locale can be determined, this method will return an error and an
// empty time object.
func (ld *LocaleDetector) Parse(layout, value string) (time.Time, error) {
if ld.validateValue(layout, value) {
ld.lastLocale = ld.detectLocale(value)
return ParseInLocation(layout, value, time.UTC, ld.lastLocale)
}
return time.Time{}, &time.ParseError{
Value: value,
Layout: layout,
Message: fmt.Sprintf("'%s' not matches to '%s' last error position = %d\n", value, layout, ld.lastErrorPosition),
}
}
func (ld *LocaleDetector) detectLocale(value string) Locale {
localesMap := make(map[Locale]int)
for _, v := range wordsRx.FindAllStringSubmatchIndex(value, -1) {
word := strings.ToLower(value[v[0]:v[1]])
if localesSet, ok := ld.localeMap[word]; ok {
localesSet.Each(func(loc Locale) bool {
if _, ok := localesMap[loc]; !ok {
localesMap[loc] = 1
} else {
localesMap[loc]++
}
return true
})
}
}
var result Locale = LocaleEnUS
frequency := 0
for key, counter := range localesMap {
if counter > frequency {
frequency = counter
result = key
}
}
return result
}

@ -0,0 +1,412 @@
package monday
// Default date formats by country.
// Mostly taken from http://en.wikipedia.org/wiki/Date_format_by_country
const (
DefaultFormatEnUS = "01/02/06"
DefaultFormatEnUSFull = "Monday, January 2, 2006" // English (United States)
DefaultFormatEnUSLong = "January 2, 2006"
DefaultFormatEnUSMedium = "Jan 02, 2006"
DefaultFormatEnUSShort = "1/2/06"
DefaultFormatEnUSDateTime = "1/2/06 3:04 PM"
DefaultFormatEnGBFull = "Monday, 2 January 2006" // English (United Kingdom)
DefaultFormatEnGBLong = "2 January 2006"
DefaultFormatEnGBMedium = "02 Jan 2006"
DefaultFormatEnGBShort = "02/01/2006"
DefaultFormatEnGBDateTime = "02/01/2006 15:04"
DefaultFormatDaDKFull = "Monday den 2. January 2006" // Danish (Denmark)
DefaultFormatDaDKLong = "2. Jan 2006"
DefaultFormatDaDKMedium = "02/01/2006"
DefaultFormatDaDKShort = "02/01/06"
DefaultFormatDaDKDateTime = "02/01/2006 15.04"
DefaultFormatNlBEFull = "Monday 2 January 2006" // Dutch (Belgium)
DefaultFormatNlBELong = "2 January 2006"
DefaultFormatNlBEMedium = "02-Jan-2006"
DefaultFormatNlBEShort = "2/01/06"
DefaultFormatNlBEDateTime = "2/01/06 15:04"
DefaultFormatNlNLFull = "Monday 2 January 2006" // Dutch (Netherlands)
DefaultFormatNlNLLong = "2 January 2006"
DefaultFormatNlNLMedium = "02 Jan 2006"
DefaultFormatNlNLShort = "02-01-06"
DefaultFormatNlNLDateTime = "02-01-06 15:04"
DefaultFormatFiFIFull = "Monday 2. January 2006" // Finnish (Finland)
DefaultFormatFiFILong = "2. January 2006"
DefaultFormatFiFIMedium = "02.1.2006"
DefaultFormatFiFIShort = "02.1.2006"
DefaultFormatFiFIDateTime = "02.1.2006 15.04"
DefaultFormatFrFRFull = "Monday 2 January 2006" // French (France)
DefaultFormatFrFRLong = "2 January 2006"
DefaultFormatFrFRMedium = "02 Jan 2006"
DefaultFormatFrFRShort = "02/01/2006"
DefaultFormatFrFRDateTime = "02/01/2006 15:04"
DefaultFormatFrCAFull = "Monday 2 January 2006" // French (Canada)
DefaultFormatFrCALong = "2 January 2006"
DefaultFormatFrCAMedium = "2006-01-02"
DefaultFormatFrCAShort = "06-01-02"
DefaultFormatFrCADateTime = "06-01-02 15:04"
DefaultFormatFrGPFull = "Monday 2 January 2006" // French (Canada)
DefaultFormatFrGPLong = "2 January 2006"
DefaultFormatFrGPMedium = "2006-01-02"
DefaultFormatFrGPShort = "06-01-02"
DefaultFormatFrGPDateTime = "06-01-02 15:04"
DefaultFormatFrLUFull = "Monday 2 January 2006" // French (Luxembourg)
DefaultFormatFrLULong = "2 January 2006"
DefaultFormatFrLUMedium = "2006-01-02"
DefaultFormatFrLUShort = "06-01-02"
DefaultFormatFrLUDateTime = "06-01-02 15:04"
DefaultFormatFrMQFull = "Monday 2 January 2006" // French (Martinique)
DefaultFormatFrMQLong = "2 January 2006"
DefaultFormatFrMQMedium = "2006-01-02"
DefaultFormatFrMQShort = "06-01-02"
DefaultFormatFrMQDateTime = "06-01-02 15:04"
DefaultFormatFrGFFull = "Monday 2 January 2006" // French (French Guiana)
DefaultFormatFrGFLong = "2 January 2006"
DefaultFormatFrGFMedium = "2006-01-02"
DefaultFormatFrGFShort = "06-01-02"
DefaultFormatFrGFDateTime = "06-01-02 15:04"
DefaultFormatFrREFull = "Monday 2 January 2006" // French (Reunion)
DefaultFormatFrRELong = "2 January 2006"
DefaultFormatFrREMedium = "2006-01-02"
DefaultFormatFrREShort = "06-01-02"
DefaultFormatFrREDateTime = "06-01-02 15:04"
DefaultFormatDeDEFull = "Monday, 2. January 2006" // German (Germany)
DefaultFormatDeDELong = "2. January 2006"
DefaultFormatDeDEMedium = "02.01.2006"
DefaultFormatDeDEShort = "02.01.06"
DefaultFormatDeDEDateTime = "02.01.06 15:04"
DefaultFormatHuHUFull = "2006. January 2., Monday" // Hungarian (Hungary)
DefaultFormatHuHULong = "2006. January 2."
DefaultFormatHuHUMedium = "2006.01.02."
DefaultFormatHuHUShort = "2006.01.02."
DefaultFormatHuHUDateTime = "2006.01.02. 15:04"
DefaultFormatItITFull = "Monday 2 January 2006" // Italian (Italy)
DefaultFormatItITLong = "2 January 2006"
DefaultFormatItITMedium = "02/Jan/2006"
DefaultFormatItITShort = "02/01/06"
DefaultFormatItITDateTime = "02/01/06 15:04"
DefaultFormatNnNOFull = "Monday 2. January 2006" // Norwegian Nynorsk (Norway)
DefaultFormatNnNOLong = "2. January 2006"
DefaultFormatNnNOMedium = "02. Jan 2006"
DefaultFormatNnNOShort = "02.01.06"
DefaultFormatNnNODateTime = "02.01.06 15:04"
DefaultFormatNbNOFull = "Monday 2. January 2006" // Norwegian Bokmål (Norway)
DefaultFormatNbNOLong = "2. January 2006"
DefaultFormatNbNOMedium = "02. Jan 2006"
DefaultFormatNbNOShort = "02.01.06"
DefaultFormatNbNODateTime = "15:04 02.01.06"
DefaultFormatPtPTFull = "Monday, 2 de January de 2006" // Portuguese (Portugal)
DefaultFormatPtPTLong = "2 de January de 2006"
DefaultFormatPtPTMedium = "02/01/2006"
DefaultFormatPtPTShort = "02/01/06"
DefaultFormatPtPTDateTime = "02/01/06, 15:04"
DefaultFormatPtBRFull = "Monday, 2 de January de 2006" // Portuguese (Brazil)
DefaultFormatPtBRLong = "02 de January de 2006"
DefaultFormatPtBRMedium = "02/01/2006"
DefaultFormatPtBRShort = "02/01/06"
DefaultFormatPtBRDateTime = "02/01/06, 15:04"
DefaultFormatRoROFull = "Monday, 02 January 2006" // Romanian (Romania)
DefaultFormatRoROLong = "02 January 2006"
DefaultFormatRoROMedium = "02.01.2006"
DefaultFormatRoROShort = "02.01.2006"
DefaultFormatRoRODateTime = "02.01.06, 15:04"
DefaultFormatRuRUFull = "Monday, 2 January 2006 г." // Russian (Russia)
DefaultFormatRuRULong = "2 January 2006 г."
DefaultFormatRuRUMedium = "02 Jan 2006 г."
DefaultFormatRuRUShort = "02.01.06"
DefaultFormatRuRUDateTime = "02.01.06, 15:04"
DefaultFormatEsESFull = "Monday, 2 de January de 2006" // Spanish (Spain)
DefaultFormatEsESLong = "2 de January de 2006"
DefaultFormatEsESMedium = "02/01/2006"
DefaultFormatEsESShort = "02/01/06"
DefaultFormatEsESDateTime = "02/01/06 15:04"
DefaultFormatCaESFull = "Monday, 2 de January de 2006" // Spanish (Spain)
DefaultFormatCaESLong = "2 de January de 2006"
DefaultFormatCaESMedium = "02/01/2006"
DefaultFormatCaESShort = "02/01/06"
DefaultFormatCaESDateTime = "02/01/06 15:04"
DefaultFormatSvSEFull = "Mondayen den 2:e January 2006" // Swedish (Sweden)
DefaultFormatSvSELong = "2 January 2006"
DefaultFormatSvSEMedium = "2 Jan 2006"
DefaultFormatSvSEShort = "2006-01-02"
DefaultFormatSvSEDateTime = "2006-01-02 15:04"
DefaultFormatTrTRFull = "2 January 2006 Monday" // Turkish (Turkey)
DefaultFormatTrTRLong = "2 January 2006"
DefaultFormatTrTRMedium = "2 Jan 2006"
DefaultFormatTrTRShort = "2.01.2006"
DefaultFormatTrTRDateTime = "2.01.2006 15:04"
DefaultFormatUkUAFull = "Monday, 2 January 2006 р." // Ukrainian (Ukraine)
DefaultFormatUkUALong = "2 January 2006 р."
DefaultFormatUkUAMedium = "02 Jan 2006 р."
DefaultFormatUkUAShort = "02.01.06"
DefaultFormatUkUADateTime = "02.01.06, 15:04"
DefaultFormatBgBGFull = "Monday, 2 January 2006" // Bulgarian (Bulgaria)
DefaultFormatBgBGLong = "2 January 2006"
DefaultFormatBgBGMedium = "2 Jan 2006"
DefaultFormatBgBGShort = "2.01.2006"
DefaultFormatBgBGDateTime = "2.01.2006 15:04"
DefaultFormatZhCNFull = "2006年1月2日 Monday" // Chinese (Mainland)
DefaultFormatZhCNLong = "2006年1月2日"
DefaultFormatZhCNMedium = "2006-01-02"
DefaultFormatZhCNShort = "2006/1/2"
DefaultFormatZhCNDateTime = "2006-01-02 15:04"
DefaultFormatZhTWFull = "2006年1月2日 Monday" // Chinese (Taiwan)
DefaultFormatZhTWLong = "2006年1月2日"
DefaultFormatZhTWMedium = "2006-01-02"
DefaultFormatZhTWShort = "2006/1/2"
DefaultFormatZhTWDateTime = "2006-01-02 15:04"
DefaultFormatZhHKFull = "2006年1月2日 Monday" // Chinese (Hong Kong)
DefaultFormatZhHKLong = "2006年1月2日"
DefaultFormatZhHKMedium = "2006-01-02"
DefaultFormatZhHKShort = "2006/1/2"
DefaultFormatZhHKDateTime = "2006-01-02 15:04"
DefaultFormatKoKRFull = "2006년1월2일 월요일" // Korean (Korea)
DefaultFormatKoKRLong = "2006년1월2일"
DefaultFormatKoKRMedium = "2006-01-02"
DefaultFormatKoKRShort = "2006/1/2"
DefaultFormatKoKRDateTime = "2006-01-02 15:04"
DefaultFormatJaJPFull = "2006年1月2日 Monday" // Japanese (Japan)
DefaultFormatJaJPLong = "2006年1月2日"
DefaultFormatJaJPMedium = "2006/01/02"
DefaultFormatJaJPShort = "2006/1/2"
DefaultFormatJaJPDateTime = "2006/01/02 15:04"
DefaultFormatElGRFull = "Monday, 2 January 2006" // Greek (Greece)
DefaultFormatElGRLong = "2 January 2006"
DefaultFormatElGRMedium = "2 Jan 2006"
DefaultFormatElGRShort = "02/01/06"
DefaultFormatElGRDateTime = "02/01/06 15:04"
DefaultFormatCsCZFull = "Monday, 2. January 2006" // Czech (Czech Republic)
DefaultFormatCsCZLong = "2. January 2006"
DefaultFormatCsCZMedium = "02 Jan 2006"
DefaultFormatCsCZShort = "02/01/2006"
DefaultFormatCsCZDateTime = "02/01/2006 15:04"
)
// FullFormatsByLocale maps locales to the'full' date formats for all
// supported locales.
var FullFormatsByLocale = map[Locale]string{
LocaleEnUS: DefaultFormatEnUSFull,
LocaleEnGB: DefaultFormatEnGBFull,
LocaleDaDK: DefaultFormatDaDKFull,
LocaleNlBE: DefaultFormatNlBEFull,
LocaleNlNL: DefaultFormatNlNLFull,
LocaleFiFI: DefaultFormatFiFIFull,
LocaleFrFR: DefaultFormatFrFRFull,
LocaleFrCA: DefaultFormatFrCAFull,
LocaleFrGP: DefaultFormatFrGPFull,
LocaleFrLU: DefaultFormatFrLUFull,
LocaleFrMQ: DefaultFormatFrMQFull,
LocaleFrGF: DefaultFormatFrGFFull,
LocaleFrRE: DefaultFormatFrREFull,
LocaleDeDE: DefaultFormatDeDEFull,
LocaleHuHU: DefaultFormatHuHUFull,
LocaleItIT: DefaultFormatItITFull,
LocaleNnNO: DefaultFormatNnNOFull,
LocaleNbNO: DefaultFormatNbNOFull,
LocalePtPT: DefaultFormatPtPTFull,
LocalePtBR: DefaultFormatPtBRFull,
LocaleRoRO: DefaultFormatRoROFull,
LocaleRuRU: DefaultFormatRuRUFull,
LocaleEsES: DefaultFormatEsESFull,
LocaleCaES: DefaultFormatCaESFull,
LocaleSvSE: DefaultFormatSvSEFull,
LocaleTrTR: DefaultFormatTrTRFull,
LocaleBgBG: DefaultFormatBgBGFull,
LocaleZhCN: DefaultFormatZhCNFull,
LocaleZhTW: DefaultFormatZhTWFull,
LocaleZhHK: DefaultFormatZhHKFull,
LocaleKoKR: DefaultFormatKoKRFull,
LocaleJaJP: DefaultFormatJaJPFull,
LocaleElGR: DefaultFormatElGRFull,
LocaleCsCZ: DefaultFormatCsCZFull,
}
// LongFormatsByLocale maps locales to the 'long' date formats for all
// supported locales.
var LongFormatsByLocale = map[Locale]string{
LocaleEnUS: DefaultFormatEnUSLong,
LocaleEnGB: DefaultFormatEnGBLong,
LocaleDaDK: DefaultFormatDaDKLong,
LocaleNlBE: DefaultFormatNlBELong,
LocaleNlNL: DefaultFormatNlNLLong,
LocaleFiFI: DefaultFormatFiFILong,
LocaleFrFR: DefaultFormatFrFRLong,
LocaleFrCA: DefaultFormatFrCALong,
LocaleFrGP: DefaultFormatFrGPLong,
LocaleFrLU: DefaultFormatFrLULong,
LocaleFrMQ: DefaultFormatFrMQLong,
LocaleFrRE: DefaultFormatFrRELong,
LocaleFrGF: DefaultFormatFrGFLong,
LocaleDeDE: DefaultFormatDeDELong,
LocaleHuHU: DefaultFormatHuHULong,
LocaleItIT: DefaultFormatItITLong,
LocaleNnNO: DefaultFormatNnNOLong,
LocaleNbNO: DefaultFormatNbNOLong,
LocalePtPT: DefaultFormatPtPTLong,
LocalePtBR: DefaultFormatPtBRLong,
LocaleRoRO: DefaultFormatRoROLong,
LocaleRuRU: DefaultFormatRuRULong,
LocaleEsES: DefaultFormatEsESLong,
LocaleCaES: DefaultFormatCaESLong,
LocaleSvSE: DefaultFormatSvSELong,
LocaleTrTR: DefaultFormatTrTRLong,
LocaleBgBG: DefaultFormatBgBGLong,
LocaleZhCN: DefaultFormatZhCNLong,
LocaleZhTW: DefaultFormatZhTWLong,
LocaleZhHK: DefaultFormatZhHKLong,
LocaleKoKR: DefaultFormatKoKRLong,
LocaleJaJP: DefaultFormatJaJPLong,
LocaleElGR: DefaultFormatElGRLong,
LocaleCsCZ: DefaultFormatCsCZLong,
}
// MediumFormatsByLocale maps locales to the 'medium' date formats for all
// supported locales.
var MediumFormatsByLocale = map[Locale]string{
LocaleEnUS: DefaultFormatEnUSMedium,
LocaleEnGB: DefaultFormatEnGBMedium,
LocaleDaDK: DefaultFormatDaDKMedium,
LocaleNlBE: DefaultFormatNlBEMedium,
LocaleNlNL: DefaultFormatNlNLMedium,
LocaleFiFI: DefaultFormatFiFIMedium,
LocaleFrFR: DefaultFormatFrFRMedium,
LocaleFrGP: DefaultFormatFrGPMedium,
LocaleFrCA: DefaultFormatFrCAMedium,
LocaleFrLU: DefaultFormatFrLUMedium,
LocaleFrMQ: DefaultFormatFrMQMedium,
LocaleFrGF: DefaultFormatFrGFMedium,
LocaleFrRE: DefaultFormatFrREMedium,
LocaleDeDE: DefaultFormatDeDEMedium,
LocaleHuHU: DefaultFormatHuHUMedium,
LocaleItIT: DefaultFormatItITMedium,
LocaleNnNO: DefaultFormatNnNOMedium,
LocaleNbNO: DefaultFormatNbNOMedium,
LocalePtPT: DefaultFormatPtPTMedium,
LocalePtBR: DefaultFormatPtBRMedium,
LocaleRoRO: DefaultFormatRoROMedium,
LocaleRuRU: DefaultFormatRuRUMedium,
LocaleEsES: DefaultFormatEsESMedium,
LocaleCaES: DefaultFormatCaESMedium,
LocaleSvSE: DefaultFormatSvSEMedium,
LocaleTrTR: DefaultFormatTrTRMedium,
LocaleBgBG: DefaultFormatBgBGMedium,
LocaleZhCN: DefaultFormatZhCNMedium,
LocaleZhTW: DefaultFormatZhTWMedium,
LocaleZhHK: DefaultFormatZhHKMedium,
LocaleKoKR: DefaultFormatKoKRMedium,
LocaleJaJP: DefaultFormatJaJPMedium,
LocaleElGR: DefaultFormatElGRMedium,
LocaleCsCZ: DefaultFormatCsCZMedium,
}
// ShortFormatsByLocale maps locales to the 'short' date formats for all
// supported locales.
var ShortFormatsByLocale = map[Locale]string{
LocaleEnUS: DefaultFormatEnUSShort,
LocaleEnGB: DefaultFormatEnGBShort,
LocaleDaDK: DefaultFormatDaDKShort,
LocaleNlBE: DefaultFormatNlBEShort,
LocaleNlNL: DefaultFormatNlNLShort,
LocaleFiFI: DefaultFormatFiFIShort,
LocaleFrFR: DefaultFormatFrFRShort,
LocaleFrCA: DefaultFormatFrCAShort,
LocaleFrLU: DefaultFormatFrLUShort,
LocaleFrMQ: DefaultFormatFrMQShort,
LocaleFrGF: DefaultFormatFrGFShort,
LocaleFrGP: DefaultFormatFrGPShort,
LocaleFrRE: DefaultFormatFrREShort,
LocaleDeDE: DefaultFormatDeDEShort,
LocaleHuHU: DefaultFormatHuHUShort,
LocaleItIT: DefaultFormatItITShort,
LocaleNnNO: DefaultFormatNnNOShort,
LocaleNbNO: DefaultFormatNbNOShort,
LocalePtPT: DefaultFormatPtPTShort,
LocalePtBR: DefaultFormatPtBRShort,
LocaleRoRO: DefaultFormatRoROShort,
LocaleRuRU: DefaultFormatRuRUShort,
LocaleEsES: DefaultFormatEsESShort,
LocaleCaES: DefaultFormatCaESShort,
LocaleSvSE: DefaultFormatSvSEShort,
LocaleTrTR: DefaultFormatTrTRShort,
LocaleBgBG: DefaultFormatBgBGShort,
LocaleZhCN: DefaultFormatZhCNShort,
LocaleZhTW: DefaultFormatZhTWShort,
LocaleZhHK: DefaultFormatZhHKShort,
LocaleKoKR: DefaultFormatKoKRShort,
LocaleJaJP: DefaultFormatJaJPShort,
LocaleElGR: DefaultFormatElGRShort,
LocaleCsCZ: DefaultFormatCsCZShort,
}
// DateTimeFormatsByLocale maps locales to the 'DateTime' date formats for
// all supported locales.
var DateTimeFormatsByLocale = map[Locale]string{
LocaleEnUS: DefaultFormatEnUSDateTime,
LocaleEnGB: DefaultFormatEnGBDateTime,
LocaleDaDK: DefaultFormatDaDKDateTime,
LocaleNlBE: DefaultFormatNlBEDateTime,
LocaleNlNL: DefaultFormatNlNLDateTime,
LocaleFiFI: DefaultFormatFiFIDateTime,
LocaleFrFR: DefaultFormatFrFRDateTime,
LocaleFrCA: DefaultFormatFrCADateTime,
LocaleFrGP: DefaultFormatFrGPDateTime,
LocaleFrLU: DefaultFormatFrLUDateTime,
LocaleFrMQ: DefaultFormatFrMQDateTime,
LocaleFrGF: DefaultFormatFrGFDateTime,
LocaleFrRE: DefaultFormatFrREDateTime,
LocaleDeDE: DefaultFormatDeDEDateTime,
LocaleHuHU: DefaultFormatHuHUDateTime,
LocaleItIT: DefaultFormatItITDateTime,
LocaleNnNO: DefaultFormatNnNODateTime,
LocaleNbNO: DefaultFormatNbNODateTime,
LocalePtPT: DefaultFormatPtPTDateTime,
LocalePtBR: DefaultFormatPtBRDateTime,
LocaleRoRO: DefaultFormatRoRODateTime,
LocaleRuRU: DefaultFormatRuRUDateTime,
LocaleEsES: DefaultFormatEsESDateTime,
LocaleCaES: DefaultFormatCaESDateTime,
LocaleSvSE: DefaultFormatSvSEDateTime,
LocaleTrTR: DefaultFormatTrTRDateTime,
LocaleBgBG: DefaultFormatBgBGDateTime,
LocaleZhCN: DefaultFormatZhCNDateTime,
LocaleZhTW: DefaultFormatZhTWDateTime,
LocaleZhHK: DefaultFormatZhHKDateTime,
LocaleKoKR: DefaultFormatKoKRDateTime,
LocaleJaJP: DefaultFormatJaJPDateTime,
LocaleElGR: DefaultFormatElGRDateTime,
LocaleCsCZ: DefaultFormatCsCZDateTime,
}

@ -0,0 +1,71 @@
package monday
var dayLongOrderMondayFirst = []string{
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
}
var dayLongOrderSundayFirst = []string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
}
var dayShortOrderMondayFirst = []string{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
}
var dayShortOrderSundayFirst = []string{
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
}
var monthLongOrder = []string{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
}
var monthShortOrder = []string{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
}

@ -0,0 +1,38 @@
/*
Package monday is a minimalistic translator for month and day of week names in time.Date objects
Introduction
Monday is not an alternative to standard time package. It is a temporary solution to use while
the internationalization features are not ready.
That's why monday doesn't create any additional parsing algorithms, layout identifiers. It is just
a wrapper for time.Format and time.ParseInLocation and uses all the same layout IDs, constants, etc.
Usage
Format usage:
t := time.Date(2013, 4, 12, 0, 0, 0, 0, time.UTC)
layout := "2 January 2006 15:04:05 MST"
translationEnUS := monday.Format(t, layout, monday.LocaleEnUS) // Instead of t.Format(layout)
translationRuRU := monday.Format(t, layout, monday.LocaleRuRU) // Instead of t.Format(layout)
...
Parse usage:
layout := "2 January 2006 15:04:05 MST"
// Instead of time.ParseInLocation(layout, "12 April 2013 00:00:00 MST", time.UTC)
parsed := monday.ParseInLocation(layout, "12 April 2013 00:00:00 MST", time.UTC, monday.LocaleEnUS))
parsed2 = monday.ParseInLocation(layout, "12 апреля 2013 00:00:00 MST", time.UTC, monday.LocaleRuRU))
...
Thread safety
Monday initializes all its data once in the init func and then uses only
func calls and local vars. Thus, it's thread-safe and doesn't need any mutexes to be
used with.
*/
package monday

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "bg_BG" locale: Bulgarian (Bulgaria)
// ============================================================
var longDayNamesBgBG = map[string]string{
"Sunday": "Неделя",
"Monday": "Понеделник",
"Tuesday": "Вторник",
"Wednesday": "Сряда",
"Thursday": "Четвъртък",
"Friday": "Петък",
"Saturday": "Събота",
}
var shortDayNamesBgBG = map[string]string{
"Sun": "Нд",
"Mon": "Пн",
"Tue": "Вт",
"Wed": "Ср",
"Thu": "Чt",
"Fri": "Пт",
"Sat": "Сб",
}
var longMonthNamesBgBG = map[string]string{
"January": "Януари",
"February": "Февруари",
"March": "Март",
"April": "Април",
"May": "Май",
"June": "Юни",
"July": "Юли",
"August": "Август",
"September": "Септември",
"October": "Октомври",
"November": "Ноември",
"December": "Декември",
}
var shortMonthNamesBgBG = map[string]string{
"Jan": "Яну",
"Feb": "Фев",
"Mar": "Мар",
"Apr": "Апр",
"May": "Май",
"Jun": "Юни",
"Jul": "Юли",
"Aug": "Авг",
"Sep": "Сеп",
"Oct": "Окт",
"Nov": "Ное",
"Dec": "Дек",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "ca_ES" locale: Catalan (Spain)
// ============================================================
var longDayNamesCaES = map[string]string{
"Sunday": "diumenge",
"Monday": "dilluns",
"Tuesday": "dimarts",
"Wednesday": "dimecres",
"Thursday": "dijous",
"Friday": "divendres",
"Saturday": "dissabte",
}
var shortDayNamesCaES = map[string]string{
"Sun": "dg",
"Mon": "dl",
"Tue": "dt",
"Wed": "dc",
"Thu": "dj",
"Fri": "dv",
"Sat": "ds",
}
var longMonthNamesCaES = map[string]string{
"January": "gener",
"February": "febrer",
"March": "març",
"April": "abril",
"May": "maig",
"June": "juny",
"July": "juliol",
"August": "agost",
"September": "setembre",
"October": "octubre",
"November": "novembre",
"December": "desembre",
}
var shortMonthNamesCaES = map[string]string{
"Jan": "gen",
"Feb": "febr",
"Mar": "març",
"Apr": "abr",
"May": "maig",
"Jun": "juny",
"Jul": "jul",
"Aug": "ag",
"Sep": "set",
"Oct": "oct",
"Nov": "nov",
"Dec": "des",
}

@ -0,0 +1,183 @@
package monday
import "strings"
func findInString(where string, what string, foundIndex *int, trimRight *int) (found bool) {
ind := strings.Index(strings.ToLower(where), strings.ToLower(what))
if ind != -1 {
*foundIndex = ind
*trimRight = len(where) - ind - len(what)
return true
}
return false
}
// commonFormatFunc is used for languages which don't have changed forms of month names dependent
// on their position (after day or standalone)
func commonFormatFunc(value, format string,
knownDaysShort, knownDaysLong, knownMonthsShort, knownMonthsLong, knownPeriods map[string]string) string {
l := stringToLayoutItems(value)
f := stringToLayoutItems(format)
if len(l) != len(f) {
return value // layouts does not matches
}
sb := &strings.Builder{}
sb.Grow(32) // Reasonable default size that should fit most strings.
for i, v := range l {
var knw map[string]string
// number of symbols before replaced term
foundIndex := 0
trimRight := 0
lowerCase := false
switch {
case findInString(f[i].item, "Monday", &foundIndex, &trimRight):
knw = knownDaysLong
case findInString(f[i].item, "Mon", &foundIndex, &trimRight):
knw = knownDaysShort
case findInString(f[i].item, "January", &foundIndex, &trimRight):
knw = knownMonthsLong
case findInString(f[i].item, "Jan", &foundIndex, &trimRight):
knw = knownMonthsShort
case findInString(f[i].item, "PM", &foundIndex, &trimRight):
knw = knownPeriods
case findInString(f[i].item, "pm", &foundIndex, &trimRight):
lowerCase = true
knw = knownPeriods
}
knw = mapToLowerCase(knw)
if knw != nil {
trimmedItem := strings.ToLower(v.item[foundIndex : len(v.item)-trimRight])
tr, ok := knw[trimmedItem]
if lowerCase == true {
tr = strings.ToLower(tr)
}
if ok {
sb.WriteString(v.item[:foundIndex])
sb.WriteString(tr)
sb.WriteString(v.item[len(v.item)-trimRight:])
} else {
sb.WriteString(v.item)
}
} else {
sb.WriteString(v.item)
}
}
return sb.String()
}
func hasDigitBefore(l []dateStringLayoutItem, position int) bool {
if position >= 2 {
return l[position-2].isDigit && len(l[position-2].item) <= 2
}
return false
}
// commonGenitiveFormatFunc is used for languages with genitive forms of names, like Russian.
func commonGenitiveFormatFunc(value, format string,
knownDaysShort, knownDaysLong, knownMonthsShort, knownMonthsLong,
knownMonthsGenShort, knownMonthsGenLong, knownPeriods map[string]string) string {
l := stringToLayoutItems(value)
f := stringToLayoutItems(format)
if len(l) != len(f) {
return value // layouts does not matches
}
sb := &strings.Builder{}
sb.Grow(32) // Reasonable default size that should fit most strings.
for i, v := range l {
lowerCase := false
var knw map[string]string
switch f[i].item {
case "Mon":
knw = knownDaysShort
case "Monday":
knw = knownDaysLong
case "Jan":
if hasDigitBefore(l, i) {
knw = knownMonthsGenShort
} else {
knw = knownMonthsShort
}
case "January":
if hasDigitBefore(l, i) {
knw = knownMonthsGenLong
} else {
knw = knownMonthsLong
}
case "PM":
knw = knownPeriods
case "pm":
lowerCase = true
knw = knownPeriods
}
knw = mapToLowerCase(knw)
if knw != nil {
tr, ok := knw[strings.ToLower(v.item)]
if !ok {
sb.WriteString(v.item)
continue
}
if lowerCase == true {
tr = strings.ToLower(tr)
}
sb.WriteString(tr)
} else {
sb.WriteString(v.item)
}
}
return sb.String()
}
func createCommonFormatFunc(locale Locale) internalFormatFunc {
return func(value, layout string) (res string) {
return commonFormatFunc(value, layout,
knownDaysShort[locale], knownDaysLong[locale], knownMonthsShort[locale], knownMonthsLong[locale], knownPeriods[locale])
}
}
func createCommonFormatFuncWithGenitive(locale Locale) internalFormatFunc {
return func(value, layout string) (res string) {
return commonGenitiveFormatFunc(value, layout,
knownDaysShort[locale], knownDaysLong[locale], knownMonthsShort[locale], knownMonthsLong[locale],
knownMonthsGenitiveShort[locale], knownMonthsGenitiveLong[locale], knownPeriods[locale])
}
}
func createCommonParseFunc(locale Locale) internalParseFunc {
return func(layout, value string) string {
return commonFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriodsReverse[locale])
}
}
func createCommonParsetFuncWithGenitive(locale Locale) internalParseFunc {
return func(layout, value string) (res string) {
return commonGenitiveFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale],
knownMonthsGenitiveShortReverse[locale], knownMonthsGenitiveLongReverse[locale], knownPeriodsReverse[locale])
}
}
func mapToLowerCase(source map[string]string) map[string]string {
result := make(map[string]string, len(source))
for k, v := range source {
result[strings.ToLower(k)] = v
}
return result
}

@ -0,0 +1,85 @@
package monday
// ============================================================
// Format rules for "cs_CZ" locale: Czech (Czech Republic)
// ============================================================
var longDayNamesCsCZ = map[string]string{
"Sunday": "neděle",
"Monday": "pondělí",
"Tuesday": "úterý",
"Wednesday": "středa",
"Thursday": "čtvrtek",
"Friday": "pátek",
"Saturday": "sobota",
}
var shortDayNamesCsCZ = map[string]string{
"Sun": "ne",
"Mon": "po",
"Tue": "út",
"Wed": "st",
"Thu": "čt",
"Fri": "pá",
"Sat": "so",
}
var longMonthNamesCsCZ = map[string]string{
"January": "leden",
"February": "únor",
"March": "březen",
"April": "duben",
"May": "květen",
"June": "červen",
"July": "červenec",
"August": "srpen",
"September": "září",
"October": "říjen",
"November": "listopad",
"December": "prosinec",
}
var shortMonthNamesCsCZ = map[string]string{
"Jan": "led",
"Feb": "úno",
"Mar": "bře",
"Apr": "dub",
"May": "kvě",
"Jun": "čvn",
"Jul": "čvc",
"Aug": "srp",
"Sep": "zář",
"Oct": "říj",
"Nov": "lis",
"Dec": "pro",
}
var longMonthNamesGenitiveCsCZ = map[string]string{
"January": "ledna",
"February": "února",
"March": "března",
"April": "dubna",
"May": "května",
"June": "června",
"July": "července",
"August": "srpna",
"September": "září",
"October": "října",
"November": "listopadu",
"December": "prosince",
}
var shortMonthNamesGenitiveCsCZ = map[string]string{
"Jan": "led",
"Feb": "úno",
"Mar": "bře",
"Apr": "dub",
"May": "kvě",
"Jun": "čvn",
"Jul": "čvc",
"Aug": "srp",
"Sep": "zář",
"Oct": "říj",
"Nov": "lis",
"Dec": "pro",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "da_DK" locale: Danish (Denmark)
// ============================================================
var longDayNamesDaDK = map[string]string{
"Sunday": "søndag",
"Monday": "mandag",
"Tuesday": "tirsdag",
"Wednesday": "onsdag",
"Thursday": "torsdag",
"Friday": "fredag",
"Saturday": "lørdag",
}
var shortDayNamesDaDK = map[string]string{
"Sun": "søn",
"Mon": "man",
"Tue": "tir",
"Wed": "ons",
"Thu": "tor",
"Fri": "fre",
"Sat": "lør",
}
var longMonthNamesDaDK = map[string]string{
"January": "januar",
"February": "februar",
"March": "marts",
"April": "april",
"May": "maj",
"June": "juni",
"July": "juli",
"August": "august",
"September": "september",
"October": "oktober",
"November": "november",
"December": "december",
}
var shortMonthNamesDaDK = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "maj",
"Jun": "jun",
"Jul": "jul",
"Aug": "aug",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "de_DE" locale: German (Germany)
// ============================================================
var longDayNamesDeDE = map[string]string{
"Sunday": "Sonntag",
"Monday": "Montag",
"Tuesday": "Dienstag",
"Wednesday": "Mittwoch",
"Thursday": "Donnerstag",
"Friday": "Freitag",
"Saturday": "Samstag",
}
var shortDayNamesDeDE = map[string]string{
"Sun": "So",
"Mon": "Mo",
"Tue": "Di",
"Wed": "Mi",
"Thu": "Do",
"Fri": "Fr",
"Sat": "Sa",
}
var longMonthNamesDeDE = map[string]string{
"January": "Januar",
"February": "Februar",
"March": "März",
"April": "April",
"May": "Mai",
"June": "Juni",
"July": "Juli",
"August": "August",
"September": "September",
"October": "Oktober",
"November": "November",
"December": "Dezember",
}
var shortMonthNamesDeDE = map[string]string{
"Jan": "Jan",
"Feb": "Feb",
"Mar": "Mär",
"Apr": "Apr",
"May": "Mai",
"Jun": "Juni",
"Jul": "Juli",
"Aug": "Aug",
"Sep": "Sep",
"Oct": "Okt",
"Nov": "Nov",
"Dec": "Dez",
}

@ -0,0 +1,77 @@
package monday
// ============================================================
// Format rules for "el_GR" locale: Greek (Greece)
// ============================================================
var longDayNamesElGR = map[string]string{
"Sunday": "Κυριακή",
"Monday": "Δευτέρα",
"Tuesday": "Τρίτη",
"Wednesday": "Τετάρτη",
"Thursday": "Πέμπτη",
"Friday": "Παρασκευή",
"Saturday": "Σάββατο",
}
var shortDayNamesElGR = map[string]string{
"Sun": "Κυρ",
"Mon": "Δευ",
"Tue": "Τρι",
"Wed": "Τετ",
"Thu": "Πεμ",
"Fri": "Παρ",
"Sat": "Σαβ",
}
var longMonthNamesElGR = map[string]string{
"January": "Ιανουάριος",
"February": "Φεβρουάριος",
"March": "Μάρτιος",
"April": "Απρίλιος",
"May": "Μάιος",
"June": "Ιούνιος",
"July": "Ιούλιος",
"August": "Αύγουστος",
"September": "Σεπτέμβριος",
"October": "Οκτώβριος",
"November": "Νοέμβριος",
"December": "Δεκέμβριος",
}
var longMonthNamesGenitiveElGR = map[string]string{
"January": "Ιανουαρίου",
"February": "Φεβρουαρίου",
"March": "Μαρτίου",
"April": "Απριλίου",
"May": "Μαΐου",
"June": "Ιουνίου",
"July": "Ιουλίου",
"August": "Αυγούστου",
"September": "Σεπτεμβρίου",
"October": "Οκτωβρίου",
"November": "Νοεμβρίου",
"December": "Δεκεμβρίου",
}
var shortMonthNamesElGR = map[string]string{
"Jan": "Ιαν",
"Feb": "Φεβ",
"Mar": "Μαρ",
"Apr": "Απρ",
"May": "Μαϊ",
"Jun": "Ιουν",
"Jul": "Ιουλ",
"Aug": "Αυγ",
"Sep": "Σεπ",
"Oct": "Οκτ",
"Nov": "Νοε",
"Dec": "Δεκ",
}
var periodsElGR = map[string]string{
"am": "πμ",
"pm": "μμ",
"AM": "ΠΜ",
"PM": "ΜΜ",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "en_GB" locale: English (Great Britain)
// ============================================================
var longDayNamesEnGB = map[string]string{
"Sunday": "Sunday",
"Monday": "Monday",
"Tuesday": "Tuesday",
"Wednesday": "Wednesday",
"Thursday": "Thursday",
"Friday": "Friday",
"Saturday": "Saturday",
}
var shortDayNamesEnGB = map[string]string{
"Sun": "Sun",
"Mon": "Mon",
"Tue": "Tue",
"Wed": "Wed",
"Thu": "Thu",
"Fri": "Fri",
"Sat": "Sat",
}
var longMonthNamesEnGB = map[string]string{
"January": "January",
"February": "February",
"March": "March",
"April": "April",
"May": "May",
"June": "June",
"July": "July",
"August": "August",
"September": "September",
"October": "October",
"November": "November",
"December": "December",
}
var shortMonthNamesEnGB = map[string]string{
"Jan": "Jan",
"Feb": "Feb",
"Mar": "Mar",
"Apr": "Apr",
"May": "May",
"Jun": "Jun",
"Jul": "Jul",
"Aug": "Aug",
"Sep": "Sep",
"Oct": "Oct",
"Nov": "Nov",
"Dec": "Dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "en_US" locale: English (United States)
// ============================================================
var longDayNamesEnUS = map[string]string{
"Sunday": "Sunday",
"Monday": "Monday",
"Tuesday": "Tuesday",
"Wednesday": "Wednesday",
"Thursday": "Thursday",
"Friday": "Friday",
"Saturday": "Saturday",
}
var shortDayNamesEnUS = map[string]string{
"Sun": "Sun",
"Mon": "Mon",
"Tue": "Tue",
"Wed": "Wed",
"Thu": "Thu",
"Fri": "Fri",
"Sat": "Sat",
}
var longMonthNamesEnUS = map[string]string{
"January": "January",
"February": "February",
"March": "March",
"April": "April",
"May": "May",
"June": "June",
"July": "July",
"August": "August",
"September": "September",
"October": "October",
"November": "November",
"December": "December",
}
var shortMonthNamesEnUS = map[string]string{
"Jan": "Jan",
"Feb": "Feb",
"Mar": "Mar",
"Apr": "Apr",
"May": "May",
"Jun": "Jun",
"Jul": "Jul",
"Aug": "Aug",
"Sep": "Sep",
"Oct": "Oct",
"Nov": "Nov",
"Dec": "Dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "es_ES" locale: Spanish (Spain)
// ============================================================
var longDayNamesEsES = map[string]string{
"Sunday": "domingo",
"Monday": "lunes",
"Tuesday": "martes",
"Wednesday": "miércoles",
"Thursday": "jueves",
"Friday": "viernes",
"Saturday": "sábado",
}
var shortDayNamesEsES = map[string]string{
"Sun": "dom",
"Mon": "lun",
"Tue": "mar",
"Wed": "mié",
"Thu": "jue",
"Fri": "vie",
"Sat": "sáb",
}
var longMonthNamesEsES = map[string]string{
"January": "enero",
"February": "febrero",
"March": "marzo",
"April": "abril",
"May": "mayo",
"June": "junio",
"July": "julio",
"August": "agosto",
"September": "septiembre",
"October": "octubre",
"November": "noviembre",
"December": "diciembre",
}
var shortMonthNamesEsES = map[string]string{
"Jan": "ene",
"Feb": "feb",
"Mar": "mar",
"Apr": "abr",
"May": "may",
"Jun": "jun",
"Jul": "jul",
"Aug": "ago",
"Sep": "sep",
"Oct": "oct",
"Nov": "nov",
"Dec": "dic",
}

@ -0,0 +1,70 @@
package monday
// ============================================================
// Format rules for "fi_FI" locale: Finnish (Finland)
// ============================================================
var longDayNamesFiFI = map[string]string{
"Sunday": "sunnuntai",
"Monday": "maanantai",
"Tuesday": "tiistai",
"Wednesday": "keskiviikko",
"Thursday": "torstai",
"Friday": "perjantai",
"Saturday": "lauantai",
}
var shortDayNamesFiFI = map[string]string{
"Sun": "su",
"Mon": "ma",
"Tue": "ti",
"Wed": "ke",
"Thu": "to",
"Fri": "pe",
"Sat": "la",
}
var longMonthNamesFiFI = map[string]string{
"January": "tammikuu",
"February": "helmikuu",
"March": "maaliskuu",
"April": "huhtikuu",
"May": "toukokuu",
"June": "kesäkuu",
"July": "heinäkuu",
"August": "elokuu",
"September": "syyskuu",
"October": "lokakuu",
"November": "marraskuu",
"December": "joulukuu",
}
var longMonthNamesGenitiveFiFI = map[string]string{
"January": "tammikuuta",
"February": "helmikuuta",
"March": "maaliskuuta",
"April": "huhtikuuta",
"May": "toukokuuta",
"June": "kesäkuuta",
"July": "heinäkuuta",
"August": "elokuuta",
"September": "syyskuuta",
"October": "lokakuuta",
"November": "marraskuuta",
"December": "joulukuuta",
}
var shortMonthNamesFiFI = map[string]string{
"Jan": "tammi",
"Feb": "helmi",
"Mar": "maalis",
"Apr": "huhti",
"May": "touko",
"Jun": "kesä",
"Jul": "heinä",
"Aug": "elo",
"Sep": "syys",
"Oct": "loka",
"Nov": "marras",
"Dec": "joulu",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "fr_FR" locale: French (France)
// ============================================================
var longDayNamesFrFR = map[string]string{
"Sunday": "dimanche",
"Monday": "lundi",
"Tuesday": "mardi",
"Wednesday": "mercredi",
"Thursday": "jeudi",
"Friday": "vendredi",
"Saturday": "samedi",
}
var shortDayNamesFrFR = map[string]string{
"Sun": "dim",
"Mon": "lun",
"Tue": "mar",
"Wed": "mer",
"Thu": "jeu",
"Fri": "ven",
"Sat": "sam",
}
var longMonthNamesFrFR = map[string]string{
"January": "janvier",
"February": "février",
"March": "mars",
"April": "avril",
"May": "mai",
"June": "juin",
"July": "juillet",
"August": "août",
"September": "septembre",
"October": "octobre",
"November": "novembre",
"December": "décembre",
}
var shortMonthNamesFrFR = map[string]string{
"Jan": "janv",
"Feb": "févr",
"Mar": "mars",
"Apr": "avr",
"May": "mai",
"Jun": "juin",
"Jul": "juil",
"Aug": "août",
"Sep": "sept",
"Oct": "oct",
"Nov": "nov",
"Dec": "déc",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "hu_HU" locale: Hungarian (Hungary)
// ============================================================
var longDayNamesHuHU = map[string]string{
"Sunday": "vasárnap",
"Monday": "hétfő",
"Tuesday": "kedd",
"Wednesday": "szerda",
"Thursday": "csütörtök",
"Friday": "péntek",
"Saturday": "szombat",
}
var shortDayNamesHuHU = map[string]string{
"Sun": "V",
"Mon": "H",
"Tue": "K",
"Wed": "Sze",
"Thu": "Cs",
"Fri": "P",
"Sat": "Szo",
}
var longMonthNamesHuHU = map[string]string{
"January": "január",
"February": "február",
"March": "március",
"April": "április",
"May": "május",
"June": "június",
"July": "július",
"August": "augusztus",
"September": "szeptember",
"October": "október",
"November": "november",
"December": "december",
}
var shortMonthNamesHuHU = map[string]string{
"Jan": "jan",
"Feb": "febr",
"Mar": "márc",
"Apr": "ápr",
"May": "máj",
"Jun": "jún",
"Jul": "júl",
"Aug": "aug",
"Sep": "szept",
"Oct": "okt",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "id_ID" locale: Indonesian (Indonesia)
// ============================================================
var longDayNamesIdID = map[string]string{
"Sunday": "Minggu",
"Monday": "Senin",
"Tuesday": "Selasa",
"Wednesday": "Rabu",
"Thursday": "Kamis",
"Friday": "Jumat",
"Saturday": "Sabtu",
}
var shortDayNamesIdID = map[string]string{
"Sun": "Min",
"Mon": "Sen",
"Tue": "Sel",
"Wed": "Rab",
"Thu": "Kam",
"Fri": "Jum",
"Sat": "Sab",
}
var longMonthNamesIdID = map[string]string{
"January": "Januari",
"February": "Februari",
"March": "Maret",
"April": "April",
"May": "Mei",
"June": "Juni",
"July": "Juli",
"August": "Agustus",
"September": "September",
"October": "Oktober",
"November": "November",
"December": "Desember",
}
var shortMonthNamesIdID = map[string]string{
"Jan": "Jan",
"Feb": "Feb",
"Mar": "Mar",
"Apr": "Apr",
"May": "Mei",
"Jun": "Jun",
"Jul": "Jul",
"Aug": "Ags",
"Sep": "Sep",
"Oct": "Okt",
"Nov": "Nov",
"Dec": "Des",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "it_IT" locale: Italian (Italy)
// ============================================================
var longDayNamesItIT = map[string]string{
"Sunday": "domenica",
"Monday": "lunedì",
"Tuesday": "martedì",
"Wednesday": "mercoledì",
"Thursday": "giovedì",
"Friday": "venerdì",
"Saturday": "sabato",
}
var shortDayNamesItIT = map[string]string{
"Sun": "dom",
"Mon": "lun",
"Tue": "mar",
"Wed": "mer",
"Thu": "gio",
"Fri": "ven",
"Sat": "sab",
}
var longMonthNamesItIT = map[string]string{
"January": "gennaio",
"February": "febbraio",
"March": "marzo",
"April": "aprile",
"May": "maggio",
"June": "giugno",
"July": "luglio",
"August": "agosto",
"September": "settembre",
"October": "ottobre",
"November": "novembre",
"December": "dicembre",
}
var shortMonthNamesItIT = map[string]string{
"Jan": "gen",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "mag",
"Jun": "giu",
"Jul": "lug",
"Aug": "ago",
"Sep": "set",
"Oct": "ott",
"Nov": "nov",
"Dec": "dic",
}

@ -0,0 +1,95 @@
package monday
import (
"strings"
)
// ============================================================
// Format rules for "ja_JP" locale: Japanese
// ============================================================
var longDayNamesJaJP = map[string]string{
"Sunday": "日曜日",
"Monday": "月曜日",
"Tuesday": "火曜日",
"Wednesday": "水曜日",
"Thursday": "木曜日",
"Friday": "金曜日",
"Saturday": "土曜日",
}
var shortDayNamesJaJP = map[string]string{
"Sun": "日",
"Mon": "月",
"Tue": "火",
"Wed": "水",
"Thu": "木",
"Fri": "金",
"Sat": "土",
}
var longMonthNamesJaJP = map[string]string{
"January": "1月",
"February": "2月",
"March": "3月",
"April": "4月",
"May": "5月",
"June": "6月",
"July": "7月",
"August": "8月",
"September": "9月",
"October": "10月",
"November": "11月",
"December": "12月",
}
var shortMonthNamesJaJP = map[string]string{
"Jan": "1月",
"Feb": "2月",
"Mar": "3月",
"Apr": "4月",
"May": "5月",
"Jun": "6月",
"Jul": "7月",
"Aug": "8月",
"Sep": "9月",
"Oct": "10月",
"Nov": "11月",
"Dec": "12月",
}
var periodsJaJP = map[string]string{
"am": "午前",
"pm": "午後",
"AM": "午前",
"PM": "午後",
}
func parseFuncJaCommon(locale Locale) internalParseFunc {
return func(layout, value string) string {
// This special case is needed because ja_JP... contains month names
// that consist of a number, a delimiter, and '月'. Example: "October" = "10 月"
//
// This means that probably default time package layout IDs like 'January' or 'Jan'
// shouldn't be used in ja_JP. But this is a time-compatible package, so someone
// might actually use those and we need to replace those before doing standard procedures.
for k, v := range knownMonthsLongReverse[locale] {
value = strings.Replace(value, k, v, -1)
}
value = commonFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale])
// knownPeriodsReverse has hash collisions
for k, v := range knownPeriodsReverse[locale] {
targetValue := strings.ToLower(v)
if strings.Index(layout, "PM") != -1 {
targetValue = strings.ToUpper(v)
}
value = strings.Replace(value, k, targetValue, -1)
}
return value
}
}

@ -0,0 +1,94 @@
package monday
import "strings"
// ============================================================
// Format rules for "ko_KR" locale: Korean (Korea)
// ============================================================
var longDayNamesKoKR = map[string]string{
"Sunday": "일요일",
"Monday": "월요일",
"Tuesday": "화요일",
"Wednesday": "수요일",
"Thursday": "목요일",
"Friday": "금요일",
"Saturday": "토요일",
}
var shortDayNamesKoKR = map[string]string{
"Sun": "일",
"Mon": "월",
"Tue": "화",
"Wed": "수",
"Thu": "목",
"Fri": "금",
"Sat": "토",
}
var longMonthNamesKoKR = map[string]string{
"January": "1월",
"February": "2월",
"March": "3월",
"April": "4월",
"May": "5월",
"June": "6월",
"July": "7월",
"August": "8월",
"September": "9월",
"October": "10월",
"November": "11월",
"December": "12월",
}
var shortMonthNamesKoKR = map[string]string{
"Jan": "1월",
"Feb": "2월",
"Mar": "3월",
"Apr": "4월",
"May": "5월",
"Jun": "6월",
"Jul": "7월",
"Aug": "8월",
"Sep": "9월",
"Oct": "10월",
"Nov": "11월",
"Dec": "12월",
}
var periodsKoKR = map[string]string{
"am": "오전",
"pm": "오후",
"AM": "오전",
"PM": "오후",
}
func parseFuncKoCommon(locale Locale) internalParseFunc {
return func(layout, value string) string {
// This special case is needed because ko_KR... contains month names
// that consist of a number, a delimiter, and '월'. Example: "September" = "9 월"
//
// This means that probably default time package layout IDs like 'January' or 'Jan'
// shouldn't be used in ko_KR. But this is a time-compatible package, so someone
// might actually use those and we need to replace those before doing standard procedures.
for k, v := range knownMonthsLongReverse[locale] {
value = strings.Replace(value, k, v, -1)
}
value = commonFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale])
// knownPeriodsReverse has hash collisions
for k, v := range knownPeriodsReverse[locale] {
targetValue := strings.ToLower(v)
if strings.Index(layout, "PM") != -1 {
targetValue = strings.ToUpper(v)
}
value = strings.Replace(value, k, targetValue, -1)
}
return value
}
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "nb_NO" locale: Norwegian Bokmål (Norway)
// ============================================================
var longDayNamesNbNO = map[string]string{
"Sunday": "søndag",
"Monday": "mandag",
"Tuesday": "tirsdag",
"Wednesday": "onsdag",
"Thursday": "torsdag",
"Friday": "fredag",
"Saturday": "lørdag",
}
var shortDayNamesNbNO = map[string]string{
"Sun": "sø",
"Mon": "ma",
"Tue": "ti",
"Wed": "on",
"Thu": "to",
"Fri": "fr",
"Sat": "lø",
}
var longMonthNamesNbNO = map[string]string{
"January": "januar",
"February": "februar",
"March": "mars",
"April": "april",
"May": "mai",
"June": "juni",
"July": "juli",
"August": "august",
"September": "september",
"October": "oktober",
"November": "november",
"December": "desember",
}
var shortMonthNamesNbNO = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "mai",
"Jun": "jun",
"Jul": "jul",
"Aug": "aug",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "des",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "nl_BE" locale: Dutch (Belgium)
// ============================================================
var longDayNamesNlBE = map[string]string{
"Sunday": "zondag",
"Monday": "maandag",
"Tuesday": "dinsdag",
"Wednesday": "woensdag",
"Thursday": "donderdag",
"Friday": "vrijdag",
"Saturday": "zaterdag",
}
var shortDayNamesNlBE = map[string]string{
"Sun": "zo",
"Mon": "ma",
"Tue": "di",
"Wed": "wo",
"Thu": "do",
"Fri": "vr",
"Sat": "za",
}
var longMonthNamesNlBE = map[string]string{
"January": "januari",
"February": "februari",
"March": "maart",
"April": "april",
"May": "mei",
"June": "juni",
"July": "juli",
"August": "augustus",
"September": "september",
"October": "oktober",
"November": "november",
"December": "december",
}
var shortMonthNamesNlBE = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mrt",
"Apr": "apr",
"May": "mei",
"Jun": "jun",
"Jul": "jul",
"Aug": "aug",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "nn_NO" locale: Norwegian Nynorsk (Norway)
// ============================================================
var longDayNamesNnNO = map[string]string{
"Sunday": "søndag",
"Monday": "måndag",
"Tuesday": "tysdag",
"Wednesday": "onsdag",
"Thursday": "torsdag",
"Friday": "fredag",
"Saturday": "laurdag",
}
var shortDayNamesNnNO = map[string]string{
"Sun": "sø",
"Mon": "må",
"Tue": "ty",
"Wed": "on",
"Thu": "to",
"Fri": "fr",
"Sat": "la",
}
var longMonthNamesNnNO = map[string]string{
"January": "januar",
"February": "februar",
"March": "mars",
"April": "april",
"May": "mai",
"June": "juni",
"July": "juli",
"August": "august",
"September": "september",
"October": "oktober",
"November": "november",
"December": "desember",
}
var shortMonthNamesNnNO = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mars",
"Apr": "apr",
"May": "mai",
"Jun": "juni",
"Jul": "juli",
"Aug": "aug",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "des",
}

@ -0,0 +1,56 @@
package monday
// ============================================================
// Format rules for "pl_PL" locale: Polish (Poland)
// ============================================================
var longDayNamesPlPL = map[string]string{
"Sunday": "Niedziela",
"Monday": "Poniedziałek",
"Tuesday": "Wtorek",
"Wednesday": "Środa",
"Thursday": "Czwartek",
"Friday": "Piątek",
"Saturday": "Sobota",
}
// http://sjp.pwn.pl/poradnia/haslo/skracanie-nazw-dni-tygodnia-i-miesiecy;8124.html
var shortDayNamesPlPL = map[string]string{
"Sun": "Nie",
"Mon": "Pon",
"Tue": "Wto",
"Wed": "Śro",
"Thu": "Czw",
"Fri": "Pią",
"Sat": "Sob",
}
var longMonthNamesPlPL = map[string]string{
"January": "Styczeń",
"February": "Luty",
"March": "Marzec",
"April": "Kwiecień",
"May": "Maj",
"June": "Czerwiec",
"July": "Lipiec",
"August": "Sierpień",
"September": "Wrzesień",
"October": "Październik",
"November": "Listopad",
"December": "Grudzień",
}
var shortMonthNamesPlPL = map[string]string{
"Jan": "Sty",
"Feb": "Lut",
"Mar": "Mar",
"Apr": "Kwi",
"May": "Maj",
"Jun": "Cze",
"Jul": "Lip",
"Aug": "Sie",
"Sep": "Wrz",
"Oct": "Paź",
"Nov": "Lis",
"Dec": "Gru",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "pt_BR" locale: Portuguese (Brazil)
// ============================================================
var longDayNamesPtBR = map[string]string{
"Sunday": "domingo",
"Monday": "segunda-feira",
"Tuesday": "terça-feira",
"Wednesday": "quarta-feira",
"Thursday": "quinta-feira",
"Friday": "sexta-feira",
"Saturday": "sábado",
}
var shortDayNamesPtBR = map[string]string{
"Sun": "dom",
"Mon": "seg",
"Tue": "ter",
"Wed": "qua",
"Thu": "qui",
"Fri": "sex",
"Sat": "sáb",
}
var longMonthNamesPtBR = map[string]string{
"January": "janeiro",
"February": "fevereiro",
"March": "março",
"April": "abril",
"May": "maio",
"June": "junho",
"July": "julho",
"August": "agosto",
"September": "setembro",
"October": "outubro",
"November": "novembro",
"December": "dezembro",
}
var shortMonthNamesPtBR = map[string]string{
"Jan": "jan",
"Feb": "fev",
"Mar": "mar",
"Apr": "abr",
"May": "mai",
"Jun": "jun",
"Jul": "jul",
"Aug": "ago",
"Sep": "set",
"Oct": "out",
"Nov": "nov",
"Dec": "dez",
}

@ -0,0 +1,72 @@
package monday
import "strings"
// ============================================================
// Format rules for "pt_PT" locale: Portuguese (Portugal)
// ============================================================
var longDayNamesPtPT = map[string]string{
"Sunday": "Domingo",
"Monday": "Segunda-feira",
"Tuesday": "Terça-feira",
"Wednesday": "Quarta-feira",
"Thursday": "Quinta-feira",
"Friday": "Sexta-feira",
"Saturday": "Sábado",
}
var shortDayNamesPtPT = map[string]string{
"Sun": "dom",
"Mon": "seg",
"Tue": "ter",
"Wed": "qua",
"Thu": "qui",
"Fri": "sex",
"Sat": "sáb",
}
var longMonthNamesPtPT = map[string]string{
"January": "Janeiro",
"February": "Fevereiro",
"March": "Março",
"April": "Abril",
"May": "Maio",
"June": "Junho",
"July": "Julho",
"August": "Agosto",
"September": "Setembro",
"October": "Outubro",
"November": "Novembro",
"December": "Dezembro",
}
var shortMonthNamesPtPT = map[string]string{
"Jan": "Jan",
"Feb": "Fev",
"Mar": "Mar",
"Apr": "Abr",
"May": "Mai",
"Jun": "Jun",
"Jul": "Jul",
"Aug": "Ago",
"Sep": "Set",
"Oct": "Out",
"Nov": "Nov",
"Dec": "Dez",
}
func parseFuncPtCommon(locale Locale) internalParseFunc {
return func(layout, value string) string {
// This special case is needed because Pt_PT/Pt_BR/... contains day-of-week names
// that consist of two words and a delimiter (like 'terça-feira'). These
// should be replaced before using the standard procedure correctly.
for k, v := range knownDaysLongReverse[locale] {
value = strings.Replace(value, k, v, -1)
}
return commonFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale])
}
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "ro_RO" locale: Romanian (Romania)
// ============================================================
var longDayNamesRoRO = map[string]string{
"Sunday": "duminică",
"Monday": "luni",
"Tuesday": "marți",
"Wednesday": "miercuri",
"Thursday": "joi",
"Friday": "vineri",
"Saturday": "sâmbătă",
}
var shortDayNamesRoRO = map[string]string{
"Sun": "Du",
"Mon": "Lu",
"Tue": "Ma",
"Wed": "Mi",
"Thu": "Jo",
"Fri": "Vi",
"Sat": "Sâ",
}
var longMonthNamesRoRO = map[string]string{
"January": "ianuarie",
"February": "februarie",
"March": "martie",
"April": "aprilie",
"May": "mai",
"June": "iunie",
"July": "iulie",
"August": "august",
"September": "septembrie",
"October": "octombrie",
"November": "noiembrie",
"December": "decembrie",
}
var shortMonthNamesRoRO = map[string]string{
"Jan": "ian",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "mai",
"Jun": "iun",
"Jul": "iul",
"Aug": "aug",
"Sep": "sept",
"Oct": "oct",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,85 @@
package monday
// ============================================================
// Format rules for "ru_RU" locale: Russian (Russia)
// ============================================================
var longDayNamesRuRU = map[string]string{
"Sunday": "Воскресенье",
"Monday": "Понедельник",
"Tuesday": "Вторник",
"Wednesday": "Среда",
"Thursday": "Четверг",
"Friday": "Пятница",
"Saturday": "Суббота",
}
var shortDayNamesRuRU = map[string]string{
"Sun": "Вс",
"Mon": "Пн",
"Tue": "Вт",
"Wed": "Ср",
"Thu": "Чт",
"Fri": "Пт",
"Sat": "Сб",
}
var longMonthNamesRuRU = map[string]string{
"January": "Январь",
"February": "Февраль",
"March": "Март",
"April": "Апрель",
"May": "Май",
"June": "Июнь",
"July": "Июль",
"August": "Август",
"September": "Сентябрь",
"October": "Октябрь",
"November": "Ноябрь",
"December": "Декабрь",
}
var longMonthNamesGenitiveRuRU = map[string]string{
"January": "января",
"February": "февраля",
"March": "марта",
"April": "апреля",
"May": "мая",
"June": "июня",
"July": "июля",
"August": "августа",
"September": "сентября",
"October": "октября",
"November": "ноября",
"December": "декабря",
}
var shortMonthNamesRuRU = map[string]string{
"Jan": "Янв",
"Feb": "Фев",
"Mar": "Мар",
"Apr": "Апр",
"May": "Май",
"Jun": "Июн",
"Jul": "Июл",
"Aug": "Авг",
"Sep": "Сен",
"Oct": "Окт",
"Nov": "Ноя",
"Dec": "Дек",
}
var shortMonthNamesGenitiveRuRU = map[string]string{
"Jan": "янв",
"Feb": "фев",
"Mar": "мар",
"Apr": "апр",
"May": "мая",
"Jun": "июн",
"Jul": "июл",
"Aug": "авг",
"Sep": "сен",
"Oct": "окт",
"Nov": "ноя",
"Dec": "дек",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "sl_SI" locale: Slovenian
// ============================================================
var longDayNamesSlSI = map[string]string{
"Sunday": "nedelja",
"Monday": "ponedeljek",
"Tuesday": "toret",
"Wednesday": "sreda",
"Thursday": "četrtek",
"Friday": "petek",
"Saturday": "sobota",
}
var shortDayNamesSlSI = map[string]string{
"Sun": "ned",
"Mon": "pon",
"Tue": "tor",
"Wed": "sre",
"Thu": "čet",
"Fri": "pet",
"Sat": "sob",
}
var longMonthNamesSlSI = map[string]string{
"January": "januar",
"February": "februar",
"March": "marec",
"April": "april",
"May": "maj",
"June": "junij",
"July": "julij",
"August": "avgust",
"September": "september",
"October": "oktober",
"November": "november",
"December": "december",
}
var shortMonthNamesSlSI = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "maj",
"Jun": "jun",
"Jul": "jul",
"Aug": "avg",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "sv_SE" locale: Swedish (Sweden)
// ============================================================
var longDayNamesSvSE = map[string]string{
"Sunday": "söndag",
"Monday": "måndag",
"Tuesday": "tisdag",
"Wednesday": "onsdag",
"Thursday": "torsdag",
"Friday": "fredag",
"Saturday": "lördag",
}
var shortDayNamesSvSE = map[string]string{
"Sun": "sön",
"Mon": "mån",
"Tue": "tis",
"Wed": "ons",
"Thu": "tors",
"Fri": "fre",
"Sat": "lör",
}
var longMonthNamesSvSE = map[string]string{
"January": "januari",
"February": "februari",
"March": "mars",
"April": "april",
"May": "maj",
"June": "juni",
"July": "juli",
"August": "augusti",
"September": "september",
"October": "oktober",
"November": "november",
"December": "december",
}
var shortMonthNamesSvSE = map[string]string{
"Jan": "jan",
"Feb": "feb",
"Mar": "mar",
"Apr": "apr",
"May": "maj",
"Jun": "jun",
"Jul": "jul",
"Aug": "aug",
"Sep": "sep",
"Oct": "okt",
"Nov": "nov",
"Dec": "dec",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "tr_TR" locale: Turkish (Turkey)
// ============================================================
var longDayNamesTrTR = map[string]string{
"Sunday": "Pazar",
"Monday": "Pazartesi",
"Tuesday": "Salı",
"Wednesday": "Çarşamba",
"Thursday": "Perşembe",
"Friday": "Cuma",
"Saturday": "Cumartesi",
}
var shortDayNamesTrTR = map[string]string{
"Sun": "Paz",
"Mon": "Pzt",
"Tue": "Sal",
"Wed": "Çar",
"Thu": "Per",
"Fri": "Cum",
"Sat": "Cmt",
}
var longMonthNamesTrTR = map[string]string{
"January": "Ocak",
"February": "Şubat",
"March": "Mart",
"April": "Nisan",
"May": "Mayıs",
"June": "Haziran",
"July": "Temmuz",
"August": "Ağustos",
"September": "Eylül",
"October": "Ekim",
"November": "Kasım",
"December": "Aralık",
}
var shortMonthNamesTrTR = map[string]string{
"Jan": "Oca",
"Feb": "Şub",
"Mar": "Mar",
"Apr": "Nis",
"May": "May",
"Jun": "Haz",
"Jul": "Tem",
"Aug": "Ağu",
"Sep": "Eyl",
"Oct": "Eki",
"Nov": "Kas",
"Dec": "Ara",
}

@ -0,0 +1,85 @@
package monday
// ============================================================
// Format rules for "uk_UA" locale: Ukrainian (Ukraine)
// ============================================================
var longDayNamesUkUA = map[string]string{
"Sunday": "Неділя",
"Monday": "Понеділок",
"Tuesday": "Вівторок",
"Wednesday": "Середа",
"Thursday": "Четвер",
"Friday": "П’ятниця",
"Saturday": "Субота",
}
var shortDayNamesUkUA = map[string]string{
"Sun": "Нд",
"Mon": "Пн",
"Tue": "Вт",
"Wed": "Ср",
"Thu": "Чт",
"Fri": "Пт",
"Sat": "Сб",
}
var longMonthNamesUkUA = map[string]string{
"January": "Січень",
"February": "Лютий",
"March": "Березень",
"April": "Квітень",
"May": "Травень",
"June": "Червень",
"July": "Липень",
"August": "Серпень",
"September": "Вересень",
"October": "Жовтень",
"November": "Листопад",
"December": "Грудень",
}
var longMonthNamesGenitiveUkUA = map[string]string{
"January": "січеня",
"February": "лютого",
"March": "березня",
"April": "квітня",
"May": "травня",
"June": "червня",
"July": "липня",
"August": "серпня",
"September": "вересня",
"October": "жовтня",
"November": "листопада",
"December": "грудня",
}
var shortMonthNamesUkUA = map[string]string{
"Jan": "Січ",
"Feb": "Лют",
"Mar": "Бер",
"Apr": "Кві",
"May": "Тра",
"Jun": "Чер",
"Jul": "Лип",
"Aug": "Сер",
"Sep": "Вер",
"Oct": "Жов",
"Nov": "Лис",
"Dec": "Гру",
}
var shortMonthNamesGenitiveUkUA = map[string]string{
"Jan": "січ",
"Feb": "лют",
"Mar": "бер",
"Apr": "кві",
"May": "тра",
"Jun": "чер",
"Jul": "лип",
"Aug": "сер",
"Sep": "вер",
"Oct": "жов",
"Nov": "лис",
"Dec": "гру",
}

@ -0,0 +1,75 @@
package monday
import "strings"
// ============================================================
// Format rules for "zh_CN" locale: Chinese (Mainland)
// ============================================================
var longDayNamesZhCN = map[string]string{
"Sunday": "星期日",
"Monday": "星期一",
"Tuesday": "星期二",
"Wednesday": "星期三",
"Thursday": "星期四",
"Friday": "星期五",
"Saturday": "星期六",
}
var shortDayNamesZhCN = map[string]string{
"Sun": "日",
"Mon": "一",
"Tue": "二",
"Wed": "三",
"Thu": "四",
"Fri": "五",
"Sat": "六",
}
var longMonthNamesZhCN = map[string]string{
"January": "1 月",
"February": "2 月",
"March": "3 月",
"April": "4 月",
"May": "5 月",
"June": "6 月",
"July": "7 月",
"August": "8 月",
"September": "9 月",
"October": "10 月",
"November": "11 月",
"December": "12 月",
}
var shortMonthNamesZhCN = map[string]string{
"Jan": "1",
"Feb": "2",
"Mar": "3",
"Apr": "4",
"May": "5",
"Jun": "6",
"Jul": "7",
"Aug": "8",
"Sep": "9",
"Oct": "10",
"Nov": "11",
"Dec": "12",
}
func parseFuncZhCommon(locale Locale) internalParseFunc {
return func(layout, value string) string {
// This special case is needed because Zh_CN/Zh/HK/... contains month names
// that consist of a number, a delimiter, and '月'. Example: "October" = "10 月"
//
// This means that probably default time package layout IDs like 'January' or 'Jan'
// shouldn't be used in Zh_*. But this is a time-compatible package, so someone
// might actually use those and we need to replace those before doing standard procedures.
for k, v := range knownMonthsLongReverse[locale] {
value = strings.Replace(value, k, v, -1)
}
return commonFormatFunc(value, layout,
knownDaysShortReverse[locale], knownDaysLongReverse[locale],
knownMonthsShortReverse[locale], knownMonthsLongReverse[locale], knownPeriods[locale])
}
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "zh_HK" locale: Chinese (Hong Kong)
// ============================================================
var longDayNamesZhHK = map[string]string{
"Sunday": "星期日",
"Monday": "星期一",
"Tuesday": "星期二",
"Wednesday": "星期三",
"Thursday": "星期四",
"Friday": "星期五",
"Saturday": "星期六",
}
var shortDayNamesZhHK = map[string]string{
"Sun": "日",
"Mon": "一",
"Tue": "二",
"Wed": "三",
"Thu": "四",
"Fri": "五",
"Sat": "六",
}
var longMonthNamesZhHK = map[string]string{
"January": "1 月",
"February": "2 月",
"March": "3 月",
"April": "4 月",
"May": "5 月",
"June": "6 月",
"July": "7 月",
"August": "8 月",
"September": "9 月",
"October": "10 月",
"November": "11 月",
"December": "12 月",
}
var shortMonthNamesZhHK = map[string]string{
"Jan": "1",
"Feb": "2",
"Mar": "3",
"Apr": "4",
"May": "5",
"Jun": "6",
"Jul": "7",
"Aug": "8",
"Sep": "9",
"Oct": "10",
"Nov": "11",
"Dec": "12",
}

@ -0,0 +1,55 @@
package monday
// ============================================================
// Format rules for "zh_TW" locale: Chinese (Taiwan)
// ============================================================
var longDayNamesZhTW = map[string]string{
"Sunday": "星期日",
"Monday": "星期一",
"Tuesday": "星期二",
"Wednesday": "星期三",
"Thursday": "星期四",
"Friday": "星期五",
"Saturday": "星期六",
}
var shortDayNamesZhTW = map[string]string{
"Sun": "日",
"Mon": "一",
"Tue": "二",
"Wed": "三",
"Thu": "四",
"Fri": "五",
"Sat": "六",
}
var longMonthNamesZhTW = map[string]string{
"January": "1 月",
"February": "2 月",
"March": "3 月",
"April": "4 月",
"May": "5 月",
"June": "6 月",
"July": "7 月",
"August": "8 月",
"September": "9 月",
"October": "10 月",
"November": "11 月",
"December": "12 月",
}
var shortMonthNamesZhTW = map[string]string{
"Jan": "1",
"Feb": "2",
"Mar": "3",
"Apr": "4",
"May": "5",
"Jun": "6",
"Jul": "7",
"Aug": "8",
"Sep": "9",
"Oct": "10",
"Nov": "11",
"Dec": "12",
}

@ -0,0 +1,91 @@
package monday
// Locale identifies locales supported by 'monday' package.
// Monday uses ICU locale identifiers. See http://userguide.icu-project.org/locale
type Locale string
// Locale constants represent all locales that are currently supported by
// this package.
const (
LocaleEnUS = "en_US" // English (United States)
LocaleEnGB = "en_GB" // English (United Kingdom)
LocaleDaDK = "da_DK" // Danish (Denmark)
LocaleNlBE = "nl_BE" // Dutch (Belgium)
LocaleNlNL = "nl_NL" // Dutch (Netherlands)
LocaleFiFI = "fi_FI" // Finnish (Finland)
LocaleFrFR = "fr_FR" // French (France)
LocaleFrCA = "fr_CA" // French (Canada)
LocaleDeDE = "de_DE" // German (Germany)
LocaleHuHU = "hu_HU" // Hungarian (Hungary)
LocaleItIT = "it_IT" // Italian (Italy)
LocaleNnNO = "nn_NO" // Norwegian Nynorsk (Norway)
LocaleNbNO = "nb_NO" // Norwegian Bokmål (Norway)
LocalePlPL = "pl_PL" // Polish (Poland)
LocalePtPT = "pt_PT" // Portuguese (Portugal)
LocalePtBR = "pt_BR" // Portuguese (Brazil)
LocaleRoRO = "ro_RO" // Romanian (Romania)
LocaleRuRU = "ru_RU" // Russian (Russia)
LocaleEsES = "es_ES" // Spanish (Spain)
LocaleCaES = "ca_ES" // Catalan (Spain)
LocaleSvSE = "sv_SE" // Swedish (Sweden)
LocaleTrTR = "tr_TR" // Turkish (Turkey)
LocaleUkUA = "uk_UA" // Ukrainian (Ukraine)
LocaleBgBG = "bg_BG" // Bulgarian (Bulgaria)
LocaleZhCN = "zh_CN" // Chinese (Mainland)
LocaleZhTW = "zh_TW" // Chinese (Taiwan)
LocaleZhHK = "zh_HK" // Chinese (Hong Kong)
LocaleKoKR = "ko_KR" // Korean (Korea)
LocaleJaJP = "ja_JP" // Japanese (Japan)
LocaleElGR = "el_GR" // Greek (Greece)
LocaleIdID = "id_ID" // Indonesian (Indonesia)
LocaleFrGP = "fr_GP" // French (Guadeloupe)
LocaleFrLU = "fr_LU" // French (Luxembourg)
LocaleFrMQ = "fr_MQ" // French (Martinique)
LocaleFrRE = "fr_RE" // French (Reunion)
LocaleFrGF = "fr_GF" // French (French Guiana)
LocaleCsCZ = "cs_CZ" // Czech (Czech Republic)
LocaleSlSI = "sl_SI" // Slovenian (Slovenia)
)
// ListLocales returns all locales supported by the package.
func ListLocales() []Locale {
return []Locale{
LocaleEnUS,
LocaleEnGB,
LocaleDaDK,
LocaleNlBE,
LocaleNlNL,
LocaleFiFI,
LocaleFrFR,
LocaleFrCA,
LocaleDeDE,
LocaleHuHU,
LocaleItIT,
LocaleNnNO,
LocaleNbNO,
LocalePlPL,
LocalePtPT,
LocalePtBR,
LocaleRoRO,
LocaleRuRU,
LocaleEsES,
LocaleCaES,
LocaleSvSE,
LocaleTrTR,
LocaleUkUA,
LocaleBgBG,
LocaleZhCN,
LocaleZhTW,
LocaleZhHK,
LocaleKoKR,
LocaleJaJP,
LocaleElGR,
LocaleFrGP,
LocaleFrLU,
LocaleFrMQ,
LocaleFrRE,
LocaleFrGF,
LocaleCsCZ,
LocaleSlSI,
}
}

@ -0,0 +1,563 @@
package monday
import (
"fmt"
"time"
)
// internalFormatFunc is a preprocessor for default time.Format func
type internalFormatFunc func(value, layout string) string
var internalFormatFuncs = map[Locale]internalFormatFunc{
LocaleEnUS: createCommonFormatFunc(LocaleEnUS),
LocaleEnGB: createCommonFormatFunc(LocaleEnGB),
LocaleDaDK: createCommonFormatFunc(LocaleDaDK),
LocaleNlBE: createCommonFormatFunc(LocaleNlBE),
LocaleNlNL: createCommonFormatFunc(LocaleNlNL),
LocaleFrFR: createCommonFormatFunc(LocaleFrFR),
LocaleFrCA: createCommonFormatFunc(LocaleFrFR),
LocaleFrGP: createCommonFormatFunc(LocaleFrFR),
LocaleFrLU: createCommonFormatFunc(LocaleFrFR),
LocaleFrMQ: createCommonFormatFunc(LocaleFrFR),
LocaleFrGF: createCommonFormatFunc(LocaleFrFR),
LocaleFrRE: createCommonFormatFunc(LocaleFrFR),
LocaleRuRU: createCommonFormatFuncWithGenitive(LocaleRuRU),
LocaleFiFI: createCommonFormatFuncWithGenitive(LocaleFiFI),
LocaleDeDE: createCommonFormatFunc(LocaleDeDE),
LocaleHuHU: createCommonFormatFunc(LocaleHuHU),
LocaleItIT: createCommonFormatFunc(LocaleItIT),
LocaleNnNO: createCommonFormatFunc(LocaleNnNO),
LocaleNbNO: createCommonFormatFunc(LocaleNbNO),
LocalePlPL: createCommonFormatFunc(LocalePlPL),
LocalePtPT: createCommonFormatFunc(LocalePtPT),
LocalePtBR: createCommonFormatFunc(LocalePtBR),
LocaleRoRO: createCommonFormatFunc(LocaleRoRO),
LocaleEsES: createCommonFormatFunc(LocaleEsES),
LocaleCaES: createCommonFormatFunc(LocaleCaES),
LocaleSvSE: createCommonFormatFunc(LocaleSvSE),
LocaleTrTR: createCommonFormatFunc(LocaleTrTR),
LocaleUkUA: createCommonFormatFuncWithGenitive(LocaleUkUA),
LocaleBgBG: createCommonFormatFunc(LocaleBgBG),
LocaleZhCN: createCommonFormatFunc(LocaleZhCN),
LocaleZhTW: createCommonFormatFunc(LocaleZhTW),
LocaleZhHK: createCommonFormatFunc(LocaleZhHK),
LocaleKoKR: createCommonFormatFunc(LocaleKoKR),
LocaleJaJP: createCommonFormatFunc(LocaleJaJP),
LocaleElGR: createCommonFormatFuncWithGenitive(LocaleElGR),
LocaleIdID: createCommonFormatFunc(LocaleIdID),
LocaleCsCZ: createCommonFormatFunc(LocaleCsCZ),
LocaleSlSI: createCommonFormatFunc(LocaleSlSI),
}
// internalParseFunc is a preprocessor for default time.ParseInLocation func
type internalParseFunc func(layout, value string) string
var internalParseFuncs = map[Locale]internalParseFunc{
LocaleEnUS: createCommonParseFunc(LocaleEnUS),
LocaleEnGB: createCommonParseFunc(LocaleEnGB),
LocaleDaDK: createCommonParseFunc(LocaleDaDK),
LocaleNlBE: createCommonParseFunc(LocaleNlBE),
LocaleNlNL: createCommonParseFunc(LocaleNlNL),
LocaleFrFR: createCommonParseFunc(LocaleFrFR),
LocaleFrCA: createCommonParseFunc(LocaleFrFR),
LocaleFrGP: createCommonParseFunc(LocaleFrFR),
LocaleFrLU: createCommonParseFunc(LocaleFrFR),
LocaleFrMQ: createCommonParseFunc(LocaleFrFR),
LocaleFrGF: createCommonParseFunc(LocaleFrFR),
LocaleFrRE: createCommonParseFunc(LocaleFrFR),
LocaleRuRU: createCommonParsetFuncWithGenitive(LocaleRuRU),
LocaleFiFI: createCommonParsetFuncWithGenitive(LocaleFiFI),
LocaleDeDE: createCommonParseFunc(LocaleDeDE),
LocaleHuHU: createCommonParseFunc(LocaleHuHU),
LocaleItIT: createCommonParseFunc(LocaleItIT),
LocaleNnNO: createCommonParseFunc(LocaleNnNO),
LocaleNbNO: createCommonParseFunc(LocaleNbNO),
LocalePlPL: parseFuncPtCommon(LocalePlPL),
LocalePtPT: parseFuncPtCommon(LocalePtPT),
LocalePtBR: parseFuncPtCommon(LocalePtBR),
LocaleRoRO: createCommonParseFunc(LocaleRoRO),
LocaleEsES: createCommonParseFunc(LocaleEsES),
LocaleCaES: createCommonParseFunc(LocaleCaES),
LocaleSvSE: createCommonParseFunc(LocaleSvSE),
LocaleTrTR: createCommonParseFunc(LocaleTrTR),
LocaleUkUA: createCommonParsetFuncWithGenitive(LocaleUkUA),
LocaleBgBG: createCommonParseFunc(LocaleBgBG),
LocaleZhCN: parseFuncZhCommon(LocaleZhCN),
LocaleZhTW: parseFuncZhCommon(LocaleZhTW),
LocaleZhHK: parseFuncZhCommon(LocaleZhHK),
LocaleKoKR: parseFuncKoCommon(LocaleKoKR),
LocaleJaJP: parseFuncJaCommon(LocaleJaJP),
LocaleElGR: createCommonParsetFuncWithGenitive(LocaleElGR),
LocaleIdID: createCommonParseFunc(LocaleIdID),
LocaleCsCZ: createCommonParseFunc(LocaleCsCZ),
LocaleSlSI: createCommonParseFunc(LocaleSlSI),
}
var knownDaysShort = map[Locale]map[string]string{} // Mapping for 'Format', days of week, short form
var knownDaysLong = map[Locale]map[string]string{} // Mapping for 'Format', days of week, long form
var knownMonthsLong = map[Locale]map[string]string{} // Mapping for 'Format', months: long form
var knownMonthsShort = map[Locale]map[string]string{} // Mapping for 'Format', months: short form
var knownMonthsGenitiveShort = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, short form
var knownMonthsGenitiveLong = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, long form
var knownPeriods = map[Locale]map[string]string{} // Mapping for 'Format', AM/PM
// Reverse maps for the same
var knownDaysShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', days of week, short form
var knownDaysLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', days of week, long form
var knownMonthsLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', months: long form
var knownMonthsShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', months: short form
var knownMonthsGenitiveShortReverse = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, short form
var knownMonthsGenitiveLongReverse = map[Locale]map[string]string{} // Mapping for 'Format', special for names in genitive, long form
var knownPeriodsReverse = map[Locale]map[string]string{} // Mapping for 'Format', AM/PM
func init() {
fillKnownWords()
}
func fillKnownWords() {
// En_US: English (United States)
fillKnownDaysLong(longDayNamesEnUS, LocaleEnUS)
fillKnownDaysShort(shortDayNamesEnUS, LocaleEnUS)
fillKnownMonthsLong(longMonthNamesEnUS, LocaleEnUS)
fillKnownMonthsShort(shortMonthNamesEnUS, LocaleEnUS)
// En_GB: English (United Kingdom)
fillKnownDaysLong(longDayNamesEnUS, LocaleEnGB)
fillKnownDaysShort(shortDayNamesEnUS, LocaleEnGB)
fillKnownMonthsLong(longMonthNamesEnUS, LocaleEnGB)
fillKnownMonthsShort(shortMonthNamesEnUS, LocaleEnGB)
// Da_DK: Danish (Denmark)
fillKnownDaysLong(longDayNamesDaDK, LocaleDaDK)
fillKnownDaysShort(shortDayNamesDaDK, LocaleDaDK)
fillKnownMonthsLong(longMonthNamesDaDK, LocaleDaDK)
fillKnownMonthsShort(shortMonthNamesDaDK, LocaleDaDK)
// Nl_BE: Dutch (Belgium)
fillKnownDaysLong(longDayNamesNlBE, LocaleNlBE)
fillKnownDaysShort(shortDayNamesNlBE, LocaleNlBE)
fillKnownMonthsLong(longMonthNamesNlBE, LocaleNlBE)
fillKnownMonthsShort(shortMonthNamesNlBE, LocaleNlBE)
// Nl_NL: Dutch (Netherlands)
fillKnownDaysLong(longDayNamesNlBE, LocaleNlNL)
fillKnownDaysShort(shortDayNamesNlBE, LocaleNlNL)
fillKnownMonthsLong(longMonthNamesNlBE, LocaleNlNL)
fillKnownMonthsShort(shortMonthNamesNlBE, LocaleNlNL)
// Fi_FI: Finnish (Finland)
fillKnownDaysLong(longDayNamesFiFI, LocaleFiFI)
fillKnownDaysShort(shortDayNamesFiFI, LocaleFiFI)
fillKnownMonthsLong(longMonthNamesFiFI, LocaleFiFI)
fillKnownMonthsShort(shortMonthNamesFiFI, LocaleFiFI)
fillKnownMonthsGenitiveLong(longMonthNamesGenitiveFiFI, LocaleFiFI)
fillKnownMonthsGenitiveShort(shortMonthNamesFiFI, LocaleFiFI)
// Fr_FR: French (France)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrFR)
fillKnownDaysShort(shortDayNamesFrFR, LocaleFrFR)
fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrFR)
fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrFR)
// Fr_CA: French (Canada)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrCA)
fillKnownDaysShort(shortDayNamesFrFR, LocaleFrCA)
fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrCA)
fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrCA)
// Fr_GP: French (Guadeloupe)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrGP)
fillKnownDaysShort(shortDayNamesFrFR, LocaleFrGP)
fillKnownMonthsLong(longMonthNamesFrFR, LocaleFrGP)
fillKnownMonthsShort(shortMonthNamesFrFR, LocaleFrGP)
// Fr_LU: French (Luxembourg)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrLU)
fillKnownDaysShort(longDayNamesFrFR, LocaleFrLU)
fillKnownMonthsLong(longDayNamesFrFR, LocaleFrLU)
fillKnownMonthsShort(longDayNamesFrFR, LocaleFrLU)
// Fr_MQ: French (Martinique)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrMQ)
fillKnownDaysShort(longDayNamesFrFR, LocaleFrMQ)
fillKnownMonthsLong(longDayNamesFrFR, LocaleFrMQ)
fillKnownMonthsShort(longDayNamesFrFR, LocaleFrMQ)
// Fr_GF: French (French Guiana)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrGF)
fillKnownDaysShort(longDayNamesFrFR, LocaleFrGF)
fillKnownMonthsLong(longDayNamesFrFR, LocaleFrGF)
fillKnownMonthsShort(longDayNamesFrFR, LocaleFrGF)
// Fr_RE: French (French Reunion)
fillKnownDaysLong(longDayNamesFrFR, LocaleFrRE)
fillKnownDaysShort(longDayNamesFrFR, LocaleFrRE)
fillKnownMonthsLong(longDayNamesFrFR, LocaleFrRE)
fillKnownMonthsShort(longDayNamesFrFR, LocaleFrRE)
// De_DE: German (Germany)
fillKnownDaysLong(longDayNamesDeDE, LocaleDeDE)
fillKnownDaysShort(shortDayNamesDeDE, LocaleDeDE)
fillKnownMonthsLong(longMonthNamesDeDE, LocaleDeDE)
fillKnownMonthsShort(shortMonthNamesDeDE, LocaleDeDE)
// Hu_HU: Hungarian (Hungary)
fillKnownDaysLong(longDayNamesHuHU, LocaleHuHU)
fillKnownDaysShort(shortDayNamesHuHU, LocaleHuHU)
fillKnownMonthsLong(longMonthNamesHuHU, LocaleHuHU)
fillKnownMonthsShort(shortMonthNamesHuHU, LocaleHuHU)
// It_IT: Italian (Italy)
fillKnownDaysLong(longDayNamesItIT, LocaleItIT)
fillKnownDaysShort(shortDayNamesItIT, LocaleItIT)
fillKnownMonthsLong(longMonthNamesItIT, LocaleItIT)
fillKnownMonthsShort(shortMonthNamesItIT, LocaleItIT)
// Nn_NO: Norwegian Nynorsk (Norway)
fillKnownDaysLong(longDayNamesNnNO, LocaleNnNO)
fillKnownDaysShort(shortDayNamesNnNO, LocaleNnNO)
fillKnownMonthsLong(longMonthNamesNnNO, LocaleNnNO)
fillKnownMonthsShort(shortMonthNamesNnNO, LocaleNnNO)
// Nb_NO: Norwegian Bokmål (Norway)
fillKnownDaysLong(longDayNamesNbNO, LocaleNbNO)
fillKnownDaysShort(shortDayNamesNbNO, LocaleNbNO)
fillKnownMonthsLong(longMonthNamesNbNO, LocaleNbNO)
fillKnownMonthsShort(shortMonthNamesNbNO, LocaleNbNO)
// Pl_PL: Polish (Poland)
fillKnownDaysLong(longDayNamesPlPL, LocalePlPL)
fillKnownDaysShort(shortDayNamesPlPL, LocalePlPL)
fillKnownMonthsLong(longMonthNamesPlPL, LocalePlPL)
fillKnownMonthsShort(shortMonthNamesPlPL, LocalePlPL)
// Pt_PT: Portuguese (Portugal)
fillKnownDaysLong(longDayNamesPtPT, LocalePtPT)
fillKnownDaysShort(shortDayNamesPtPT, LocalePtPT)
fillKnownMonthsLong(longMonthNamesPtPT, LocalePtPT)
fillKnownMonthsShort(shortMonthNamesPtPT, LocalePtPT)
// Pt_BR: Portuguese (Brazil)
fillKnownDaysLong(longDayNamesPtBR, LocalePtBR)
fillKnownDaysShort(shortDayNamesPtBR, LocalePtBR)
fillKnownMonthsLong(longMonthNamesPtBR, LocalePtBR)
fillKnownMonthsShort(shortMonthNamesPtBR, LocalePtBR)
// Ro_RO: Romanian (Romania)
fillKnownDaysLong(longDayNamesRoRO, LocaleRoRO)
fillKnownDaysShort(shortDayNamesRoRO, LocaleRoRO)
fillKnownMonthsLong(longMonthNamesRoRO, LocaleRoRO)
fillKnownMonthsShort(shortMonthNamesRoRO, LocaleRoRO)
// Ru_RU: Russian (Russia)
fillKnownDaysLong(longDayNamesRuRU, LocaleRuRU)
fillKnownDaysShort(shortDayNamesRuRU, LocaleRuRU)
fillKnownMonthsLong(longMonthNamesRuRU, LocaleRuRU)
fillKnownMonthsShort(shortMonthNamesRuRU, LocaleRuRU)
fillKnownMonthsGenitiveLong(longMonthNamesGenitiveRuRU, LocaleRuRU)
fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveRuRU, LocaleRuRU)
// Es_ES: Spanish (Spain)
fillKnownDaysLong(longDayNamesEsES, LocaleEsES)
fillKnownDaysShort(shortDayNamesEsES, LocaleEsES)
fillKnownMonthsLong(longMonthNamesEsES, LocaleEsES)
fillKnownMonthsShort(shortMonthNamesEsES, LocaleEsES)
// Ca_ES: Catalan (Spain)
fillKnownDaysLong(longDayNamesCaES, LocaleCaES)
fillKnownDaysShort(shortDayNamesCaES, LocaleCaES)
fillKnownMonthsLong(longMonthNamesCaES, LocaleCaES)
fillKnownMonthsShort(shortMonthNamesCaES, LocaleCaES)
// Sv_SE: Swedish (Sweden)
fillKnownDaysLong(longDayNamesSvSE, LocaleSvSE)
fillKnownDaysShort(shortDayNamesSvSE, LocaleSvSE)
fillKnownMonthsLong(longMonthNamesSvSE, LocaleSvSE)
fillKnownMonthsShort(shortMonthNamesSvSE, LocaleSvSE)
// Tr_TR: Turkish (Turkey)
fillKnownDaysLong(longDayNamesTrTR, LocaleTrTR)
fillKnownDaysShort(shortDayNamesTrTR, LocaleTrTR)
fillKnownMonthsLong(longMonthNamesTrTR, LocaleTrTR)
fillKnownMonthsShort(shortMonthNamesTrTR, LocaleTrTR)
// Uk_UA: Ukrainian (Ukraine)
fillKnownDaysLong(longDayNamesUkUA, LocaleUkUA)
fillKnownDaysShort(shortDayNamesUkUA, LocaleUkUA)
fillKnownMonthsLong(longMonthNamesUkUA, LocaleUkUA)
fillKnownMonthsShort(shortMonthNamesUkUA, LocaleUkUA)
fillKnownMonthsGenitiveLong(longMonthNamesGenitiveUkUA, LocaleUkUA)
fillKnownMonthsGenitiveShort(shortMonthNamesGenitiveUkUA, LocaleUkUA)
// Bg_BG: Bulgarian (Bulgaria)
fillKnownDaysLong(longDayNamesBgBG, LocaleBgBG)
fillKnownDaysShort(shortDayNamesBgBG, LocaleBgBG)
fillKnownMonthsLong(longMonthNamesBgBG, LocaleBgBG)
fillKnownMonthsShort(shortMonthNamesBgBG, LocaleBgBG)
// Zh_CN: Chinese (Mainland)
fillKnownDaysLong(longDayNamesZhCN, LocaleZhCN)
fillKnownDaysShort(shortDayNamesZhCN, LocaleZhCN)
fillKnownMonthsLong(longMonthNamesZhCN, LocaleZhCN)
fillKnownMonthsShort(shortMonthNamesZhCN, LocaleZhCN)
// Zh_TW: Chinese (Taiwan)
fillKnownDaysLong(longDayNamesZhTW, LocaleZhTW)
fillKnownDaysShort(shortDayNamesZhTW, LocaleZhTW)
fillKnownMonthsLong(longMonthNamesZhTW, LocaleZhTW)
fillKnownMonthsShort(shortMonthNamesZhTW, LocaleZhTW)
// Zh_HK: Chinese (Hong Kong)
fillKnownDaysLong(longDayNamesZhHK, LocaleZhHK)
fillKnownDaysShort(shortDayNamesZhHK, LocaleZhHK)
fillKnownMonthsLong(longMonthNamesZhHK, LocaleZhHK)
fillKnownMonthsShort(shortMonthNamesZhHK, LocaleZhHK)
// Ko_KR: Korean (Korea)
fillKnownDaysLong(longDayNamesKoKR, LocaleKoKR)
fillKnownDaysShort(shortDayNamesKoKR, LocaleKoKR)
fillKnownMonthsLong(longMonthNamesKoKR, LocaleKoKR)
fillKnownMonthsShort(shortMonthNamesKoKR, LocaleKoKR)
fillKnownPeriods(periodsKoKR, LocaleKoKR)
// Ja_JP: Japanese (Japan)
fillKnownDaysLong(longDayNamesJaJP, LocaleJaJP)
fillKnownDaysShort(shortDayNamesJaJP, LocaleJaJP)
fillKnownMonthsLong(longMonthNamesJaJP, LocaleJaJP)
fillKnownMonthsShort(shortMonthNamesJaJP, LocaleJaJP)
fillKnownPeriods(periodsJaJP, LocaleJaJP)
// El_GR: Greek (Greece)
fillKnownDaysLong(longDayNamesElGR, LocaleElGR)
fillKnownDaysShort(shortDayNamesElGR, LocaleElGR)
fillKnownMonthsLong(longMonthNamesElGR, LocaleElGR)
fillKnownMonthsShort(shortMonthNamesElGR, LocaleElGR)
fillKnownMonthsGenitiveLong(longMonthNamesGenitiveElGR, LocaleElGR)
fillKnownMonthsGenitiveShort(shortMonthNamesElGR, LocaleElGR)
fillKnownPeriods(periodsElGR, LocaleElGR)
// Id_ID: Indonesia (Indonesia)
fillKnownDaysLong(longDayNamesIdID, LocaleIdID)
fillKnownDaysShort(shortDayNamesIdID, LocaleIdID)
fillKnownMonthsLong(longMonthNamesIdID, LocaleIdID)
fillKnownMonthsShort(shortMonthNamesIdID, LocaleIdID)
// Cs_CZ: Czech (Czech Republic)
fillKnownDaysLong(longDayNamesCsCZ, LocaleCsCZ)
fillKnownDaysShort(shortDayNamesCsCZ, LocaleCsCZ)
fillKnownMonthsLong(longMonthNamesCsCZ, LocaleCsCZ)
fillKnownMonthsShort(shortMonthNamesCsCZ, LocaleCsCZ)
// Sl_SI: Slovenian (Slovenia)
fillKnownDaysLong(longDayNamesSlSI, LocaleSlSI)
fillKnownDaysShort(shortDayNamesSlSI, LocaleSlSI)
fillKnownMonthsLong(longMonthNamesSlSI, LocaleSlSI)
fillKnownMonthsShort(shortMonthNamesSlSI, LocaleSlSI)
}
func fill(src map[string]string, dest map[Locale]map[string]string, locale Locale) {
loc, ok := dest[locale]
if !ok {
loc = make(map[string]string, len(src))
dest[locale] = loc
}
for k, v := range src {
loc[k] = v
}
}
func fillReverse(src map[string]string, dest map[Locale]map[string]string, locale Locale) {
loc, ok := dest[locale]
if !ok {
loc = make(map[string]string, len(src))
dest[locale] = loc
}
for k, v := range src {
loc[v] = k
}
}
func fillKnownMonthsGenitiveShort(src map[string]string, locale Locale) {
fillReverse(src, knownMonthsGenitiveShortReverse, locale)
fill(src, knownMonthsGenitiveShort, locale)
}
func fillKnownMonthsGenitiveLong(src map[string]string, locale Locale) {
fillReverse(src, knownMonthsGenitiveLongReverse, locale)
fill(src, knownMonthsGenitiveLong, locale)
}
func fillKnownDaysShort(src map[string]string, locale Locale) {
fillReverse(src, knownDaysShortReverse, locale)
fill(src, knownDaysShort, locale)
}
func fillKnownDaysLong(src map[string]string, locale Locale) {
fillReverse(src, knownDaysLongReverse, locale)
fill(src, knownDaysLong, locale)
}
func fillKnownMonthsShort(src map[string]string, locale Locale) {
fillReverse(src, knownMonthsShortReverse, locale)
fill(src, knownMonthsShort, locale)
}
func fillKnownMonthsLong(src map[string]string, locale Locale) {
fillReverse(src, knownMonthsLongReverse, locale)
fill(src, knownMonthsLong, locale)
}
func fillKnownPeriods(src map[string]string, locale Locale) {
fillReverse(src, knownPeriodsReverse, locale)
fill(src, knownPeriods, locale)
}
// Format is the standard time.Format wrapper, that replaces known standard 'time' package
// identifiers for months and days to their equivalents in the specified language.
//
// Values of variables 'longDayNames', 'shortDayNames', 'longMonthNames', 'shortMonthNames'
// from file 'time/format.go' (revision 'go1') are chosen as the 'known' words.
//
// Some languages have specific behavior, e.g. in Russian language
// month names have different suffix when they are presented stand-alone (i.e. in a list or something)
// and yet another one when they are part of a formatted date.
// So, even though March is "Март" in Russian, correctly formatted today's date would be: "7 марта 2007".
// Thus, some transformations for some languages may be a bit more complex than just plain replacements.
func Format(dt time.Time, layout string, locale Locale) string {
fm := dt.Format(layout)
intFunc, ok := internalFormatFuncs[locale]
if !ok {
return fm
}
return intFunc(fm, layout)
}
// ParseInLocation is the standard time.ParseInLocation wrapper, which replaces
// known month/day translations for a specified locale back to English before
// calling time.ParseInLocation. So, you can parse localized dates with this wrapper.
func ParseInLocation(layout, value string, loc *time.Location, locale Locale) (time.Time, error) {
intFunc, ok := internalParseFuncs[locale]
if ok {
value = intFunc(layout, value)
} else {
return time.Now(), fmt.Errorf("unsupported locale: %v", locale)
}
return time.ParseInLocation(layout, value, loc)
}
// Parse is the standard time.Parse wrapper, which replaces
// known month/day translations for a specified locale back to English before
// calling time.Parse.
func Parse(layout, value string, locale Locale) (time.Time, error) {
intFunc, ok := internalParseFuncs[locale]
if ok {
value = intFunc(layout, value)
} else {
return time.Now(), fmt.Errorf("unsupported locale: %v", locale)
}
return time.Parse(layout, value)
}
// GetShortDays retrieves the list of days for the given locale.
// "Short" days are abbreviated versions of the full day names. In English,
// for example, this might return "Tues" for "Tuesday". For certain locales,
// the long and short form of the days of the week may be the same.
//
// If the locale cannot be found, the resulting slice will be nil.
func GetShortDays(locale Locale) []string {
days, ok := knownDaysShort[locale]
if !ok {
return nil
}
var dayOrder []string
// according to https://www.timeanddate.com/calendar/days/monday.html
// only Canada, USA and Japan use Sunday as first day of the week
switch locale {
case LocaleEnUS, LocaleJaJP:
dayOrder = dayShortOrderSundayFirst
default:
dayOrder = dayShortOrderMondayFirst
}
ret := make([]string, 0, len(days))
for _, day := range dayOrder {
ret = append(ret, days[day])
}
return ret
}
// GetShortMonths retrieves the list of months for the given locale.
// "Short" months are abbreviated versions of the full month names. In
// English, for example, this might return "Jan" for "January". For
// certain locales, the long and short form of the months may be the same.
//
// If the locale cannot be found, the resulting slice will be nil.
func GetShortMonths(locale Locale) []string {
months, ok := knownMonthsShort[locale]
if !ok {
return nil
}
ret := make([]string, 0, len(months))
for _, m := range monthShortOrder {
ret = append(ret, months[m])
}
return ret
}
// GetLongDays retrieves the list of days for the given locale. It will return
// the full name of the days of the week.
//
// If the locale cannot be found, the resulting slice will be nil.
func GetLongDays(locale Locale) []string {
days, ok := knownDaysLong[locale]
if !ok {
return nil
}
var dayOrder []string
// according to https://www.timeanddate.com/calendar/days/monday.html
// only Canada, USA and Japan use Sunday as first day of the week
switch locale {
case LocaleEnUS, LocaleJaJP:
dayOrder = dayLongOrderSundayFirst
default:
dayOrder = dayLongOrderMondayFirst
}
ret := make([]string, 0, len(days))
for _, day := range dayOrder {
ret = append(ret, days[day])
}
return ret
}
// GetLongMonths retrieves the list of months for the given locale. In
// contrast to the "short" version of this function, this functions returns
// the full name of the month.
//
// If the locale cannot be found, the resulting slice will be nil.
func GetLongMonths(locale Locale) []string {
months, ok := knownMonthsLong[locale]
if !ok {
return nil
}
ret := make([]string, 0, len(months))
for _, m := range monthLongOrder {
ret = append(ret, months[m])
}
return ret
}

@ -0,0 +1,67 @@
package monday
import "sync"
var keyExists = struct{}{}
// Set is a thread safe set data structure.
//
// It is ported from https://github.com/fatih/set with only the required functionality.
type set struct {
m map[Locale]struct{}
l sync.RWMutex
}
// NewSet allocates and returns a new Set. It accepts a variable number of
// arguments to populate the initial set. If nothing is passed a Set with zero
// size is created.
func newSet(items ...Locale) *set {
s := set{
m: make(map[Locale]struct{}),
}
s.Add(items...)
return &s
}
// Add adds the specified items (one or more) to the set. The underlying
// Set s is modified. If no items are passed it silently returns.
func (s *set) Add(items ...Locale) {
if len(items) == 0 {
return
}
s.l.Lock()
defer s.l.Unlock()
for _, item := range items {
s.m[item] = keyExists
}
}
// Each traverses the items in the Set, calling the provided function f for
// each set member. Traversal will continue until all items in the Set have
// been visited, or if the closure returns false.
func (s *set) Each(f func(item Locale) bool) {
s.l.RLock()
defer s.l.RUnlock()
for item := range s.m {
if !f(item) {
break
}
}
}
// Has looks for the existence of items passed. It returns false if nothing is
// passed. For multiple items it returns true only if all of the items exist.
func (s *set) Has(items ...Locale) bool {
if len(items) == 0 {
return false
}
s.l.RLock()
defer s.l.RUnlock()
has := true
for _, item := range items {
if _, has = s.m[item]; !has {
break
}
}
return has
}

@ -0,0 +1,92 @@
package monday
import (
"strings"
"unicode"
"unicode/utf8"
)
// dateStringLayoutItem represents one word or set of delimiters between words.
// This is an abstraction level above date raw character string of date representation.
//
// Example: "1 February / 2013" ->
// dateStringLayoutItem { item: "1", isWord: true }
// dateStringLayoutItem { item: " ", isWord: false }
// dateStringLayoutItem { item: "February", isWord: true }
// dateStringLayoutItem { item: " / ", isWord: false }
// dateStringLayoutItem { item: "2013", isWord: true }
type dateStringLayoutItem struct {
item string
isWord bool // true if this is a sequence of letters/digits (as opposed to a sequence of non-letters like delimiters)
isDigit bool // true if this is a sequence only containing digits
}
// extractLetterSequence extracts first word (sequence of letters ending with a non-letter)
// starting with the specified index and wraps it to dateStringLayoutItem according to the type
// of the word.
func extractLetterSequence(originalStr string, index int) (it dateStringLayoutItem) {
letters := &strings.Builder{}
bytesToParse := []byte(originalStr[index:])
runeCount := utf8.RuneCount(bytesToParse)
var isWord bool
var isDigit bool
letters.Grow(runeCount)
for i := 0; i < runeCount; i++ {
rne, runeSize := utf8.DecodeRune(bytesToParse)
bytesToParse = bytesToParse[runeSize:]
if i == 0 {
isWord = unicode.IsLetter(rne)
isDigit = unicode.IsDigit(rne)
} else {
if (isWord && (!unicode.IsLetter(rne) && !unicode.IsDigit(rne))) ||
(isDigit && !unicode.IsDigit(rne)) ||
(!isWord && unicode.IsLetter(rne)) ||
(!isDigit && unicode.IsDigit(rne)) {
break
}
}
letters.WriteRune(rne)
}
it.item = letters.String()
it.isWord = isWord
it.isDigit = isDigit
return
}
// stringToLayoutItems transforms raw date string (like "2 Mar 2012") into
// a set of dateStringLayoutItems, which are more convenient to work with
// in other analysis modules.
func stringToLayoutItems(dateStr string) (seqs []dateStringLayoutItem) {
i := 0
for i < len(dateStr) {
seq := extractLetterSequence(dateStr, i)
i += len(seq.item)
seqs = append(seqs, seq)
}
return
}
func layoutToString(li []dateStringLayoutItem) string {
// This function is expensive enough to be worth counting
// bytes and allocating all in one go.
numChars := 0
for _, v := range li {
numChars += len(v.item)
}
sb := &strings.Builder{}
sb.Grow(numChars)
for _, v := range li {
sb.WriteString(v.item)
}
return sb.String()
}

@ -41,6 +41,9 @@ github.com/go-toast/toast
# github.com/godbus/dbus/v5 v5.0.4
## explicit; go 1.12
github.com/godbus/dbus/v5
# github.com/goodsign/monday v1.0.0
## explicit; go 1.13
github.com/goodsign/monday
# github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1
## explicit
github.com/gopherjs/gopherjs/js

Loading…
Cancel
Save