Files
tablizer/vendor/github.com/glycerine/zygomys/zygo/time.go
2024-05-14 12:10:58 +02:00

112 lines
2.2 KiB
Go

package zygo
import (
"errors"
"fmt"
"time"
)
var UtcTz *time.Location
var NYC *time.Location
func init() {
var err error
UtcTz, err = time.LoadLocation("UTC")
panicOn(err)
NYC, err = time.LoadLocation("America/New_York")
panicOn(err)
}
type SexpTime struct {
Tm time.Time
}
func (r *SexpTime) Type() *RegisteredType {
return nil // TODO what should this be?
}
func (t *SexpTime) SexpString(ps *PrintState) string {
return t.Tm.String()
}
func NowFunction(env *Zlisp, name string,
args []Sexp) (Sexp, error) {
return &SexpTime{Tm: time.Now()}, nil
}
// string -> time.Time
func AsTmFunction(env *Zlisp, name string,
args []Sexp) (Sexp, error) {
if len(args) != 1 {
return SexpNull, WrongNargs
}
var str *SexpStr
switch t := args[0].(type) {
case *SexpStr:
str = t
default:
return SexpNull,
errors.New("argument of astm should be a string RFC3999Nano timestamp that we want to convert to time.Time")
}
tm, err := time.ParseInLocation(time.RFC3339Nano, str.S, NYC)
if err != nil {
return SexpNull, err
}
return &SexpTime{Tm: tm.In(NYC)}, nil
}
func TimeitFunction(env *Zlisp, name string,
args []Sexp) (Sexp, error) {
if len(args) != 1 {
return SexpNull, WrongNargs
}
var fun *SexpFunction
switch t := args[0].(type) {
case *SexpFunction:
fun = t
default:
return SexpNull,
errors.New("argument of timeit should be function")
}
starttime := time.Now()
elapsed := time.Since(starttime)
maxseconds := 10.0
var iterations int
for iterations = 0; iterations < 10000; iterations++ {
_, err := env.Apply(fun, []Sexp{})
if err != nil {
return SexpNull, err
}
elapsed = time.Since(starttime)
if elapsed.Seconds() > maxseconds {
break
}
}
fmt.Printf("ran %d iterations in %f seconds\n",
iterations, elapsed.Seconds())
fmt.Printf("average %f seconds per run\n",
elapsed.Seconds()/float64(iterations))
return SexpNull, nil
}
func MillisFunction(env *Zlisp, name string,
args []Sexp) (Sexp, error) {
millis := time.Now().UnixNano() / 1000000
return &SexpInt{Val: int64(millis)}, nil
}
func (env *Zlisp) ImportTime() {
env.AddFunction("now", NowFunction)
env.AddFunction("timeit", TimeitFunction)
env.AddFunction("astm", AsTmFunction)
env.AddFunction("millis", MillisFunction)
}