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