Skip to content

Instantly share code, notes, and snippets.

@heyLu
Last active September 29, 2015 14:48
Show Gist options
  • Save heyLu/3c70766096588d1d9641 to your computer and use it in GitHub Desktop.
Save heyLu/3c70766096588d1d9641 to your computer and use it in GitHub Desktop.
/*
* A little experiment with date parsing.
*/
package main
import (
"fmt"
"regexp"
"strconv"
"time"
)
type matcher struct {
re *regexp.Regexp
parse func([]string) (time.Time, error)
}
func main() {
res := map[string]matcher{
"minutes": matcher{
re: regexp.MustCompile("^in ([a-zA-Z0-9]+) minutes?$"),
parse: func(parts []string) (time.Time, error) {
var t time.Time
var d time.Duration
switch parts[1] {
case "ten":
d = 10 * time.Minute
default:
n, err := strconv.Atoi(parts[1])
if err != nil {
return t, err
}
d = time.Duration(n) * time.Minute
}
t = time.Now()
return t.Add(d), nil
},
},
"hours": matcher{
re: regexp.MustCompile("^in ([a-zA-Z0-9]+) hours?$"),
parse: func(parts []string) (time.Time, error) {
var t time.Time
var d time.Duration
switch parts[1] {
case "an":
d = time.Hour
case "ten":
d = 10 * time.Hour
default:
n, err := strconv.Atoi(parts[1])
if err != nil {
return t, err
}
d = time.Duration(n) * time.Hour
}
t = time.Now()
return t.Add(d), nil
},
},
"weeks": matcher{
re: regexp.MustCompile("^in ([a-zA-Z0-9]+) weeks?$"),
parse: func(parts []string) (time.Time, error) {
var t time.Time
n, err := strconv.Atoi(parts[1])
if err != nil {
return t, err
}
t = time.Now()
return t.AddDate(0, n, 0), nil
},
},
"months": matcher{
re: regexp.MustCompile("^in ([a-zA-Z0-9]+) months?$"),
parse: func(parts []string) (time.Time, error) {
var t time.Time
n, err := strconv.Atoi(parts[1])
if err != nil {
return t, err
}
t = time.Now()
return t.AddDate(0, n, 0), nil
},
},
"tomorrow": matcher{
re: regexp.MustCompile("^tomorrow$"),
parse: func([]string) (time.Time, error) {
return time.Now().AddDate(0, 0, 1), nil
},
},
"next": matcher{
re: regexp.MustCompile("^next ([a-zA-Z]+)$"),
parse: func(parts []string) (time.Time, error) {
switch parts[1] {
case "week":
return time.Now().AddDate(0, 0, 7), nil
case "month":
return time.Now().AddDate(0, 1, 0), nil
case "year":
return time.Now().AddDate(1, 0, 0), nil
default:
panic("not implemented")
}
},
},
}
exprs := []string{
"in ten minutes",
"in 10 minutes",
"in an hour",
"in 3 hours",
"tomorrow",
"next week",
"next month",
"next year",
"in 5 weeks",
"in 3 months",
}
for _, expr := range exprs {
for name, m := range res {
if m.re.MatchString(expr) {
fmt.Printf("%s %q\n", name, expr)
if m.parse != nil {
matches := m.re.FindStringSubmatch(expr)
t, err := m.parse(matches)
t = t.Round(time.Second)
fmt.Println(t, err)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment