Switched to expression-based timestamps
This commit is contained in:
parent
7bf586757a
commit
5c89c44ff7
7 changed files with 215 additions and 151 deletions
105
cmds/timestamps/ast.go
Normal file
105
cmds/timestamps/ast.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TimeComponent struct {
|
||||
TS *string `parser:"@Time"`
|
||||
}
|
||||
|
||||
func (t TimeComponent) Time() (time.Time, error) {
|
||||
if strings.HasSuffix(*t.TS, "Z") {
|
||||
return time.ParseInLocation("15:04:05Z", *t.TS, time.UTC)
|
||||
}
|
||||
return time.ParseInLocation("15:04:05", *t.TS, time.Local)
|
||||
}
|
||||
|
||||
func (t TimeComponent) RequiresRefreshing() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type DateWithTimeComponents struct {
|
||||
Date *string `parser:"@Date"`
|
||||
MaybeTime *TimeComponent `parser:" @@?"`
|
||||
}
|
||||
|
||||
func (d DateWithTimeComponents) Time() (time.Time, error) {
|
||||
t, err := time.Parse("2006-01-02", *d.Date)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
if d.MaybeTime != nil {
|
||||
tt, err := d.MaybeTime.Time()
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
t = t.Add(tt.Sub(tt.Truncate(24 * time.Hour)))
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
type Timestamp struct {
|
||||
Full *string `parser:"@Timestamp"`
|
||||
DT *DateWithTimeComponents `parser:"| @@"`
|
||||
TimeToday *TimeComponent `parser:" | @@"`
|
||||
Int *int `parser:" | @Int"`
|
||||
}
|
||||
|
||||
func (t Timestamp) Time() (time.Time, error) {
|
||||
switch {
|
||||
case t.Full != nil:
|
||||
if strings.HasSuffix(*t.Full, "Z") {
|
||||
return time.ParseInLocation("2006-01-02T15:04:05Z", *t.Full, time.UTC)
|
||||
}
|
||||
return time.ParseInLocation("2006-01-02T15:04:05", *t.Full, time.Local)
|
||||
case t.DT != nil:
|
||||
return t.DT.Time()
|
||||
case t.TimeToday != nil:
|
||||
tt, err := t.TimeToday.Time()
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
today := time.Now().In(tt.Location())
|
||||
return time.Date(today.Year(), today.Month(), today.Day(), tt.Hour(), tt.Minute(), tt.Second(), tt.Nanosecond(), tt.Location()), nil
|
||||
}
|
||||
return time.Unix(int64(*t.Int), 0), nil
|
||||
}
|
||||
|
||||
func (t Timestamp) RequiresRefreshing() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type Atom struct {
|
||||
Timestamp *Timestamp `parser:"@@"`
|
||||
Identifier *string `parser:" | @Identifier"`
|
||||
}
|
||||
|
||||
func (a Atom) Time() (time.Time, error) {
|
||||
switch {
|
||||
case a.Timestamp != nil:
|
||||
return a.Timestamp.Time()
|
||||
case a.Identifier != nil:
|
||||
if *a.Identifier == "now" {
|
||||
return time.Now(), nil
|
||||
}
|
||||
|
||||
return time.Time{}, errors.New("unknown identifier")
|
||||
}
|
||||
return time.Time{}, errors.New("unhandled case")
|
||||
}
|
||||
|
||||
func (a Atom) RequiresRefreshing() bool {
|
||||
switch {
|
||||
case a.Timestamp != nil:
|
||||
return a.Timestamp.RequiresRefreshing()
|
||||
case a.Identifier != nil:
|
||||
if *a.Identifier == "now" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue