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  }