diff --git a/README.md b/README.md index 7804b3b..f207a62 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ nowAgain, err := parser.Since(inTenMinutes, "-10 minutes") ## Available units The available time units are +* `ms`, `millisecond` or `milliseconds` * `s`, `second` or `seconds` * `m`, `minute` or `minutes` * `h`, `hour` or `hours` @@ -44,7 +45,7 @@ It's the number that will multiply the time unit: ### Validation You can use this regular expression to validate your inputs: ``` - ^((\\+|\\-))?([1-9][0-9]*)\\s?(s|seconds?|m|minutes?|h|hours?|d|days?|w|weeks?)$ + ^((\+|\-))?([1-9][0-9]*)\s?(ms|milliseconds?|s|seconds?|m|minutes?|h|hours?|d|days?|w|weeks?)$ ``` ## Scope diff --git a/parser.go b/parser.go index 60e5b99..a0f23cf 100644 --- a/parser.go +++ b/parser.go @@ -8,12 +8,33 @@ import ( ) const ( - Regex = "^((\\+|\\-))?([1-9][0-9]*)\\s?(s|seconds?|m|minutes?|h|hours?|d|days?|w|weeks?)$" + Regex = "^((\\+|\\-))?([1-9][0-9]*)\\s?(ms|milliseconds?|s|seconds?|m|minutes?|h|hours?|d|days?|w|weeks?)$" Day = time.Hour * 24 Week = Day * 7 ) -var compiledRegex *regexp.Regexp +var compiledRegex *regexp.Regexp + +var unitMap = map[string]time.Duration{ + "ms": time.Millisecond, + "millisecond": time.Millisecond, + "milliseconds": time.Millisecond, + "s": time.Second, + "second": time.Second, + "seconds": time.Second, + "m": time.Minute, + "minute": time.Minute, + "minutes": time.Minute, + "h": time.Hour, + "hour": time.Hour, + "hours": time.Hour, + "d": Day, + "day": Day, + "days": Day, + "w": Week, + "week": Week, + "weeks": Week, +} // Parser is the service that will provide the package functionality type Parser struct {} @@ -28,6 +49,7 @@ func New() *Parser { // The input string must contain a time unit and a signed multiplier ('+' sign by default if omitted) // // The accepted time unit are: +// - `ms`, `millisecond` or `milliseconds` // - `s`, `second` or `seconds` // - `m`, `minute` or `minutes` // - `h`, `hour` or `hours` @@ -94,20 +116,12 @@ func (p *Parser) getMultiplier(sign string, multiplier string) (time.Duration, e } func (p *Parser) getDuration(unit string, multiplier time.Duration) (time.Duration, error) { - switch unit[:1] { - case "s": - return time.Second * multiplier, nil - case "m": - return time.Minute * multiplier, nil - case "h": - return time.Hour * multiplier, nil - case "d": - return Day * multiplier, nil - case "w": - return Week * multiplier, nil + duration, found := unitMap[unit] + if !found { + return 0, fmt.Errorf("The duration unit '%s' is not supported", unit) } - return 0, fmt.Errorf("The duration unit '%s' is not supported", unit) + return duration * multiplier, nil } func (p *Parser) getRegex() (*regexp.Regexp, error) { diff --git a/parser_test.go b/parser_test.go index b113e21..2624455 100644 --- a/parser_test.go +++ b/parser_test.go @@ -10,21 +10,24 @@ func TestItParsePositiveDurationsCorrectly(t *testing.T) { parser := after.New() valid := map[string]time.Duration{ - "1s": time.Second, - "+1 second": time.Second, - "20seconds": time.Second * 20, - "1m": time.Minute, - "+1 minute": time.Minute, - "20 minutes": time.Minute * 20, - "1h": time.Hour, - "+1 hour": time.Hour, - "20hours": time.Hour * 20, - "1d": time.Hour * 24, - "+1 day": time.Hour * 24, - "20 days": time.Hour * 24 * 20, - "1w": time.Hour * 24 * 7, - "+1 week": time.Hour * 24 * 7, - "20 weeks": time.Hour * 24 * 7 * 20, + "1 millisecond": time.Millisecond, + "+1ms": time.Millisecond, + "20 milliseconds": time.Millisecond * 20, + "1s": time.Second, + "+1 second": time.Second, + "20seconds": time.Second * 20, + "1m": time.Minute, + "+1 minute": time.Minute, + "20 minutes": time.Minute * 20, + "1h": time.Hour, + "+1 hour": time.Hour, + "20hours": time.Hour * 20, + "1d": time.Hour * 24, + "+1 day": time.Hour * 24, + "20 days": time.Hour * 24 * 20, + "1w": time.Hour * 24 * 7, + "+1 week": time.Hour * 24 * 7, + "20 weeks": time.Hour * 24 * 7 * 20, } for input, expected := range valid { @@ -43,21 +46,24 @@ func TestItParseNegativeDurationsCorrectly(t *testing.T) { parser := after.New() valid := map[string]time.Duration{ - "-1s": -time.Second, - "-1 second": -time.Second, - "-20seconds": -time.Second * 20, - "-1m": -time.Minute, - "-1 minute": -time.Minute, - "-20 minutes": -time.Minute * 20, - "-1h": -time.Hour, - "-1 hour": -time.Hour, - "-20hours": -time.Hour * 20, - "-1d": -time.Hour * 24, - "-1 day": -time.Hour * 24, - "-20 days": -time.Hour * 24 * 20, - "-1w": -time.Hour * 24 * 7, - "-1 week": -time.Hour * 24 * 7, - "-20 weeks": -time.Hour * 24 * 7 * 20, + "-1ms": -time.Millisecond, + "-1 millisecond": -time.Millisecond, + "-20millisecond": -time.Millisecond * 20, + "-1s": -time.Second, + "-1 second": -time.Second, + "-20seconds": -time.Second * 20, + "-1m": -time.Minute, + "-1 minute": -time.Minute, + "-20 minutes": -time.Minute * 20, + "-1h": -time.Hour, + "-1 hour": -time.Hour, + "-20hours": -time.Hour * 20, + "-1d": -time.Hour * 24, + "-1 day": -time.Hour * 24, + "-20 days": -time.Hour * 24 * 20, + "-1w": -time.Hour * 24 * 7, + "-1 week": -time.Hour * 24 * 7, + "-20 weeks": -time.Hour * 24 * 7 * 20, } for input, expected := range valid {