date.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package column
  2. import (
  3. "time"
  4. "github.com/ClickHouse/clickhouse-go/lib/binary"
  5. )
  6. type Date struct {
  7. base
  8. Timezone *time.Location
  9. offset int64
  10. }
  11. func (dt *Date) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
  12. sec, err := decoder.Int16()
  13. if err != nil {
  14. return nil, err
  15. }
  16. return time.Unix(int64(sec)*24*3600-dt.offset, 0).In(dt.Timezone), nil
  17. }
  18. func (dt *Date) Write(encoder *binary.Encoder, v interface{}) error {
  19. var timestamp int64
  20. switch value := v.(type) {
  21. case time.Time:
  22. _, offset := value.Zone()
  23. timestamp = value.Unix() + int64(offset)
  24. case int16:
  25. return encoder.Int16(value)
  26. case int32:
  27. timestamp = int64(value) + dt.offset
  28. case uint32:
  29. timestamp = int64(value) + dt.offset
  30. case uint64:
  31. timestamp = int64(value) + dt.offset
  32. case int64:
  33. timestamp = value + dt.offset
  34. case string:
  35. var err error
  36. timestamp, err = dt.parse(value)
  37. if err != nil {
  38. return err
  39. }
  40. // this relies on Nullable never sending nil values through
  41. case *time.Time:
  42. _, offset := value.Zone()
  43. timestamp = (*value).Unix() + int64(offset)
  44. case *int16:
  45. return encoder.Int16(*value)
  46. case *int32:
  47. timestamp = int64(*value) + dt.offset
  48. case *int64:
  49. timestamp = *value + dt.offset
  50. case *string:
  51. var err error
  52. timestamp, err = dt.parse(*value)
  53. if err != nil {
  54. return err
  55. }
  56. default:
  57. return &ErrUnexpectedType{
  58. T: v,
  59. Column: dt,
  60. }
  61. }
  62. return encoder.Int16(int16(timestamp / 24 / 3600))
  63. }
  64. func (dt *Date) parse(value string) (int64, error) {
  65. tv, err := time.Parse("2006-01-02", value)
  66. if err != nil {
  67. return 0, err
  68. }
  69. return time.Date(
  70. time.Time(tv).Year(),
  71. time.Time(tv).Month(),
  72. time.Time(tv).Day(),
  73. 0, 0, 0, 0, time.UTC,
  74. ).Unix(), nil
  75. }