加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
w.go 5.36 KB
一键复制 编辑 原始数据 按行查看 历史
springrain 提交于 2023-05-10 15:35 . v1.8.12 来自 达梦8.1.3.12
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package dm
import (
"database/sql/driver"
"strings"
"time"
)
const (
Seconds_1900_1970 = 2209017600
OFFSET_YEAR = 0
OFFSET_MONTH = 1
OFFSET_DAY = 2
OFFSET_HOUR = 3
OFFSET_MINUTE = 4
OFFSET_SECOND = 5
OFFSET_NANOSECOND = 6
OFFSET_TIMEZONE = 7
DT_LEN = 8
INVALID_VALUE = int(INT32_MIN)
NANOSECOND_DIGITS = 9
NANOSECOND_POW = 1000000000
)
type DmTimestamp struct {
dt []int
dtype int
scale int
oracleFormatPattern string
oracleDateLanguage int
// Valid为false代表DmArray数据在数据库中为NULL
Valid bool
}
func newDmTimestampFromDt(dt []int, dtype int, scale int) *DmTimestamp {
dmts := new(DmTimestamp)
dmts.Valid = true
dmts.dt = dt
dmts.dtype = dtype
dmts.scale = scale
return dmts
}
func newDmTimestampFromBytes(bytes []byte, column column, conn *DmConnection) *DmTimestamp {
dmts := new(DmTimestamp)
dmts.Valid = true
dmts.dt = decode(bytes, column.isBdta, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
if isLocalTimeZone(int(column.colType), int(column.scale)) {
dmts.scale = getLocalTimeZoneScale(int(column.colType), int(column.scale))
} else {
dmts.scale = int(column.scale)
}
dmts.dtype = int(column.colType)
dmts.scale = int(column.scale)
dmts.oracleDateLanguage = int(conn.OracleDateLanguage)
switch column.colType {
case DATE:
dmts.oracleFormatPattern = conn.FormatDate
case TIME:
dmts.oracleFormatPattern = conn.FormatTime
case TIME_TZ:
dmts.oracleFormatPattern = conn.FormatTimeTZ
case DATETIME, DATETIME2:
dmts.oracleFormatPattern = conn.FormatTimestamp
case DATETIME_TZ, DATETIME2_TZ:
dmts.oracleFormatPattern = conn.FormatTimestampTZ
}
return dmts
}
func NewDmTimestampFromString(str string) (*DmTimestamp, error) {
dt := make([]int, DT_LEN)
dtype, err := toDTFromString(strings.TrimSpace(str), dt)
if err != nil {
return nil, err
}
if dtype == DATE {
return newDmTimestampFromDt(dt, dtype, 0), nil
}
return newDmTimestampFromDt(dt, dtype, 6), nil
}
func NewDmTimestampFromTime(time time.Time) *DmTimestamp {
dt := toDTFromTime(time)
return newDmTimestampFromDt(dt, DATETIME, 6)
}
func (dmTimestamp *DmTimestamp) ToTime() time.Time {
return toTimeFromDT(dmTimestamp.dt, 0)
}
// 获取年月日时分秒毫秒时区
func (dmTimestamp *DmTimestamp) GetDt() []int {
return dmTimestamp.dt
}
func (dmTimestamp *DmTimestamp) CompareTo(ts DmTimestamp) int {
if dmTimestamp.ToTime().Equal(ts.ToTime()) {
return 0
} else if dmTimestamp.ToTime().Before(ts.ToTime()) {
return -1
} else {
return 1
}
}
func (dmTimestamp *DmTimestamp) String() string {
if dmTimestamp.oracleFormatPattern != "" {
return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, int32(dmTimestamp.scale), dmTimestamp.oracleDateLanguage)
}
return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
}
func (dest *DmTimestamp) Scan(src interface{}) error {
if dest == nil {
return ECGO_STORE_IN_NIL_POINTER.throw()
}
switch src := src.(type) {
case nil:
*dest = *new(DmTimestamp)
// 将Valid标志置false表示数据库中该列为NULL
(*dest).Valid = false
return nil
case *DmTimestamp:
*dest = *src
return nil
case time.Time:
ret := NewDmTimestampFromTime(src)
*dest = *ret
return nil
case string:
ret, err := NewDmTimestampFromString(src)
if err != nil {
return err
}
*dest = *ret
return nil
default:
return UNSUPPORTED_SCAN.throw()
}
}
func (dmTimestamp DmTimestamp) Value() (driver.Value, error) {
if !dmTimestamp.Valid {
return nil, nil
}
return dmTimestamp, nil
}
//func (dmTimestamp *DmTimestamp) toBytes() ([]byte, error) {
// return encode(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale, dmTimestamp.dt[OFFSET_TIMEZONE])
//}
/**
* 获取当前对象的年月日时分秒,如果原来没有decode会先decode;
*/
func (dmTimestamp *DmTimestamp) getDt() []int {
return dmTimestamp.dt
}
func (dmTimestamp *DmTimestamp) getTime() int64 {
sec := toTimeFromDT(dmTimestamp.dt, 0).Unix()
return sec + int64(dmTimestamp.dt[OFFSET_NANOSECOND])
}
func (dmTimestamp *DmTimestamp) setTime(time int64) {
timeInMillis := (time / 1000) * 1000
nanos := (int64)((time % 1000) * 1000000)
if nanos < 0 {
nanos = 1000000000 + nanos
timeInMillis = (((time / 1000) - 1) * 1000)
}
dmTimestamp.dt = toDTFromUnix(timeInMillis, nanos)
}
func (dmTimestamp *DmTimestamp) setTimezone(tz int) error {
// DM中合法的时区取值范围为-12:59至+14:00
if tz <= -13*60 || tz > 14*60 {
return ECGO_INVALID_DATETIME_FORMAT.throw()
}
dmTimestamp.dt[OFFSET_TIMEZONE] = tz
return nil
}
func (dmTimestamp *DmTimestamp) getNano() int64 {
return int64(dmTimestamp.dt[OFFSET_NANOSECOND] * 1000)
}
func (dmTimestamp *DmTimestamp) setNano(nano int64) {
dmTimestamp.dt[OFFSET_NANOSECOND] = (int)(nano / 1000)
}
func (dmTimestamp *DmTimestamp) string() string {
if dmTimestamp.oracleFormatPattern != "" {
return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, int32(dmTimestamp.scale), dmTimestamp.oracleDateLanguage)
}
return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
}
func (dmTimestamp *DmTimestamp) checkValid() error {
if !dmTimestamp.Valid {
return ECGO_IS_NULL.throw()
}
return nil
}
/* for gorm v2 */
func (d *DmTimestamp) GormDataType() string {
return "TIMESTAMP"
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化