Skip to content

Instantly share code, notes, and snippets.

@kniren
Created January 27, 2017 08:58
Show Gist options
  • Save kniren/f961e32a811b305b5442bae303f5d8b9 to your computer and use it in GitHub Desktop.
Save kniren/f961e32a811b305b5442bae303f5d8b9 to your computer and use it in GitHub Desktop.
Partial implementation of Time elements for Series/DataFrames (Gota)
package series
import (
"fmt"
"math"
"time"
)
// timeElement is the concrete implementation of the Element interface for
// time.Time. If the stored time.Time is zero, it will be considered as a NaN
// element.
type timeElement struct {
e time.Time
}
func (e *timeElement) Set(value interface{}) {
switch value.(type) {
case string:
s := value.(string)
parsed, err := time.Parse(timeformat, s)
if err != nil {
e.e = time.Time{}
return
}
e.e = parsed
case Element:
elem := value.(Element)
parsed, err := elem.Time()
if err != nil {
e.e = time.Time{}
return
}
e.e = parsed
default:
e.e = time.Time{}
return
}
}
func (e timeElement) Copy() Element {
if e.IsNA() {
return &timeElement{time.Time{}}
}
return &timeElement{time.Time(e.e)}
}
func (e timeElement) IsNA() bool {
if e.IsNA() {
return true
}
return false
}
func (e timeElement) Type() Type {
return Time // TODO: Need to create type on series.go
}
func (e timeElement) Val() ElementValue {
if e.IsNA() {
return nil
}
return time.Time(e.e)
}
func (e timeElement) String() string {
if e.IsNA() {
return "NaN"
}
return fmt.Sprint(e.e)
}
func (e timeElement) Int() (int, error) {
return 0, fmt.Errorf("can't convert Time to int")
}
func (e timeElement) Float() float64 {
return math.NaN()
}
func (e timeElement) Bool() (bool, error) {
return false, fmt.Errorf("can't convert Time to bool")
}
func (e timeElement) Time() (time.Time, error) {
if e.IsNA() {
return time.Time{}, fmt.Errorf("can't convert NaN to time.Time")
}
return time.Time(e.e), nil
}
func (e timeElement) Eq(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return e.e.Equal(cmp)
}
func (e timeElement) Neq(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return !e.e.Equal(cmp)
}
func (e timeElement) Less(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return e.e.Before(cmp)
}
func (e timeElement) LessEq(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return e.e.Before(cmp) || e.e.Equal(cmp)
}
func (e timeElement) Greater(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return e.e.After(cmp)
}
func (e timeElement) GreaterEq(elem Element) bool {
if e.IsNA() || elem.IsNA() {
return false
}
cmp, err := elem.Time()
if err != nil {
return false
}
return e.e.After(cmp) || e.e.Equal(cmp)
}
@shixzie
Copy link

shixzie commented Jan 28, 2017

Error checking for the comparator funcs is not needed since a Zero time.Time would be returned and thus the operarion still the same. The IsNA func would cause an infinite loop, return e.e.IsZero() instead. Just finished the whole implementation on a separated branch, i'll create the PR ASAP, rnow i'm having issues with my ISP.

@shixzie
Copy link

shixzie commented Jan 31, 2017

PR created

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment