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