| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package column
- import (
- "time"
- "github.com/ClickHouse/clickhouse-go/lib/binary"
- )
- type Date struct {
- base
- Timezone *time.Location
- offset int64
- }
- func (dt *Date) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
- sec, err := decoder.Int16()
- if err != nil {
- return nil, err
- }
- return time.Unix(int64(sec)*24*3600-dt.offset, 0).In(dt.Timezone), nil
- }
- func (dt *Date) Write(encoder *binary.Encoder, v interface{}) error {
- var timestamp int64
- switch value := v.(type) {
- case time.Time:
- _, offset := value.Zone()
- timestamp = value.Unix() + int64(offset)
- case int16:
- return encoder.Int16(value)
- case int32:
- timestamp = int64(value) + dt.offset
- case uint32:
- timestamp = int64(value) + dt.offset
- case uint64:
- timestamp = int64(value) + dt.offset
- case int64:
- timestamp = value + dt.offset
- case string:
- var err error
- timestamp, err = dt.parse(value)
- if err != nil {
- return err
- }
- // this relies on Nullable never sending nil values through
- case *time.Time:
- _, offset := value.Zone()
- timestamp = (*value).Unix() + int64(offset)
- case *int16:
- return encoder.Int16(*value)
- case *int32:
- timestamp = int64(*value) + dt.offset
- case *int64:
- timestamp = *value + dt.offset
- case *string:
- var err error
- timestamp, err = dt.parse(*value)
- if err != nil {
- return err
- }
- default:
- return &ErrUnexpectedType{
- T: v,
- Column: dt,
- }
- }
- return encoder.Int16(int16(timestamp / 24 / 3600))
- }
- func (dt *Date) parse(value string) (int64, error) {
- tv, err := time.Parse("2006-01-02", value)
- if err != nil {
- return 0, err
- }
- return time.Date(
- time.Time(tv).Year(),
- time.Time(tv).Month(),
- time.Time(tv).Day(),
- 0, 0, 0, 0, time.UTC,
- ).Unix(), nil
- }
|