Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
337 lines (306 sloc) 7.19 KB
package naturaldate
import "time"
type parser Peg {
t time.Time
number int
month time.Month
weekday time.Weekday
direction int
}
Query
<- _ Expr+ EOF
Expr
<- NOW
/ RelativeMinutes
/ RelativeHours
/ RelativeDays
/ RelativeWeeks
/ RelativeWeekdays
/ RelativeMonth
/ RelativeYear
/ Date
/ Time
/ Word
RelativeMinutes
<- Number MINUTES AGO
{
p.t = p.t.Add(-time.Minute * time.Duration(p.number))
}
/ (Number MINUTES FROM_NOW / In Number? MINUTES FROM_NOW?)
{
p.t = p.t.Add(time.Minute * time.Duration(p.number))
}
/ Last Number? MINUTES
{
p.t = p.t.Add(-time.Minute * time.Duration(p.number))
}
/ Next Number? MINUTES
{
p.t = p.t.Add(time.Minute * time.Duration(p.number))
}
/ Number MINUTES
{
p.t = p.t.Add(p.withDirection(time.Minute) * time.Duration(p.number))
}
RelativeHours
<- Number HOURS AGO
{
p.t = p.t.Add(-time.Hour * time.Duration(p.number))
}
/ (Number HOURS FROM_NOW / In Number? HOURS FROM_NOW?)
{
p.t = p.t.Add(time.Hour * time.Duration(p.number))
}
/ Last Number? HOURS
{
p.t = p.t.Add(-time.Hour * time.Duration(p.number))
}
/ Next Number? HOURS
{
p.t = p.t.Add(time.Hour * time.Duration(p.number))
}
/ Number HOURS
{
p.t = p.t.Add(p.withDirection(time.Hour) * time.Duration(p.number))
}
RelativeDays
<- Number DAYS AGO
{
p.t = truncateDay(p.t.Add(-day * time.Duration(p.number)))
}
/ (Number DAYS FROM_NOW / In Number? DAYS FROM_NOW?)
{
p.t = p.t.Add(day * time.Duration(p.number))
}
/ Last Number? DAYS
{
p.t = truncateDay(p.t.Add(-day * time.Duration(p.number)))
}
/ Next Number? DAYS
{
p.t = truncateDay(p.t.Add(day * time.Duration(p.number)))
}
/ Number DAYS
{
p.t = truncateDay(p.t.Add(p.withDirection(day) * time.Duration(p.number)))
}
RelativeWeeks
<- Number WEEKS AGO
{
p.t = truncateDay(p.t.Add(-week * time.Duration(p.number)))
}
/ (Number WEEKS FROM_NOW / In Number? WEEKS FROM_NOW?)
{
p.t = p.t.Add(week * time.Duration(p.number))
}
/ Last Number? WEEKS
{
p.t = truncateDay(p.t.Add(-week * time.Duration(p.number)))
}
/ Next Number? WEEKS
{
p.t = truncateDay(p.t.Add(week * time.Duration(p.number)))
}
/ Number WEEKS
{
p.t = truncateDay(p.t.Add(p.withDirection(week) * time.Duration(p.number)))
}
RelativeMonth
<- Number MONTHS AGO
{
p.t = p.t.AddDate(0, -p.number, 0)
}
/ (Number MONTHS FROM_NOW / In Number? MONTHS FROM_NOW?)
{
p.t = p.t.AddDate(0, p.number, 0)
}
/ Last Number? MONTHS
{
p.t = p.t.AddDate(0, -p.number, 0)
}
/ Next Number? MONTHS
{
p.t = p.t.AddDate(0, p.number, 0)
}
/ LAST Month
{
p.t = prevMonth(p.t, p.month)
}
/ NEXT Month
{
p.t = nextMonth(p.t, p.month)
}
/ Month
{
if p.direction < 0 {
p.t = prevMonth(p.t, p.month)
} else {
p.t = nextMonth(p.t, p.month)
}
}
RelativeYear
<- Number YEARS AGO
{
p.t = p.t.AddDate(-p.number, 0, 0)
}
/ (Number YEARS FROM_NOW / In Number? YEARS FROM_NOW?)
{
p.t = p.t.AddDate(p.number, 0, 0)
}
/ Last Number? YEARS
{
p.t = p.t.AddDate(-p.number, 0, 0)
}
/ Next Number? YEARS
{
p.t = p.t.AddDate(p.number, 0, 0)
}
/ LAST YEARS
{
p.t = time.Date(p.t.Year() - 1, 1, 1, 0, 0, 0, 0, p.t.Location())
}
/ NEXT YEARS
{
p.t = time.Date(p.t.Year() + 1, 1, 1, 0, 0, 0, 0, p.t.Location())
}
RelativeWeekdays
<- TODAY
{
p.t = truncateDay(p.t)
}
/ YESTERDAY
{
p.t = truncateDay(p.t.Add(-day))
}
/ LAST Weekday
{
p.t = truncateDay(prevWeekday(p.t, p.weekday))
}
/ NEXT Weekday
{
p.t = truncateDay(nextWeekday(p.t, p.weekday))
}
/ Weekday
{
if p.direction < 0 {
p.t = truncateDay(prevWeekday(p.t, p.weekday))
} else {
p.t = truncateDay(nextWeekday(p.t, p.weekday))
}
}
Date
<- (Number Ordinal / Last Number? Number)
{
t := p.t
year, month, _ := t.Date()
hour, min, sec := t.Clock()
p.t = time.Date(year, month, p.number, hour, min, sec, 0, t.Location())
}
Time
<- Clock12Hour
/ Clock24Hour
Clock12Hour
<- Number
{
year, month, day := p.t.Date()
p.t = time.Date(year, month, day, p.number, 0, 0, 0, p.t.Location())
}
(Minutes Seconds?)?
AM
/ Number
{
year, month, day := p.t.Date()
p.t = time.Date(year, month, day, p.number + 12, 0, 0, 0, p.t.Location())
}
(Minutes Seconds?)?
PM
Clock24Hour
<- Number
{
year, month, day := p.t.Date()
p.t = time.Date(year, month, day, p.number, 0, 0, 0, p.t.Location())
}
(Minutes Seconds?)?
Minutes
<- ':' Number
{
t := p.t
year, month, day := t.Date()
hour, _, _ := t.Clock()
p.t = time.Date(year, month, day, hour, p.number, 0, 0, t.Location())
}
Seconds
<- ':' Number
{
t := p.t
year, month, day := t.Date()
hour, min, _ := t.Clock()
p.t = time.Date(year, month, day, hour, min, p.number, 0, t.Location())
}
Number
<- < [0-9]+ > _ { n, _ := strconv.Atoi(text); p.number = n }
/ 'one' _ { p.number = 1 }
/ 'two' _ { p.number = 2 }
/ 'three' _ { p.number = 3 }
/ 'four' _ { p.number = 4 }
/ 'five' _ { p.number = 5 }
/ 'six' _ { p.number = 6 }
/ 'seven' _ { p.number = 7 }
/ 'eight' _ { p.number = 8 }
/ 'nine' _ { p.number = 9 }
/ 'ten' _ { p.number = 10 }
Weekday
<- 'sunday' _ { p.weekday = time.Sunday }
/ 'monday' _ { p.weekday = time.Monday }
/ 'tuesday' _ { p.weekday = time.Tuesday }
/ 'wednesday' _ { p.weekday = time.Wednesday }
/ 'thursday' _ { p.weekday = time.Thursday }
/ 'friday' _ { p.weekday = time.Friday }
/ 'saturday' _ { p.weekday = time.Saturday }
Month
<- 'january' _ { p.month = time.January }
/ 'february' _ { p.month = time.February }
/ 'march' _ { p.month = time.March }
/ 'april' _ { p.month = time.April }
/ 'may' _ { p.month = time.May }
/ 'june' _ { p.month = time.June }
/ 'july' _ { p.month = time.July }
/ 'august' _ { p.month = time.August }
/ 'september' _ { p.month = time.September }
/ 'october' _ { p.month = time.October }
/ 'november' _ { p.month = time.November }
/ 'december' _ { p.month = time.December }
In
<- IN { p.number = 1}
Last
<- LAST { p.number = 1 }
Next
<- NEXT { p.number = 1 }
Ordinal
<- ('st' / 'nd' / 'rd' / 'th') _
Word
<- [a-z]+ _
YEARS <- 'year' 's'? _
MONTHS <- 'month' 's'? _
WEEKS <- 'week' 's'? _
DAYS <- 'day' 's'? _
HOURS <- 'hour' 's'? _
MINUTES <- 'minute' 's'? _
YESTERDAY <- 'yesterday' _
TODAY <- 'today' _
AGO <- 'ago' _
FROM_NOW <- 'from now' _
NOW <- 'now' _
AM <- 'am' _
PM <- 'pm' _
NEXT <- 'next' _
IN <- ('in an' / 'in a' / 'in') _
LAST <- ('last' / 'past' / 'previous') _
_
<- Whitespace*
Whitespace
<- ' ' / '\t' / EOL
EOL
<- '\r\n' / '\n' / '\r'
EOF
<- !.
You can’t perform that action at this time.