Skip to content

Commit

Permalink
feat: weekday snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
sonirico committed Mar 15, 2020
1 parent 04060d5 commit 06a6e5f
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 89 deletions.
38 changes: 24 additions & 14 deletions evaluator/constants.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
package evaluator

type Value string

type Unit string

type Snap string
import "time"

const (
Second Unit = "s"
Minute Unit = "m"
Hour Unit = "h"
Day Unit = "d"
Week Unit = "w"
Month Unit = "M"
Year Unit = "Y"
Second string = "s"
Minute = "m"
Hour = "h"
Day = "d"
Week = "w"
Month = "M"
Year = "Y"

Monday = "mon"
Tuesday = "tue"
Wednesday = "wed"
Thursday = "thu"
Friday = "fri"
Saturday = "sat"
Sunday = "sun"
)

const (
Start Snap = "/"
End Snap = "@"
Start string = "/"
End string = "@"
)

const (
Now = "now"
)

type valueResolver map[string]func(string) time.Time

func (vr valueResolver) register(token string, fn func(string) time.Time) {
vr[token] = fn
}
88 changes: 68 additions & 20 deletions evaluator/dates.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,6 @@ func EndOfYear(date time.Time) time.Time {
return BeginningOfYear(date).AddDate(1, 0, 0).Add(-time.Nanosecond)
}

// Monday monday
func PreviousMonday(date time.Time) time.Time {
t := BeginningOfDay(date)
weekday := int(t.Weekday())
if weekday == 0 {
weekday = 7
}
return t.AddDate(0, 0, -weekday+1)
}

// Sunday sunday
func PreviousSunday(date time.Time) time.Time {
t := BeginningOfDay(date)
weekday := int(t.Weekday())
if weekday == 0 {
return t
}
return t.AddDate(0, 0, 7-weekday)
}

// Next sunday
func EndOfSunday(date time.Time) time.Time {
return EndOfDay(PreviousSunday(date))
Expand Down Expand Up @@ -137,3 +117,71 @@ func AddMonths(date time.Time, amount int) time.Time {
func AddYears(date time.Time, amount int) time.Time {
return date.AddDate(amount, 0, 0)
}

func PreviousWeekDay(date time.Time, targetWeekDay time.Weekday) time.Time {
wd := int(date.Weekday())
twd := int(targetWeekDay)
return date.AddDate(0, 0, -(((wd-twd)%7 + 7) % 7))
}

func PreviousMonday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Monday)
}

func PreviousTuesday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Tuesday)
}

func PreviousWednesday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Wednesday)
}

func PreviousThursday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Thursday)
}

func PreviousFriday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Friday)
}

func PreviousSaturday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Saturday)
}

func PreviousSunday(date time.Time) time.Time {
return PreviousWeekDay(date, time.Sunday)
}

func NextWeekDay(date time.Time, targetWeekDay time.Weekday) time.Time {
wd := int(date.Weekday())
twd := int(targetWeekDay)
return date.AddDate(0, 0, ((twd-wd)%7+7)%7)
}

func NextMonday(date time.Time) time.Time {
return NextWeekDay(date, time.Monday)
}

func NextTuesday(date time.Time) time.Time {
return NextWeekDay(date, time.Tuesday)
}

func NextWednesday(date time.Time) time.Time {
return NextWeekDay(date, time.Wednesday)
}

func NextThursday(date time.Time) time.Time {
return NextWeekDay(date, time.Thursday)
}

func NextFriday(date time.Time) time.Time {
return NextWeekDay(date, time.Friday)
}

func NextSaturday(date time.Time) time.Time {
return NextWeekDay(date, time.Saturday)
}

func NextSunday(date time.Time) time.Time {
return NextWeekDay(date, time.Sunday)
}
90 changes: 54 additions & 36 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import (
"github.com/sonirico/datetoken.go/token"
)

type evalArithmeticFunc func(Unit) time.Time
type evalSnapFunc func(Snap) time.Time

type evalConfig struct {
WeekStartDay time.Weekday
TimeLocation *time.Location
Expand All @@ -25,37 +22,25 @@ type evaluator struct {

current time.Time
timeSet bool

arithmeticRegistry map[Unit]evalArithmeticFunc
snapRegistry map[Snap]evalSnapFunc
}

func newEvaluator() *evaluator {
evaluator := &evaluator{
config: &evalConfig{
WeekStartDay: time.Sunday,
},
timeSet: false,
arithmeticRegistry: make(map[Unit]evalArithmeticFunc),
snapRegistry: make(map[Snap]evalSnapFunc),
timeSet: false,
}
return evaluator
}

func (e *evaluator) registerSnapFunc(snap Snap, fn evalSnapFunc) {
e.snapRegistry[snap] = fn
}

func (e *evaluator) registerArithmeticFunc(unit Unit, fn evalArithmeticFunc) {
e.arithmeticRegistry[unit] = fn
}

// Override initial node value
func (e *evaluator) setInitial(date time.Time) {
if e.timeSet {
return
}
e.current = date
e.timeSet = true
}

func (e *evaluator) evalValueNode(node *ast.ValueNode) {
Expand All @@ -73,55 +58,88 @@ func (e *evaluator) evalArithmeticNode(node *ast.ArithmeticNode) {
}

switch node.Unit {
case "s":
case Second:
e.addSeconds(amount)
case "m":
case Minute:
e.addMinutes(amount)
case "h":
case Hour:
e.addHours(amount)
case "d":
case Day:
e.addDays(amount)
case "w":
case Week:
e.addWeeks(amount)
case "M":
case Month:
e.addMonths(amount)
case "Y":
case Year:
e.addYears(amount)
}
}

func (e *evaluator) evalStartSnap(node *ast.SnapNode) {
switch node.Unit {
case "m":
// time units
case Minute:
e.snapStartOfMinute()
case "h":
case Hour:
e.snapStartOfHour()
case "d":
case Day:
e.snapStartOfDay()
case "w":
case Week:
e.snapStartOfWeek()
case "M":
case Month:
e.snapStartOfMonth()
case "Y":
case Year:
e.snapStartOfYear()
// weekdays
case Monday:
e.previousMonday()
case Tuesday:
e.previousTuesday()
case Wednesday:
e.previousWednesday()
case Thursday:
e.previousThursday()
case Friday:
e.previousFriday()
case Saturday:
e.previousSaturday()
case Sunday:
e.previousSunday()
}
}

func (e *evaluator) evalEndSnap(node *ast.SnapNode) {
switch node.Unit {
case "m":
// time unit
case Minute:
e.snapEndOfMinute()
case "h":
case Hour:
e.snapEndOfHour()
case "d":
case Day:
e.snapEndOfDay()
case "w":
case Week:
e.snapEndOfWeek()
case "M":
case Month:
e.snapEndOfMonth()
case "Y":
case Year:
e.snapEndOfYear()
// weekdays
case Monday:
e.nextMonday()
case Tuesday:
e.nextTuesday()
case Wednesday:
e.nextWednesday()
case Thursday:
e.nextThursday()
case Friday:
e.nextFriday()
case Saturday:
e.nextSaturday()
case Sunday:
e.nextSunday()
}

}

func (e *evaluator) evalSnapNode(node *ast.SnapNode) {
Expand Down
56 changes: 56 additions & 0 deletions evaluator/evaluator_dates.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,59 @@ func (e *evaluator) addMonths(amount int) {
func (e *evaluator) addYears(amount int) {
e.current = AddYears(e.current, amount)
}

func (e *evaluator) previousMonday() {
e.current = PreviousMonday(e.current)
}

func (e *evaluator) previousTuesday() {
e.current = PreviousTuesday(e.current)
}

func (e *evaluator) previousWednesday() {
e.current = PreviousWednesday(e.current)
}

func (e *evaluator) previousThursday() {
e.current = PreviousThursday(e.current)
}

func (e *evaluator) previousFriday() {
e.current = PreviousFriday(e.current)
}

func (e *evaluator) previousSaturday() {
e.current = PreviousSaturday(e.current)
}

func (e *evaluator) previousSunday() {
e.current = PreviousSunday(e.current)
}

func (e *evaluator) nextMonday() {
e.current = NextMonday(e.current)
}

func (e *evaluator) nextTuesday() {
e.current = NextTuesday(e.current)
}

func (e *evaluator) nextWednesday() {
e.current = NextWednesday(e.current)
}

func (e *evaluator) nextThursday() {
e.current = NextThursday(e.current)
}

func (e *evaluator) nextFriday() {
e.current = NextFriday(e.current)
}

func (e *evaluator) nextSaturday() {
e.current = NextSaturday(e.current)
}

func (e *evaluator) nextSunday() {
e.current = NextSunday(e.current)
}
Loading

0 comments on commit 06a6e5f

Please sign in to comment.