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