Skip to content

Commit

Permalink
Add tables generator and initial parsing methods (#4)
Browse files Browse the repository at this point in the history
This commit introduced the initial lunes parsing functionality, including a generator to read and create the default CLDR locales data.
  • Loading branch information
edmocosta authored Jul 24, 2024
1 parent c5eb4d7 commit 99160b4
Show file tree
Hide file tree
Showing 16 changed files with 12,551 additions and 130 deletions.
114 changes: 22 additions & 92 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ Third party libraries used by the Lunes Libraries:

--------------------------------------------------------------------------------
Dependency : github.com/elastic/go-licenser
Version: v0.4.1
Version: v0.4.2
Licence type (autodetected): Apache-2.0
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/elastic/[email protected].1/LICENSE:
Contents of probable licence file $GOMODCACHE/github.com/elastic/[email protected].2/LICENSE:


Apache License
Expand Down Expand Up @@ -434,11 +434,11 @@ Contents of probable licence file $GOMODCACHE/github.com/magefile/[email protected]/L

--------------------------------------------------------------------------------
Dependency : go.elastic.co/go-licence-detector
Version: v0.6.0
Version: v0.6.1
Licence type (autodetected): Apache-2.0
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/go.elastic.co/[email protected].0/LICENSE:
Contents of probable licence file $GOMODCACHE/go.elastic.co/[email protected].1/LICENSE:


Apache License
Expand Down Expand Up @@ -677,11 +677,11 @@ THE SOFTWARE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/tools
Version: v0.22.0
Version: v0.23.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/tools@v0.22.0/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/tools@v0.23.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -720,11 +720,11 @@ Indirect dependencies

--------------------------------------------------------------------------------
Dependency : github.com/cyphar/filepath-securejoin
Version: v0.2.2
Version: v0.2.5
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/cyphar/[email protected].2/LICENSE:
Contents of probable licence file $GOMODCACHE/github.com/cyphar/[email protected].5/LICENSE:

Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
Copyright (C) 2017 SUSE LLC. All rights reserved.
Expand Down Expand Up @@ -1220,39 +1220,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


--------------------------------------------------------------------------------
Dependency : github.com/pkg/errors
Version: v0.8.1
Licence type (autodetected): BSD-2-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/pkg/[email protected]/LICENSE:

Copyright (c) 2015, Dave Cheney <[email protected]>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

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.


--------------------------------------------------------------------------------
Dependency : github.com/pmezard/go-difflib
Version: v1.0.0
Expand Down Expand Up @@ -1416,11 +1383,11 @@ SOFTWARE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/crypto
Version: v0.0.0-20191011191535-87dc89f01550
Version: v0.13.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.0.0-20191011191535-87dc89f01550/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.13.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1451,50 +1418,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


--------------------------------------------------------------------------------
Dependency : golang.org/x/lint
Version: v0.0.0-20210508222113-6edffad5e616
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/[email protected]/LICENSE:

Copyright (c) 2013 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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
OWNER 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.


--------------------------------------------------------------------------------
Dependency : golang.org/x/mod
Version: v0.18.0
Version: v0.19.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/mod@v0.18.0/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/mod@v0.19.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1527,11 +1457,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/net
Version: v0.26.0
Version: v0.27.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/net@v0.26.0/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/net@v0.27.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1601,11 +1531,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/sys
Version: v0.21.0
Version: v0.22.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.21.0/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.22.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1675,11 +1605,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/term
Version: v0.0.0-20201126162022-7de9c90e9dd1
Version: v0.12.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.0.0-20201126162022-7de9c90e9dd1/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.12.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1712,11 +1642,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/text
Version: v0.3.6
Version: v0.13.0
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/text@v0.3.6/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/text@v0.13.0/LICENSE:

Copyright (c) 2009 The Go Authors. All rights reserved.

Expand Down Expand Up @@ -1749,11 +1679,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

--------------------------------------------------------------------------------
Dependency : golang.org/x/xerrors
Version: v0.0.0-20200804184101-5ec99f83aff1
Version: v0.0.0-20190717185122-a985d3407aa7
Licence type (autodetected): BSD-3-Clause
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/golang.org/x/[email protected]20200804184101-5ec99f83aff1/LICENSE:
Contents of probable licence file $GOMODCACHE/golang.org/x/[email protected]20190717185122-a985d3407aa7/LICENSE:

Copyright (c) 2019 The Go Authors. All rights reserved.

Expand Down
141 changes: 141 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,144 @@
# Lunes

---

**Lunes** is a [Go](http://golang.org) library for parsing localized time strings into `time.Time`.

There's no intention to replace the standard `time` package parsing functions, instead, it acts as wrapper
translating the provided value to English before invoking the `time.Parse` and `time.ParseInLocation`.

It currently supports almost all [CLDR](https://cldr.unicode.org/) core locales (+900 including drafts),
being limited to the **gregorian** calendars.

Once the official Go i18n features for time parsing are ready, it should be replaced.

## Usage

#### Parse

```go
// it's like time.Parse, but with an additional locale parameter to perform the value translation.
// the language argument must be a well-formed BCP 47 language tag, e.g ("en", "en-US") and
// a known locale. If no data is found for the language, it returns ErrUnsupportedLocale.
// If the given locale does not support any layout element specified on the layout argument,
// it results in an ErrUnsupportedLayoutElem error. On the other hand, if the value does not
// match the layout, an ErrLayoutMismatch is returned.
t, err := lunes.Parse("Monday Jan _2 2006 15:04:05", "lunes oct 27 1988 11:53:29", lunes.LocaleEsES)

// parse in specific time zones.
t, err := lunes.ParseInLocation("Monday Jan _2 2006 15:04:05", "lunes oct 27 1988 11:53:29", time.UTC, lunes.LocaleEsES)
```

```go
// creates a new generic locale for the given BCP 47 language tag, using the default CLDR
// gregorian calendars data of the specified language. If the locale is unknown and/or no
// default data is found, it returns ErrUnsupportedLocale.
locale, err := lunes.NewDefaultLocale(lunes.LocaleEsES)

// ParseWithLocale has a better performance for multiple parse operations, as it does not
// need to look up the locale data in each iteration.
for _, val := range valuesToParse {
t, err := lunes.ParseWithLocale("Monday Jan _2 2006 15:04:05", val, locale)
}
```

#### Translate

```go
// translates the value, without parsing it to time.Time. The language argument must be a
// well-formed BCP 47 language tag, e.g ("en", "en-US") and a known locale. If no data is
// found for the language, it returns ErrUnsupportedLocale.
// If the given locale does not support any layout element specified on the layout argument,
// it results in an ErrUnsupportedLayoutElem error. On the other hand, if the values does not
// match the layout, an ErrLayoutMismatch is returned.
// For the following example, it results in: Friday Jan 27 11:53:29.
str, err := lunes.Translate("Monday Jan _2 15:04:05", "viernes ene 27 11:53:29", lunes.LocaleEsES)

// the translated value is meant to be used with the time package functions
t, err := time.Parse("Monday Jan _2 15:04:05", str)
```

#### Custom Locales

A `lunes.Locale` provides a collection of time layouts values in a specific language.
It is used to provide a map between the time layout elements in foreign language to English.
In oder to use custom locales, the following functions must be implemented:

```go
// Language represents a BCP 47 tag, specifying this locale language.
Language() string

// LongDayNames returns the long day names translations for the week days.
// It must be sorted, starting from Sunday to Saturday, and contains all 7 elements,
// even if one or more days are empty. If this locale does not support this format,
// it should return an empty slice.
LongDayNames() []string

// ShortDayNames returns the short day names translations for the week days.
// It must be sorted, starting from Sunday to Saturday, and contains all 7 elements,
// even if one or more days are empty. If this locale does not support this format,
// it should return an empty slice.
ShortDayNames() []string

// LongMonthNames returns the long day names translations for the months names.
// It must be sorted, starting from January to December, and contains all 12 elements,
// even if one or more months are empty. If this locale does not support this format,
// it should return an empty slice.
LongMonthNames() []string

// ShortMonthNames returns the short day names translations for the months names.
// It must be sorted, starting from January to December, and contains all 12 elements,
// even if one or more months are empty. If this locale does not support this format,
// it should return an empty slice.
ShortMonthNames() []string

// DayPeriods returns the periods of day translations for the AM and PM abbreviations.
// It must be sorted, starting from AM to PM, and contains both elements, even if one
// of them is empty. If this locale does not support this format, it should return an
// empty slice.
DayPeriods() []string
```

Custom locales can be used with the `lunes.ParseWithLocale`, `lunes.ParseInLocationWithLocale`, and `lunes.TranslateWithLocale`
functions:

```go
locale := &CustomLocale{}

// It's like Parse, but instead of receiving a BCP 47 language tag argument, it receives a lunes.Locale
t, err := lunes.ParseWithLocale("Monday Jan _2 2006 15:04:05", "lunes oct 27 1988 11:53:29", locale)

// It's like ParseInLocation, but instead of receiving a BCP 47 language tag argument, it receives a lunes.Locale
t, err := lunes.ParseInLocationWithLocale("Monday Jan _2 2006 15:04:05", "lunes oct 27 1988 11:53:29", time.UTC, locale)

// It's like Translate, but instead of receiving a BCP 47 language tag argument, it receives a lunes.Locale
t, err := lunes.TranslateWithLocale("Monday Jan _2 2006 15:04:05", "lunes oct 27 1988 11:53:29", locale)
```

## Benchmarks

Comparing to [github.com/goodsign/monday](https://github.com/goodsign/monday)

```
BenchmarkTranslate-10 3850832 303.2 ns/op 220 B/op 5 allocs/op
BenchmarkTranslateWithLocale-10 5149981 235.1 ns/op 76 B/op 4 allocs/op
BenchmarkParse-10 2811612 428.1 ns/op 220 B/op 5 allocs/op
BenchmarkParseInLocation-10 2792997 439.2 ns/op 220 B/op 5 allocs/op
BenchmarkParseWithLocale-10 3268903 362.7 ns/op 76 B/op 4 allocs/op
BenchmarkParseInLocationWithLocale-10 2974732 390.2 ns/op 76 B/op 4 allocs/op
BenchmarkParseMonday-10 213014 5584 ns/op 3754 B/op 117 allocs/op
BenchmarkParseInLocationMonday-10 211826 5593 ns/op 3754 B/op 117 allocs/op
```

### Usage notes

- It currently supports the following time layout replacements:
- Short days names (`Mon`)
- Long days names (`Monday`)
- Short month names (`Jan`)
- Long month names (`January`)
- Day periods (`PM`)
- Translations are auto-generated, and it might be inconsistent depending on the CLDR locale [stage](https://cldr.unicode.org/index/process).
- A few locales does not support (or are missing) translations for specific layout elements (short/long days/month names or day periods), in that case,
an ErrUnsupportedLayoutElem will be reported.

Loading

0 comments on commit 99160b4

Please sign in to comment.