| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package column
- import (
- "math"
- "strconv"
- "strings"
- "time"
- "github.com/ClickHouse/clickhouse-go/lib/binary"
- )
- type DateTime64 struct {
- base
- Timezone *time.Location
- }
- func (dt *DateTime64) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
- value, err := decoder.Int64()
- if err != nil {
- return nil, err
- }
- precision, err := dt.getPrecision()
- if err != nil {
- return nil, err
- }
- var nano int64
- if precision < 19 {
- nano = value * int64(math.Pow10(9-precision))
- }
- sec := nano / int64(10e8)
- nsec := nano - sec*10e8
- return time.Unix(sec, nsec).In(dt.Timezone), nil
- }
- func (dt *DateTime64) Write(encoder *binary.Encoder, v interface{}) error {
- var timestamp int64
- switch value := v.(type) {
- case time.Time:
- if !value.IsZero() {
- timestamp = value.UnixNano()
- }
- case uint64:
- timestamp = int64(value)
- case int64:
- timestamp = value
- case string:
- var err error
- timestamp, err = dt.parse(value)
- if err != nil {
- return err
- }
- case *time.Time:
- if value != nil && !(*value).IsZero() {
- timestamp = (*value).UnixNano()
- }
- case *int64:
- timestamp = *value
- case *string:
- var err error
- timestamp, err = dt.parse(*value)
- if err != nil {
- return err
- }
- default:
- return &ErrUnexpectedType{
- T: v,
- Column: dt,
- }
- }
- precision, err := dt.getPrecision()
- if err != nil {
- return err
- }
- timestamp = timestamp / int64(math.Pow10(9-precision))
- return encoder.Int64(timestamp)
- }
- func (dt *DateTime64) parse(value string) (int64, error) {
- tv, err := time.Parse("2006-01-02 15:04:05.999", value)
- if err != nil {
- return 0, err
- }
- return tv.UnixNano(), nil
- }
- func (dt *DateTime64) getPrecision() (int, error) {
- dtParams := dt.base.chType[11 : len(dt.base.chType)-1]
- precision, err := strconv.Atoi(strings.Split(dtParams, ",")[0])
- if err != nil {
- return 0, err
- }
- return precision, nil
- }
|