datetime.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package column
  2. import (
  3. "time"
  4. "github.com/ClickHouse/clickhouse-go/lib/binary"
  5. )
  6. type DateTime struct {
  7. base
  8. Timezone *time.Location
  9. }
  10. func (dt *DateTime) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
  11. sec, err := decoder.Int32()
  12. if err != nil {
  13. return nil, err
  14. }
  15. return time.Unix(int64(sec), 0).In(dt.Timezone), nil
  16. }
  17. func (dt *DateTime) Write(encoder *binary.Encoder, v interface{}) error {
  18. var timestamp int64
  19. switch value := v.(type) {
  20. case time.Time:
  21. if !value.IsZero() {
  22. timestamp = value.Unix()
  23. }
  24. case int16:
  25. timestamp = int64(value)
  26. case int32:
  27. timestamp = int64(value)
  28. case uint32:
  29. timestamp = int64(value)
  30. case uint64:
  31. timestamp = int64(value)
  32. case int64:
  33. timestamp = value
  34. case string:
  35. var err error
  36. timestamp, err = dt.parse(value)
  37. if err != nil {
  38. return err
  39. }
  40. case *time.Time:
  41. if value != nil && !(*value).IsZero() {
  42. timestamp = (*value).Unix()
  43. }
  44. case *int16:
  45. timestamp = int64(*value)
  46. case *int32:
  47. timestamp = int64(*value)
  48. case *int64:
  49. timestamp = *value
  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.Int32(int32(timestamp))
  63. }
  64. func (dt *DateTime) parse(value string) (int64, error) {
  65. tv, err := time.Parse("2006-01-02 15:04:05", 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. time.Time(tv).Hour(),
  74. time.Time(tv).Minute(),
  75. time.Time(tv).Second(),
  76. 0, time.Local, //use local timzone when insert into clickhouse
  77. ).Unix(), nil
  78. }