133 lines
2.3 KiB
Go
133 lines
2.3 KiB
Go
package fixed
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"slices"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
//go:generate go tool enumer -type Month
|
|
type Month int
|
|
|
|
const (
|
|
January Month = iota
|
|
February
|
|
March
|
|
April
|
|
May
|
|
June
|
|
July
|
|
August
|
|
September
|
|
October
|
|
November
|
|
December
|
|
)
|
|
|
|
var Year = []Month{January, February, March, April, May, June, July, August, September, October, November, December}
|
|
|
|
var shortMonths = map[string]Month{
|
|
// english
|
|
"jan": January,
|
|
"feb": February,
|
|
"mar": March,
|
|
"apr": April,
|
|
"may": May,
|
|
"jun": June,
|
|
"jul": July,
|
|
"aug": August,
|
|
"sep": September,
|
|
"oct": October,
|
|
"nov": November,
|
|
"dec": December,
|
|
// german
|
|
// "jan": January,
|
|
// "feb": February,
|
|
"mär": March,
|
|
// "apr": April,
|
|
"mai": May,
|
|
// "jun": June,
|
|
// "jul": July,
|
|
// "aug": August,
|
|
// "sep": September,
|
|
"okt": October,
|
|
// "nov": November,
|
|
"dez": December,
|
|
}
|
|
|
|
// ParseMonth parses a single month
|
|
func ParseMonth(s string) (Month, error) {
|
|
s = strings.ToLower(strings.TrimSpace(s))
|
|
|
|
// full string
|
|
if m, err := MonthString(s); err == nil {
|
|
return m, nil
|
|
}
|
|
|
|
// short string
|
|
if m, ok := shortMonths[s]; ok {
|
|
return m, nil
|
|
}
|
|
|
|
m, err := strconv.Atoi(s)
|
|
if m < 1 || m > 12 || err != nil {
|
|
return 0, fmt.Errorf("invalid month: %s", s)
|
|
}
|
|
|
|
return Month(m - 1), nil
|
|
}
|
|
|
|
// ParseMonths converts a months string into a slice of individual months
|
|
// Months format:
|
|
//
|
|
// month[-month][, ...]
|
|
func ParseMonths(s string) ([]Month, error) {
|
|
var res []Month
|
|
|
|
for segment := range strings.SplitSeq(s, ",") {
|
|
fromto := strings.SplitN(segment, "-", 2)
|
|
if len(fromto) == 0 {
|
|
return nil, fmt.Errorf("invalid month range: %s", segment)
|
|
}
|
|
|
|
fromToFrom := fromto[0]
|
|
|
|
// single empty segment
|
|
if len(fromto) == 1 && strings.TrimSpace(fromToFrom) == "" {
|
|
return slices.Clone(Year), nil
|
|
}
|
|
|
|
from, err := ParseMonth(fromToFrom)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res = append(res, from)
|
|
|
|
if len(fromto) == 2 {
|
|
to, err := ParseMonth(fromto[1])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if to < from {
|
|
to += 12
|
|
}
|
|
|
|
for m := from + 1; m <= to; m++ {
|
|
res = append(res, m%12)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(res) > 12 {
|
|
return nil, errors.New("too many months")
|
|
}
|
|
|
|
if len(slices.Compact(slices.Sorted(slices.Values(res)))) < len(res) {
|
|
return nil, errors.New("duplicate months")
|
|
}
|
|
|
|
return res, nil
|
|
}
|