w.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright (c) 2000-2018, 达梦数据库有限公司.
  3. * All rights reserved.
  4. */
  5. package dm
  6. import (
  7. "database/sql/driver"
  8. "strings"
  9. "time"
  10. )
  11. const (
  12. Seconds_1900_1970 = 2209017600
  13. OFFSET_YEAR = 0
  14. OFFSET_MONTH = 1
  15. OFFSET_DAY = 2
  16. OFFSET_HOUR = 3
  17. OFFSET_MINUTE = 4
  18. OFFSET_SECOND = 5
  19. OFFSET_NANOSECOND = 6
  20. OFFSET_TIMEZONE = 7
  21. DT_LEN = 8
  22. INVALID_VALUE = int(INT32_MIN)
  23. NANOSECOND_DIGITS = 9
  24. NANOSECOND_POW = 1000000000
  25. )
  26. type DmTimestamp struct {
  27. dt []int
  28. dtype int
  29. scale int
  30. oracleFormatPattern string
  31. oracleDateLanguage int
  32. // Valid为false代表DmArray数据在数据库中为NULL
  33. Valid bool
  34. }
  35. func newDmTimestampFromDt(dt []int, dtype int, scale int) *DmTimestamp {
  36. dmts := new(DmTimestamp)
  37. dmts.Valid = true
  38. dmts.dt = dt
  39. dmts.dtype = dtype
  40. dmts.scale = scale
  41. return dmts
  42. }
  43. func newDmTimestampFromBytes(bytes []byte, column column, conn *DmConnection) *DmTimestamp {
  44. dmts := new(DmTimestamp)
  45. dmts.Valid = true
  46. dmts.dt = decode(bytes, column.isBdta, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
  47. if isLocalTimeZone(int(column.colType), int(column.scale)) {
  48. dmts.scale = getLocalTimeZoneScale(int(column.colType), int(column.scale))
  49. } else {
  50. dmts.scale = int(column.scale)
  51. }
  52. dmts.dtype = int(column.colType)
  53. dmts.scale = int(column.scale)
  54. dmts.oracleDateLanguage = int(conn.OracleDateLanguage)
  55. switch column.colType {
  56. case DATE:
  57. dmts.oracleFormatPattern = conn.FormatDate
  58. case TIME:
  59. dmts.oracleFormatPattern = conn.FormatTime
  60. case TIME_TZ:
  61. dmts.oracleFormatPattern = conn.FormatTimeTZ
  62. case DATETIME, DATETIME2:
  63. dmts.oracleFormatPattern = conn.FormatTimestamp
  64. case DATETIME_TZ, DATETIME2_TZ:
  65. dmts.oracleFormatPattern = conn.FormatTimestampTZ
  66. }
  67. return dmts
  68. }
  69. func NewDmTimestampFromString(str string) (*DmTimestamp, error) {
  70. dt := make([]int, DT_LEN)
  71. dtype, err := toDTFromString(strings.TrimSpace(str), dt)
  72. if err != nil {
  73. return nil, err
  74. }
  75. if dtype == DATE {
  76. return newDmTimestampFromDt(dt, dtype, 0), nil
  77. }
  78. return newDmTimestampFromDt(dt, dtype, 6), nil
  79. }
  80. func NewDmTimestampFromTime(time time.Time) *DmTimestamp {
  81. dt := toDTFromTime(time)
  82. return newDmTimestampFromDt(dt, DATETIME, 6)
  83. }
  84. func (dmTimestamp *DmTimestamp) ToTime() time.Time {
  85. return toTimeFromDT(dmTimestamp.dt, 0)
  86. }
  87. // 获取年月日时分秒毫秒时区
  88. func (dmTimestamp *DmTimestamp) GetDt() []int {
  89. return dmTimestamp.dt
  90. }
  91. func (dmTimestamp *DmTimestamp) CompareTo(ts DmTimestamp) int {
  92. if dmTimestamp.ToTime().Equal(ts.ToTime()) {
  93. return 0
  94. } else if dmTimestamp.ToTime().Before(ts.ToTime()) {
  95. return -1
  96. } else {
  97. return 1
  98. }
  99. }
  100. func (dmTimestamp *DmTimestamp) String() string {
  101. if dmTimestamp.oracleFormatPattern != "" {
  102. return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, int32(dmTimestamp.scale), dmTimestamp.oracleDateLanguage)
  103. }
  104. return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
  105. }
  106. func (dest *DmTimestamp) Scan(src interface{}) error {
  107. if dest == nil {
  108. return ECGO_STORE_IN_NIL_POINTER.throw()
  109. }
  110. switch src := src.(type) {
  111. case nil:
  112. *dest = *new(DmTimestamp)
  113. // 将Valid标志置false表示数据库中该列为NULL
  114. (*dest).Valid = false
  115. return nil
  116. case *DmTimestamp:
  117. *dest = *src
  118. return nil
  119. case time.Time:
  120. ret := NewDmTimestampFromTime(src)
  121. *dest = *ret
  122. return nil
  123. case string:
  124. ret, err := NewDmTimestampFromString(src)
  125. if err != nil {
  126. return err
  127. }
  128. *dest = *ret
  129. return nil
  130. default:
  131. return UNSUPPORTED_SCAN.throw()
  132. }
  133. }
  134. func (dmTimestamp DmTimestamp) Value() (driver.Value, error) {
  135. if !dmTimestamp.Valid {
  136. return nil, nil
  137. }
  138. return dmTimestamp, nil
  139. }
  140. //func (dmTimestamp *DmTimestamp) toBytes() ([]byte, error) {
  141. // return encode(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale, dmTimestamp.dt[OFFSET_TIMEZONE])
  142. //}
  143. /**
  144. * 获取当前对象的年月日时分秒,如果原来没有decode会先decode;
  145. */
  146. func (dmTimestamp *DmTimestamp) getDt() []int {
  147. return dmTimestamp.dt
  148. }
  149. func (dmTimestamp *DmTimestamp) getTime() int64 {
  150. sec := toTimeFromDT(dmTimestamp.dt, 0).Unix()
  151. return sec + int64(dmTimestamp.dt[OFFSET_NANOSECOND])
  152. }
  153. func (dmTimestamp *DmTimestamp) setTime(time int64) {
  154. timeInMillis := (time / 1000) * 1000
  155. nanos := (int64)((time % 1000) * 1000000)
  156. if nanos < 0 {
  157. nanos = 1000000000 + nanos
  158. timeInMillis = (((time / 1000) - 1) * 1000)
  159. }
  160. dmTimestamp.dt = toDTFromUnix(timeInMillis, nanos)
  161. }
  162. func (dmTimestamp *DmTimestamp) setTimezone(tz int) error {
  163. // DM中合法的时区取值范围为-12:59至+14:00
  164. if tz <= -13*60 || tz > 14*60 {
  165. return ECGO_INVALID_DATETIME_FORMAT.throw()
  166. }
  167. dmTimestamp.dt[OFFSET_TIMEZONE] = tz
  168. return nil
  169. }
  170. func (dmTimestamp *DmTimestamp) getNano() int64 {
  171. return int64(dmTimestamp.dt[OFFSET_NANOSECOND] * 1000)
  172. }
  173. func (dmTimestamp *DmTimestamp) setNano(nano int64) {
  174. dmTimestamp.dt[OFFSET_NANOSECOND] = (int)(nano / 1000)
  175. }
  176. func (dmTimestamp *DmTimestamp) string() string {
  177. if dmTimestamp.oracleFormatPattern != "" {
  178. return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, int32(dmTimestamp.scale), dmTimestamp.oracleDateLanguage)
  179. }
  180. return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
  181. }
  182. func (dmTimestamp *DmTimestamp) checkValid() error {
  183. if !dmTimestamp.Valid {
  184. return ECGO_IS_NULL.throw()
  185. }
  186. return nil
  187. }