gitee.com/curryzheng/dm@v0.0.1/i.go (about)

     1  /*
     2   * Copyright (c) 2000-2018, 达梦数据库有限公司.
     3   * All rights reserved.
     4   */
     5  package dm
     6  
     7  import (
     8  	"math"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  	"unicode"
    13  )
    14  
    15  func encodeByString(x string, dtype int, scale int, ltz int, dtz int) ([]byte, error) {
    16  	dt := make([]int, DT_LEN)
    17  	if _, err := toDTFromString(x, dt); err != nil {
    18  		return nil, err
    19  	}
    20  	return encode(dt, dtype, scale, ltz)
    21  }
    22  
    23  func encodeByTime(x time.Time, dtype int, scale int, lTz int, dbTz int) ([]byte, error) {
    24  	dt := toDTFromTime(x)
    25  	return encode(dt, dtype, scale, lTz)
    26  }
    27  
    28  func encodeByDateNumber(x int64, destDType int, scale int, lTz int, dbTz int16) ([]byte, error) {
    29  	switch destDType {
    30  	case DATETIME:
    31  
    32  		if x > 2958463*24*60*60 {
    33  			return nil, ECGO_DATETIME_OVERFLOW.throw()
    34  		}
    35  
    36  		dt := toDTFromUnix(x-Seconds_1900_1970, 0)
    37  		return encode(dt, destDType, scale, lTz)
    38  
    39  	case TIME:
    40  		dt := toDTFromUnix(x, 0)
    41  		return encode(dt, destDType, scale, lTz)
    42  
    43  	case DATE:
    44  
    45  		if x > 2958463 {
    46  			return nil, ECGO_DATETIME_OVERFLOW.throw()
    47  		}
    48  
    49  		dt := toDTFromUnix(x*24*60*60-Seconds_1900_1970, 0)
    50  		if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 {
    51  			return nil, ECGO_DATETIME_OVERFLOW.throw()
    52  		}
    53  		return encode(dt, destDType, scale, lTz)
    54  
    55  	default:
    56  		return nil, ECGO_DATA_CONVERTION_ERROR.throw()
    57  
    58  	}
    59  }
    60  
    61  func toTimeFromString(str string, ltz int) time.Time {
    62  	dt := make([]int, DT_LEN)
    63  	toDTFromString(str, dt)
    64  	return toTimeFromDT(dt, ltz)
    65  }
    66  
    67  func toTimeFromDT(dt []int, ltz int) time.Time {
    68  	var year, month, day, hour, minute, second, nsec, tz int
    69  
    70  	year = dt[OFFSET_YEAR]
    71  
    72  	if dt[OFFSET_MONTH] > 0 {
    73  		month = dt[OFFSET_MONTH]
    74  	} else {
    75  		month = 1
    76  	}
    77  
    78  	if dt[OFFSET_DAY] > 0 {
    79  		day = dt[OFFSET_DAY]
    80  	} else {
    81  		day = 1
    82  	}
    83  
    84  	hour = dt[OFFSET_HOUR]
    85  	minute = dt[OFFSET_MINUTE]
    86  	second = dt[OFFSET_SECOND]
    87  	nsec = dt[OFFSET_MILLISECOND] * 1000
    88  	if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
    89  		tz = ltz * 60
    90  	} else {
    91  		tz = dt[OFFSET_TIMEZONE] * 60
    92  	}
    93  	return time.Date(year, time.Month(month), day, hour, minute, second, nsec, time.FixedZone("", tz))
    94  }
    95  
    96  func decode(value []byte, isBdta bool, colType int, scale int, ltz int, dbtz int) []int {
    97  	var dt []int
    98  	if isBdta {
    99  		dt = dmdtDecodeBdta(value)
   100  	} else {
   101  		dt = dmdtDecodeFast(value)
   102  	}
   103  
   104  	if isLocalTimeZone(colType, scale) {
   105  		transformTZ(dt, dbtz, ltz)
   106  		scale = getLocalTimeZoneScale(colType, scale)
   107  	}
   108  
   109  	if scale > 0 && scale < 6 {
   110  		tmp := math.Pow10(6 - scale)
   111  		dt[OFFSET_MILLISECOND] = int(float64(dt[OFFSET_MILLISECOND]) / tmp * tmp)
   112  	}
   113  	return dt
   114  }
   115  
   116  func dmdtDecodeFast(value []byte) []int {
   117  	dt := make([]int, DT_LEN)
   118  	dt[OFFSET_TIMEZONE] = INVALID_VALUE
   119  
   120  	if len(value) == 3 {
   121  
   122  		dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0)) & 0x7FFF
   123  		if dt[OFFSET_YEAR] > 9999 {
   124  			dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000))
   125  		}
   126  
   127  		dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1)
   128  
   129  		dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f
   130  	} else if len(value) < 8 {
   131  
   132  		dt[OFFSET_HOUR] = int(value[0]) & 0x1F
   133  		dt[OFFSET_MINUTE] = ((int(value[0]) >> 5) & 0x07) + ((int(value[1]) & 0x07) << 3)
   134  		dt[OFFSET_SECOND] = ((int(value[1]) >> 3) & 0x1f) + ((int(value[2]) & 0x01) << 5)
   135  		dt[OFFSET_MILLISECOND] = ((int(value[2]) >> 1) & 0x7f) + ((int(value[3]) & 0x00ff) << 7) + ((int(value[4]) & 0x1F) << 15)
   136  
   137  		if len(value) > 5 {
   138  			dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 5))
   139  		}
   140  	} else {
   141  
   142  		dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0)) & 0x7FFF
   143  		if dt[OFFSET_YEAR] > 9999 {
   144  			dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000))
   145  		}
   146  
   147  		dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1)
   148  
   149  		dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f
   150  
   151  		dt[OFFSET_HOUR] = (int(value[3]) & 0x1F)
   152  
   153  		dt[OFFSET_MINUTE] = ((int(value[3]) >> 5) & 0x07) + ((int(value[4]) & 0x07) << 3)
   154  
   155  		dt[OFFSET_SECOND] = ((int(value[4]) >> 3) & 0x1f) + ((int(value[5]) & 0x01) << 5)
   156  
   157  		dt[OFFSET_MILLISECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x1F) << 15)
   158  
   159  		if len(value) > 8 {
   160  			dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 8))
   161  		}
   162  	}
   163  	return dt
   164  }
   165  
   166  func dmdtDecodeBdta(value []byte) []int {
   167  	dt := make([]int, DT_LEN)
   168  	dt[OFFSET_YEAR] = int(Dm_build_1.Dm_build_98(value, 0))
   169  	dt[OFFSET_MONTH] = int(value[2] & 0xFF)
   170  	dt[OFFSET_DAY] = int(value[3] & 0xFF)
   171  	dt[OFFSET_HOUR] = int(value[4] & 0xFF)
   172  	dt[OFFSET_MINUTE] = int(value[5] & 0xFF)
   173  	dt[OFFSET_SECOND] = int(value[6] & 0xFF)
   174  	dt[OFFSET_MILLISECOND] = int((value[7] & 0xFF) + (value[8] << 8) + (value[9] << 16))
   175  	dt[OFFSET_TIMEZONE] = int(Dm_build_1.Dm_build_98(value, 10))
   176  	return dt
   177  }
   178  
   179  func dtToStringByOracleFormat(dt []int, oracleFormatPattern string, language int) string {
   180  	return format(dt, oracleFormatPattern, language)
   181  }
   182  
   183  func dtToString(dt []int, dtype int, scale int) string {
   184  	switch dtype {
   185  	case DATE:
   186  		return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY])
   187  
   188  	case TIME:
   189  		if scale > 0 {
   190  			return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale)
   191  		} else {
   192  			return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND])
   193  		}
   194  
   195  	case TIME_TZ:
   196  		if scale > 0 {
   197  			return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE])
   198  		} else {
   199  			return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE])
   200  		}
   201  
   202  	case DATETIME:
   203  		if scale > 0 {
   204  			return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale)
   205  		} else {
   206  			return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND])
   207  		}
   208  
   209  	case DATETIME_TZ:
   210  		if scale > 0 {
   211  			return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE])
   212  		} else {
   213  			return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE])
   214  		}
   215  	}
   216  
   217  	return ""
   218  }
   219  
   220  func formatYear(value int) string {
   221  	if value >= 0 {
   222  		if value < 10 {
   223  			return "000" + strconv.FormatInt(int64(value), 10)
   224  		} else if value < 100 {
   225  			return "00" + strconv.FormatInt(int64(value), 10)
   226  		} else if value < 1000 {
   227  			return "0" + strconv.FormatInt(int64(value), 10)
   228  		} else {
   229  			return strconv.FormatInt(int64(value), 10)
   230  		}
   231  	} else {
   232  		if value > -10 {
   233  			return "-000" + strconv.FormatInt(int64(-value), 10)
   234  		} else if value > -100 {
   235  			return "-00" + strconv.FormatInt(int64(-value), 10)
   236  		} else if value > -1000 {
   237  			return "-0" + strconv.FormatInt(int64(-value), 10)
   238  		} else {
   239  			return strconv.FormatInt(int64(-value), 10)
   240  		}
   241  	}
   242  }
   243  
   244  func format2(value int) string {
   245  	if value < 10 {
   246  		return "0" + strconv.FormatInt(int64(value), 10)
   247  	} else {
   248  		return strconv.FormatInt(int64(value), 10)
   249  	}
   250  }
   251  
   252  func formatMilliSecond(ms int, prec int) string {
   253  	var ret string
   254  	if ms < 10 {
   255  		ret = "00000" + strconv.FormatInt(int64(ms), 10)
   256  	} else if ms < 100 {
   257  		ret = "0000" + strconv.FormatInt(int64(ms), 10)
   258  	} else if ms < 1000 {
   259  		ret = "000" + strconv.FormatInt(int64(ms), 10)
   260  	} else if ms < 10000 {
   261  		ret = "00" + strconv.FormatInt(int64(ms), 10)
   262  	} else if ms < 100000 {
   263  		ret = "0" + strconv.FormatInt(int64(ms), 10)
   264  	} else {
   265  		ret = strconv.FormatInt(int64(ms), 10)
   266  	}
   267  
   268  	if prec < 6 {
   269  		ret = ret[:prec]
   270  	}
   271  	return ret
   272  }
   273  
   274  func formatTZ(tz int) string {
   275  	tz_hour := int(math.Abs(float64(tz / 60)))
   276  	tz_min := int(math.Abs(float64(tz % 60)))
   277  
   278  	if tz >= 0 {
   279  		return "+" + format2(tz_hour) + ":" + format2(tz_min)
   280  	} else {
   281  		return "-" + format2(tz_hour) + ":" + format2(tz_min)
   282  	}
   283  }
   284  
   285  func toDTFromTime(x time.Time) []int {
   286  	hour, min, sec := x.Clock()
   287  	ts := make([]int, DT_LEN)
   288  	ts[OFFSET_YEAR] = x.Year()
   289  	ts[OFFSET_MONTH] = int(x.Month())
   290  	ts[OFFSET_DAY] = x.Day()
   291  	ts[OFFSET_HOUR] = hour
   292  	ts[OFFSET_MINUTE] = min
   293  	ts[OFFSET_SECOND] = sec
   294  	ts[OFFSET_MILLISECOND] = (int)(x.Nanosecond() / 1000)
   295  	_, tz := x.Zone()
   296  	ts[OFFSET_TIMEZONE] = tz / 60
   297  	return ts
   298  }
   299  
   300  func toDTFromUnix(sec int64, nsec int64) []int {
   301  	return toDTFromTime(time.Unix(sec, nsec))
   302  }
   303  
   304  func toDTFromString(s string, dt []int) (dtype int, err error) {
   305  	defer func() {
   306  		if p := recover(); p != nil {
   307  			err = ECGO_INVALID_DATETIME_FORMAT.throw()
   308  		}
   309  	}()
   310  	date_s := ""
   311  	time_s := ""
   312  	nanos_s := ""
   313  	tz_s := ""
   314  	year := 0
   315  	month := 0
   316  	day := 0
   317  	hour := 0
   318  	minute := 0
   319  	second := 0
   320  	a_nanos := 0
   321  	firstDash := -1
   322  	secondDash := -1
   323  	firstColon := -1
   324  	secondColon := -1
   325  	period := -1
   326  	sign := 0
   327  	ownTz := INVALID_VALUE
   328  	dtype = -1
   329  
   330  	zeros := "000000000"
   331  
   332  	if s != "" && strings.TrimSpace(s) == "" {
   333  		return 0, ECGO_INVALID_DATETIME_FORMAT.throw()
   334  	}
   335  	s = strings.TrimSpace(s)
   336  
   337  	if strings.Index(s, "-") == 0 {
   338  		s = strings.TrimSpace(s[1:])
   339  		sign = 1
   340  	}
   341  
   342  	comps := strings.Split(s, " ")
   343  
   344  	switch len(comps) {
   345  	case 3:
   346  		date_s = comps[0]
   347  		time_s = comps[1]
   348  		tz_s = comps[2]
   349  		dtype = DATETIME_TZ
   350  
   351  	case 2:
   352  		if strings.Index(comps[0], ":") > 0 {
   353  			time_s = comps[0]
   354  			tz_s = comps[1]
   355  			dtype = TIME_TZ
   356  		} else {
   357  			date_s = comps[0]
   358  			time_s = comps[1]
   359  			dtype = DATETIME
   360  		}
   361  
   362  	case 1:
   363  		if strings.Index(comps[0], ":") > 0 {
   364  			time_s = comps[0]
   365  			dtype = TIME
   366  		} else {
   367  			date_s = comps[0]
   368  			dtype = DATE
   369  		}
   370  
   371  	default:
   372  		return 0, ECGO_INVALID_DATETIME_FORMAT.throw()
   373  	}
   374  
   375  	if date_s != "" {
   376  
   377  		firstDash = strings.Index(date_s, "-")
   378  		secondDash = strings.Index(date_s[firstDash+1:], "-")
   379  
   380  		if firstDash < 0 || secondDash < 0 {
   381  			firstDash = strings.Index(s, ".")
   382  			secondDash = strings.Index(date_s[firstDash+1:], ".")
   383  		}
   384  
   385  		if firstDash < 0 || secondDash < 0 {
   386  			firstDash = strings.Index(s, "/")
   387  			secondDash = strings.Index(date_s[firstDash+1:], "/")
   388  		}
   389  		if secondDash > 0 {
   390  			secondDash += firstDash + 1
   391  		}
   392  
   393  		if (firstDash > 0) && (secondDash > 0) && (secondDash < len(date_s)-1) {
   394  
   395  			if sign == 1 {
   396  				i, err := strconv.ParseInt(date_s[:firstDash], 10, 32)
   397  				if err != nil {
   398  					return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   399  				}
   400  				year = 0 - int(i) - 1900
   401  			} else {
   402  				i, err := strconv.ParseInt(date_s[:firstDash], 10, 32)
   403  				if err != nil {
   404  					return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   405  				}
   406  				year = int(i) - 1900
   407  			}
   408  
   409  			i, err := strconv.ParseInt(date_s[firstDash+1:secondDash], 10, 32)
   410  			if err != nil {
   411  				return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   412  			}
   413  			month = int(i) - 1
   414  
   415  			i, err = strconv.ParseInt(date_s[secondDash+1:], 10, 32)
   416  			if err != nil {
   417  				return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   418  			}
   419  			day = int(i)
   420  
   421  			if !checkDate(year+1900, month+1, day) {
   422  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   423  			}
   424  		} else {
   425  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   426  		}
   427  	}
   428  
   429  	if time_s != "" {
   430  		firstColon = strings.Index(time_s, ":")
   431  		secondColon = strings.Index(time_s[firstColon+1:], ":")
   432  		if secondColon > 0 {
   433  			secondColon += firstColon + 1
   434  		}
   435  
   436  		period = strings.Index(time_s[secondColon+1:], ".")
   437  		if period > 0 {
   438  			period += secondColon + 1
   439  		}
   440  
   441  		if (firstColon > 0) && (secondColon > 0) && (secondColon < len(time_s)-1) {
   442  			i, err := strconv.ParseInt(time_s[:firstColon], 10, 32)
   443  			if err != nil {
   444  				return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   445  			}
   446  			hour = int(i)
   447  
   448  			i, err = strconv.ParseInt(time_s[firstColon+1:secondColon], 10, 32)
   449  			if err != nil {
   450  				return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   451  			}
   452  			minute = int(i)
   453  
   454  			if period > 0 && period < len(time_s)-1 {
   455  				i, err = strconv.ParseInt(time_s[secondColon+1:period], 10, 32)
   456  				if err != nil {
   457  					return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   458  				}
   459  				second = int(i)
   460  
   461  				nanos_s = time_s[period+1:]
   462  				if len(nanos_s) > 9 {
   463  					return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   464  				}
   465  				if !unicode.IsDigit(rune(nanos_s[0])) {
   466  					return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   467  				}
   468  				nanos_s = nanos_s + zeros[0:9-len(nanos_s)]
   469  
   470  				i, err = strconv.ParseInt(nanos_s[:6], 10, 32)
   471  				if err != nil {
   472  					return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   473  				}
   474  				a_nanos = int(i)
   475  			} else if period > 0 {
   476  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   477  			} else {
   478  				i, err = strconv.ParseInt(time_s[secondColon+1:], 10, 32)
   479  				if err != nil {
   480  					return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
   481  				}
   482  				second = int(i)
   483  			}
   484  
   485  			if hour >= 24 || hour < 0 || minute >= 60 || minute < 0 || second >= 60 || second < 0 {
   486  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   487  			}
   488  		} else {
   489  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   490  		}
   491  	}
   492  
   493  	if tz_s != "" {
   494  		neg := false
   495  		if strings.Index(tz_s, "-") == 0 {
   496  			neg = true
   497  		}
   498  
   499  		if strings.Index(tz_s, "-") == 0 || strings.Index(tz_s, "+") == 0 {
   500  			tz_s = strings.TrimSpace(tz_s[1:])
   501  		}
   502  
   503  		hm := strings.Split(tz_s, ":")
   504  		var tzh, tzm int16 = 0, 0
   505  		switch len(hm) {
   506  		case 2:
   507  			s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16)
   508  			if err != nil {
   509  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   510  			}
   511  			tzh = int16(s)
   512  
   513  			s, err = strconv.ParseInt(strings.TrimSpace(hm[1]), 10, 16)
   514  			if err != nil {
   515  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   516  			}
   517  			tzm = int16(s)
   518  		case 1:
   519  			s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16)
   520  			if err != nil {
   521  				return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   522  			}
   523  			tzh = int16(s)
   524  		default:
   525  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   526  		}
   527  
   528  		ownTz = int(tzh*60 + tzm)
   529  		if ownTz < 0 {
   530  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   531  		}
   532  
   533  		if neg {
   534  			ownTz *= -1
   535  		}
   536  
   537  		if ownTz <= -13*60 || ownTz > 14*60 {
   538  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   539  		}
   540  	}
   541  
   542  	dt[OFFSET_YEAR] = year + 1900
   543  	dt[OFFSET_MONTH] = month + 1
   544  	if day == 0 {
   545  		dt[OFFSET_DAY] = 1
   546  	} else {
   547  		dt[OFFSET_DAY] = day
   548  	}
   549  	dt[OFFSET_HOUR] = hour
   550  	dt[OFFSET_MINUTE] = minute
   551  	dt[OFFSET_SECOND] = second
   552  	dt[OFFSET_MILLISECOND] = a_nanos
   553  	dt[OFFSET_TIMEZONE] = int(ownTz)
   554  	return dtype, nil
   555  }
   556  
   557  func transformTZ(dt []int, defaultSrcTz int, destTz int) {
   558  	srcTz := defaultSrcTz
   559  	if dt[OFFSET_TIMEZONE] != INVALID_VALUE {
   560  		srcTz = dt[OFFSET_TIMEZONE]
   561  	}
   562  
   563  	if destTz != srcTz {
   564  		dt = addMinute(dt, destTz-srcTz)
   565  		if dt[OFFSET_TIMEZONE] != INVALID_VALUE {
   566  			dt[OFFSET_TIMEZONE] = destTz
   567  		}
   568  	}
   569  }
   570  
   571  func encode(dt []int, dtype int, scale int, lTz int) ([]byte, error) {
   572  
   573  	if isLocalTimeZone(dtype, scale) && dt[OFFSET_TIMEZONE] != INVALID_VALUE && dt[OFFSET_TIMEZONE] != lTz {
   574  		transformTZ(dt, dt[OFFSET_TIMEZONE], lTz)
   575  	}
   576  
   577  	if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 {
   578  		return nil, ECGO_DATETIME_OVERFLOW.throw()
   579  	}
   580  
   581  	year := dt[OFFSET_YEAR]
   582  
   583  	month := dt[OFFSET_MONTH]
   584  
   585  	day := dt[OFFSET_DAY]
   586  
   587  	hour := dt[OFFSET_HOUR]
   588  
   589  	min := dt[OFFSET_MINUTE]
   590  
   591  	sec := dt[OFFSET_SECOND]
   592  
   593  	msec := dt[OFFSET_MILLISECOND]
   594  
   595  	var tz int
   596  
   597  	if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
   598  		tz = lTz
   599  	} else {
   600  		tz = dt[OFFSET_TIMEZONE]
   601  	}
   602  
   603  	var ret []byte
   604  
   605  	if dtype == DATE {
   606  		ret = make([]byte, 3)
   607  
   608  		ret[0] = (byte)(year & 0xFF)
   609  
   610  		if year >= 0 {
   611  			ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
   612  		} else {
   613  			ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
   614  		}
   615  
   616  		ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
   617  	} else if dtype == DATETIME {
   618  		ret = make([]byte, 8)
   619  
   620  		ret[0] = (byte)(year & 0xFF)
   621  
   622  		if year >= 0 {
   623  			ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
   624  		} else {
   625  			ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
   626  		}
   627  
   628  		ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
   629  
   630  		ret[3] = (byte)(hour | ((min & 0x07) << 5))
   631  
   632  		ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
   633  
   634  		ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
   635  
   636  		ret[6] = (byte)((msec >> 7) & 0xFF)
   637  
   638  		ret[7] = (byte)((msec >> 15) & 0xFF)
   639  	} else if dtype == DATETIME_TZ {
   640  		ret = make([]byte, 10)
   641  
   642  		ret[0] = (byte)(year & 0xFF)
   643  
   644  		if year >= 0 {
   645  			ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
   646  		} else {
   647  			ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
   648  		}
   649  
   650  		ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
   651  
   652  		ret[3] = (byte)(hour | ((min & 0x07) << 5))
   653  
   654  		ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
   655  
   656  		ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
   657  
   658  		ret[6] = (byte)((msec >> 7) & 0xFF)
   659  
   660  		ret[7] = (byte)((msec >> 15) & 0xFF)
   661  
   662  		Dm_build_1.Dm_build_12(ret, 8, int16(tz))
   663  	} else if dtype == TIME {
   664  		ret = make([]byte, 5)
   665  
   666  		ret[0] = (byte)(hour | ((min & 0x07) << 5))
   667  
   668  		ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
   669  
   670  		ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
   671  
   672  		ret[3] = (byte)((msec >> 7) & 0xFF)
   673  
   674  		ret[4] = (byte)((msec >> 15) & 0xFF)
   675  	} else if dtype == TIME_TZ {
   676  		ret = make([]byte, 7)
   677  
   678  		ret[0] = (byte)(hour | ((min & 0x07) << 5))
   679  
   680  		ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
   681  
   682  		ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
   683  
   684  		ret[3] = (byte)((msec >> 7) & 0xFF)
   685  
   686  		ret[4] = (byte)((msec >> 15) & 0xFF)
   687  
   688  		Dm_build_1.Dm_build_12(ret, 5, int16(tz))
   689  	}
   690  
   691  	return ret, nil
   692  }
   693  
   694  func checkDate(year int, month int, day int) bool {
   695  	if year > 9999 || year < -4712 || month > 12 || month < 1 {
   696  		return false
   697  	}
   698  
   699  	monthDays := getDaysOfMonth(year, month)
   700  	if day > monthDays || day < 1 {
   701  		return false
   702  	}
   703  	return true
   704  }
   705  
   706  func getDaysOfMonth(year int, month int) int {
   707  	switch month {
   708  	case 1, 3, 5, 7, 8, 10, 12:
   709  		return 31
   710  	case 4, 6, 9, 11:
   711  		return 30
   712  	case 2:
   713  		if isLeapYear(year) {
   714  			return 29
   715  		}
   716  		return 28
   717  	default:
   718  		return 0
   719  	}
   720  }
   721  
   722  func isLeapYear(year int) bool {
   723  	return ((year%4 == 0 && year%100 != 0) || year%400 == 0)
   724  }
   725  
   726  func addYear(dt []int, n int) []int {
   727  	dt[OFFSET_YEAR] += n
   728  	return dt
   729  }
   730  
   731  func addMonth(dt []int, n int) []int {
   732  	month := dt[OFFSET_MONTH] + n
   733  	addYearValue := month / 12
   734  	if month %= 12; month < 1 {
   735  		month += 12
   736  		addYearValue--
   737  	}
   738  
   739  	daysOfMonth := getDaysOfMonth(dt[OFFSET_YEAR], month)
   740  	if dt[OFFSET_DAY] > daysOfMonth {
   741  		dt[OFFSET_DAY] = daysOfMonth
   742  	}
   743  
   744  	dt[OFFSET_MONTH] = month
   745  	addYear(dt, addYearValue)
   746  	return dt
   747  }
   748  
   749  func addDay(dt []int, n int) []int {
   750  	tmp := dt[OFFSET_DAY] + n
   751  	monthDays := 0
   752  	monthDays = getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH])
   753  	for tmp > monthDays || tmp <= 0 {
   754  		if tmp > monthDays {
   755  			addMonth(dt, 1)
   756  			tmp -= monthDays
   757  		} else {
   758  			addMonth(dt, -1)
   759  			tmp += monthDays
   760  		}
   761  	}
   762  	dt[OFFSET_DAY] = tmp
   763  	return dt
   764  }
   765  
   766  func addHour(dt []int, n int) []int {
   767  	hour := dt[OFFSET_HOUR] + n
   768  	addDayValue := hour / 24
   769  	if hour %= 24; hour < 0 {
   770  		hour += 24
   771  		addDayValue--
   772  	}
   773  
   774  	dt[OFFSET_HOUR] = hour
   775  	addDay(dt, addDayValue)
   776  	return dt
   777  }
   778  
   779  func addMinute(dt []int, n int) []int {
   780  	minute := dt[OFFSET_MINUTE] + n
   781  	addHourValue := minute / 60
   782  	if minute %= 60; minute < 0 {
   783  		minute += 60
   784  		addHourValue--
   785  	}
   786  
   787  	dt[OFFSET_MINUTE] = minute
   788  	addHour(dt, addHourValue)
   789  	return dt
   790  }