gitee.com/chunanyong/dm@v1.8.12/zs.go (about)

     1  /*
     2   * Copyright (c) 2000-2018, 达梦数据库有限公司.
     3   * All rights reserved.
     4   */
     5  
     6  package dm
     7  
     8  import (
     9  	"fmt"
    10  	"math"
    11  	"strconv"
    12  	"strings"
    13  	"time"
    14  	"unicode"
    15  	"unicode/utf8"
    16  
    17  	"gitee.com/chunanyong/dm/util"
    18  )
    19  
    20  type oracleDateFormat struct {
    21  	PM                bool
    22  	TZNegative        bool
    23  	pattern           string
    24  	language          int
    25  	scale             int32
    26  	FormatElementList []interface{}
    27  	YearElement       yearElement
    28  	MonthElement      monthElement
    29  	MonElement        monElement
    30  	MMElement         mmElement
    31  	DDElement         ddElement
    32  	HH24Element       hh24Element
    33  	HH12Element       hh12Element
    34  	MIElement         miElement
    35  	SSElement         ssElement
    36  	FElement          fElement
    37  	TZHElement        tzhElement
    38  	TZMElement        tzmElement
    39  	AMElement         amElement
    40  }
    41  
    42  type element interface {
    43  	/**
    44  	 * 从字符串中解析出对应的值,
    45  	 * @param str 完整的字符串
    46  	 * @param offset 当前偏移
    47  	 * @return 解析后的offset
    48  	 */
    49  	parse(str string, offset int, dt []int) (int, error)
    50  
    51  	/**
    52  	 * 将时间值value格式化成字符串
    53  	 */
    54  	format(dt []int) string
    55  }
    56  
    57  type yearElement struct {
    58  	OracleDateFormat *oracleDateFormat
    59  	len              int
    60  }
    61  
    62  func (YearElement yearElement) parse(str string, offset int, dt []int) (int, error) {
    63  	strLen := 0
    64  	for i := offset; i < offset+YearElement.len && i < len(str); i++ {
    65  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
    66  			break
    67  		}
    68  		strLen++
    69  	}
    70  	str = str[offset : offset+strLen]
    71  	if YearElement.len < 4 {
    72  		today := strconv.FormatInt(int64(dt[OFFSET_YEAR]), 10)
    73  		i, err := strconv.ParseInt(today[:4-YearElement.len]+str, 10, 32)
    74  		if err != nil {
    75  			return 0, err
    76  		}
    77  		dt[OFFSET_YEAR] = int(i)
    78  	} else {
    79  		i, err := strconv.ParseInt(str, 10, 32)
    80  		if err != nil {
    81  			return 0, err
    82  		}
    83  		dt[OFFSET_YEAR] = int(i)
    84  	}
    85  
    86  	return offset + strLen, nil
    87  }
    88  
    89  func (YearElement yearElement) format(dt []int) string {
    90  	return YearElement.OracleDateFormat.formatInt(dt[OFFSET_YEAR], YearElement.len)
    91  }
    92  
    93  type monthElement struct {
    94  	OracleDateFormat *oracleDateFormat
    95  	upperCase        bool
    96  	lowerCase        bool
    97  }
    98  
    99  var monthNameList = []string{"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
   100  
   101  func (MonthElement monthElement) parse(str string, offset int, dt []int) (int, error) {
   102  
   103  	if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
   104  		index := strings.IndexRune(str[offset:], '月')
   105  		if index == -1 {
   106  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   107  		}
   108  		index += offset
   109  
   110  		mon, err := strconv.ParseInt(str[offset:index], 10, 32)
   111  		if err != nil {
   112  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   113  		}
   114  
   115  		if mon > 12 || mon < 1 {
   116  			return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   117  		}
   118  		dt[OFFSET_MONTH] = int(mon)
   119  		return index + utf8.RuneLen('月'), nil
   120  	} else {
   121  		str = str[offset:]
   122  		mon := 0
   123  		for i := 1; i < len(monthNameList); i++ {
   124  			if util.StringUtil.StartWithIgnoreCase(str, monthNameList[i]) {
   125  				mon = i
   126  				break
   127  			}
   128  		}
   129  		if mon == 0 {
   130  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   131  		}
   132  		dt[OFFSET_MONTH] = mon
   133  		return offset + len(monthNameList[mon]), nil
   134  	}
   135  }
   136  
   137  func (MonthElement monthElement) format(dt []int) string {
   138  	value := dt[OFFSET_MONTH]
   139  
   140  	if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
   141  		return strconv.FormatInt(int64(value), 10) + "月"
   142  	}
   143  
   144  	if MonthElement.upperCase {
   145  		return strings.ToUpper(monthNameList[value])
   146  	} else if MonthElement.lowerCase {
   147  		return strings.ToLower(monthNameList[value])
   148  	} else {
   149  		return monthNameList[value]
   150  	}
   151  
   152  }
   153  
   154  type monElement struct {
   155  	OracleDateFormat *oracleDateFormat
   156  	upperCase        bool
   157  	lowerCase        bool
   158  }
   159  
   160  var monNameList []string = []string{"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
   161  
   162  func (MonElement monElement) parse(str string, offset int, dt []int) (int, error) {
   163  
   164  	if MonElement.OracleDateFormat.language == LANGUAGE_CN {
   165  		index := strings.IndexRune(str[offset:], '月') + offset
   166  		if index == -1+offset {
   167  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   168  		}
   169  
   170  		mon, err := strconv.ParseInt(str[offset:index], 10, 32)
   171  		if err != nil {
   172  			return -1, err
   173  		}
   174  
   175  		if mon > 12 || mon < 1 {
   176  			return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   177  		}
   178  		dt[OFFSET_MONTH] = int(mon)
   179  		return index + utf8.RuneLen('月'), nil
   180  	} else {
   181  		str = str[offset : offset+3]
   182  		mon := 0
   183  		for i := 1; i < len(monNameList); i++ {
   184  			if util.StringUtil.EqualsIgnoreCase(str, monNameList[i]) {
   185  				mon = i
   186  				break
   187  			}
   188  		}
   189  		if mon == 0 {
   190  			return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   191  		}
   192  		dt[OFFSET_MONTH] = mon
   193  		return offset + 3, nil
   194  	}
   195  
   196  }
   197  
   198  func (MonElement monElement) format(dt []int) string {
   199  	value := dt[OFFSET_MONTH]
   200  	language := int(0)
   201  	if language == LANGUAGE_CN {
   202  		return strconv.FormatInt(int64(value), 10) + "月"
   203  	}
   204  
   205  	if MonElement.upperCase {
   206  		return strings.ToUpper(monNameList[value])
   207  	} else if MonElement.lowerCase {
   208  		return strings.ToLower(monNameList[value])
   209  	} else {
   210  		return monNameList[value]
   211  	}
   212  }
   213  
   214  type mmElement struct {
   215  	OracleDateFormat *oracleDateFormat
   216  }
   217  
   218  func (MMElement mmElement) parse(str string, offset int, dt []int) (int, error) {
   219  	strLen := 0
   220  	for i := offset; i < offset+2 && i < len(str); i++ {
   221  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   222  			break
   223  		}
   224  		strLen++
   225  	}
   226  	str = str[offset : offset+strLen]
   227  	month, err := strconv.ParseInt(str, 10, 32)
   228  	if err != nil {
   229  		return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
   230  	}
   231  
   232  	if month > 12 || month < 1 {
   233  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   234  	}
   235  	dt[OFFSET_MONTH] = int(month)
   236  	return offset + strLen, nil
   237  }
   238  
   239  func (MMElement mmElement) format(dt []int) string {
   240  	return MMElement.OracleDateFormat.formatInt(dt[OFFSET_MONTH], 2)
   241  }
   242  
   243  type ddElement struct {
   244  	OracleDateFormat *oracleDateFormat
   245  }
   246  
   247  func (DDElement ddElement) parse(str string, offset int, dt []int) (int, error) {
   248  	strLen := 0
   249  	for i := offset; i < offset+2 && i < len(str); i++ {
   250  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   251  			break
   252  		}
   253  		strLen++
   254  	}
   255  	str = str[offset : offset+strLen]
   256  	day, err := strconv.ParseInt(str, 10, 32)
   257  	if err != nil {
   258  		return -1, err
   259  	}
   260  
   261  	if day > 31 || day < 1 {
   262  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   263  	}
   264  	dt[OFFSET_DAY] = int(day)
   265  	return offset + strLen, nil
   266  }
   267  
   268  func (DDElement ddElement) format(dt []int) string {
   269  	return DDElement.OracleDateFormat.formatInt(dt[OFFSET_DAY], 2)
   270  }
   271  
   272  type hh24Element struct {
   273  	OracleDateFormat *oracleDateFormat
   274  }
   275  
   276  func (HH24Element hh24Element) parse(str string, offset int, dt []int) (int, error) {
   277  	strLen := 0
   278  	for i := offset; i < offset+2 && i < len(str); i++ {
   279  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   280  			break
   281  		}
   282  		strLen++
   283  	}
   284  	str = str[offset : offset+strLen]
   285  	hour, err := strconv.ParseInt(str, 10, 32)
   286  	if err != nil {
   287  		return -1, err
   288  	}
   289  
   290  	if hour > 23 || hour < 0 {
   291  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   292  	}
   293  	dt[OFFSET_HOUR] = int(hour) // 0-23
   294  	return offset + strLen, nil
   295  }
   296  
   297  func (HH24Element hh24Element) format(dt []int) string {
   298  	return HH24Element.OracleDateFormat.formatInt(dt[OFFSET_HOUR], 2) // 0-23
   299  }
   300  
   301  type hh12Element struct {
   302  	OracleDateFormat *oracleDateFormat
   303  }
   304  
   305  func (HH12Element hh12Element) parse(str string, offset int, dt []int) (int, error) {
   306  	strLen := 0
   307  	for i := offset; i < offset+2 && i < len(str); i++ {
   308  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   309  			break
   310  		}
   311  		strLen++
   312  	}
   313  	str = str[offset : offset+strLen]
   314  	hour, err := strconv.ParseInt(str, 10, 32)
   315  	if err != nil {
   316  		return -1, err
   317  	}
   318  
   319  	if hour > 12 || hour < 1 {
   320  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   321  	}
   322  	dt[OFFSET_HOUR] = int(hour)
   323  	return offset + strLen, nil
   324  }
   325  
   326  func (HH12Element hh12Element) format(dt []int) string {
   327  	var ret string
   328  	value := dt[OFFSET_HOUR]
   329  	if value > 12 || value == 0 {
   330  		ret = HH12Element.OracleDateFormat.formatInt(int(math.Abs(float64(value-12))), 2) // 1-12
   331  	} else {
   332  		ret = HH12Element.OracleDateFormat.formatInt(value, 2)
   333  	}
   334  	return ret
   335  }
   336  
   337  type miElement struct {
   338  	OracleDateFormat *oracleDateFormat
   339  }
   340  
   341  func (MIElement miElement) parse(str string, offset int, dt []int) (int, error) {
   342  	strLen := 0
   343  	for i := offset; i < offset+2 && i < len(str); i++ {
   344  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   345  			break
   346  		}
   347  		strLen++
   348  	}
   349  	str = str[offset : offset+strLen]
   350  	minute, err := strconv.ParseInt(str, 10, 32)
   351  	if err != nil {
   352  		return -1, err
   353  	}
   354  
   355  	if minute > 59 || minute < 0 {
   356  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   357  	}
   358  	dt[OFFSET_MINUTE] = int(minute) // 0-59
   359  	return offset + strLen, nil
   360  }
   361  
   362  func (MIElement miElement) format(dt []int) string {
   363  	return MIElement.OracleDateFormat.formatInt(dt[OFFSET_MINUTE], 2) // 0-59
   364  }
   365  
   366  type ssElement struct {
   367  	OracleDateFormat *oracleDateFormat
   368  }
   369  
   370  func (SSElement ssElement) parse(str string, offset int, dt []int) (int, error) {
   371  	strLen := 0
   372  	for i := offset; i < offset+2 && i < len(str); i++ {
   373  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   374  			break
   375  		}
   376  		strLen++
   377  	}
   378  	str = str[offset : offset+strLen]
   379  	second, err := strconv.ParseInt(str, 10, 32)
   380  	if err != nil {
   381  		return -1, err
   382  	}
   383  
   384  	if second > 59 || second < 0 {
   385  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   386  	}
   387  	dt[OFFSET_SECOND] = int(second) // 0-59
   388  	return offset + strLen, nil
   389  }
   390  
   391  func (SSElement ssElement) format(dt []int) string {
   392  	return SSElement.OracleDateFormat.formatInt(dt[OFFSET_SECOND], 2) // 0-59
   393  }
   394  
   395  type fElement struct {
   396  	OracleDateFormat *oracleDateFormat
   397  	len              int
   398  }
   399  
   400  func (FElement fElement) parse(str string, offset int, dt []int) (int, error) {
   401  	strLen := 0
   402  	maxLen := 0
   403  	if FElement.len > 0 {
   404  		maxLen = FElement.len
   405  	} else {
   406  		maxLen = NANOSECOND_DIGITS
   407  	}
   408  	for i := offset; i < offset+maxLen && i < len(str); i++ {
   409  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   410  			break
   411  		}
   412  		strLen++
   413  	}
   414  	str = str[offset : offset+strLen]
   415  	ms, err := strconv.ParseInt(str, 10, 32)
   416  	if err != nil {
   417  		return -1, err
   418  	}
   419  
   420  	if strLen < NANOSECOND_DIGITS {
   421  		ms *= int64(math.Pow10(NANOSECOND_DIGITS - strLen))
   422  	} else {
   423  		ms /= int64(math.Pow10(strLen - NANOSECOND_DIGITS))
   424  	}
   425  
   426  	dt[OFFSET_NANOSECOND] = int(ms)
   427  	return offset + strLen, nil
   428  }
   429  
   430  func (FElement fElement) format(dt []int) string {
   431  	msgLen := 0
   432  	if FElement.len > 0 {
   433  		msgLen = FElement.len
   434  	} else {
   435  		msgLen = int(FElement.OracleDateFormat.scale)
   436  	}
   437  	return FElement.OracleDateFormat.formatMilliSecond(dt[OFFSET_NANOSECOND], msgLen)
   438  }
   439  
   440  type tzhElement struct {
   441  	OracleDateFormat *oracleDateFormat
   442  }
   443  
   444  func (TZHElement tzhElement) parse(str string, offset int, dt []int) (int, error) {
   445  	if str[offset] == '+' {
   446  		offset += 1
   447  	} else if str[offset] == '-' {
   448  		offset += 1
   449  		TZHElement.OracleDateFormat.TZNegative = true
   450  	}
   451  
   452  	strLen := 0
   453  	for i := offset; i < offset+2 && i < len(str); i++ {
   454  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   455  			break
   456  		}
   457  		strLen++
   458  	}
   459  	str = str[offset : offset+strLen]
   460  
   461  	tzh, err := strconv.ParseInt(str, 10, 32)
   462  	if err != nil {
   463  		return -1, err
   464  	}
   465  
   466  	if tzh > 23 || tzh < 0 {
   467  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   468  	}
   469  
   470  	tzh *= 60
   471  	if dt[OFFSET_TIMEZONE] == int(INVALID_VALUE) {
   472  		dt[OFFSET_TIMEZONE] = int(tzh)
   473  	} else {
   474  		dt[OFFSET_TIMEZONE] += int(tzh)
   475  	}
   476  
   477  	return offset + strLen, nil
   478  }
   479  
   480  func (TZHElement tzhElement) format(dt []int) string {
   481  	var value int
   482  	if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
   483  		value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) / 60
   484  	} else {
   485  		value = 0
   486  	}
   487  
   488  	return TZHElement.OracleDateFormat.formatInt(value, 2)
   489  }
   490  
   491  type tzmElement struct {
   492  	OracleDateFormat *oracleDateFormat
   493  }
   494  
   495  func (TZMElement tzmElement) parse(str string, offset int, dt []int) (int, error) {
   496  	if str[offset] == '+' {
   497  		offset += 1
   498  	} else if str[offset] == '-' {
   499  		offset += 1
   500  		TZMElement.OracleDateFormat.TZNegative = true
   501  	}
   502  
   503  	strLen := 0
   504  	for i := offset; i < offset+2 && i < len(str); i++ {
   505  		if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
   506  			break
   507  		}
   508  		strLen++
   509  	}
   510  	str = str[offset : offset+strLen]
   511  
   512  	tzm, err := strconv.ParseInt(str, 10, 32)
   513  	if err != nil {
   514  		return -1, err
   515  	}
   516  	if tzm > 59 || tzm < 0 {
   517  		return -1, ECGO_INVALID_DATETIME_VALUE.throw()
   518  	}
   519  
   520  	if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
   521  		dt[OFFSET_TIMEZONE] = int(tzm)
   522  	} else {
   523  		dt[OFFSET_TIMEZONE] += int(tzm)
   524  	}
   525  	return offset + strLen, nil
   526  }
   527  
   528  func (TZMElement tzmElement) format(dt []int) string {
   529  	var value int
   530  	if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
   531  		value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) % 60
   532  	} else {
   533  		value = 0
   534  	}
   535  
   536  	return TZMElement.OracleDateFormat.formatInt(value, 2)
   537  }
   538  
   539  type amElement struct {
   540  	OracleDateFormat *oracleDateFormat
   541  }
   542  
   543  func (AMElement amElement) parse(str string, offset int, dt []int) (int, error) {
   544  	runeStr := ([]rune(str))[offset : offset+2]
   545  
   546  	if AMElement.OracleDateFormat.language == LANGUAGE_CN {
   547  		if util.StringUtil.EqualsIgnoreCase("下午", string(runeStr)) {
   548  			AMElement.OracleDateFormat.PM = true
   549  			return offset + utf8.RuneLen('下') + utf8.RuneLen('午'), nil
   550  		} else {
   551  			AMElement.OracleDateFormat.PM = false
   552  			return offset + utf8.RuneLen('上') + utf8.RuneLen('午'), nil
   553  		}
   554  
   555  	} else if util.StringUtil.EqualsIgnoreCase("PM", string(runeStr)) {
   556  		AMElement.OracleDateFormat.PM = true
   557  	} else {
   558  		AMElement.OracleDateFormat.PM = false
   559  	}
   560  
   561  	return offset + 2, nil
   562  }
   563  
   564  func (AMElement amElement) format(dt []int) string {
   565  	hour := dt[OFFSET_HOUR]
   566  	language := int(0)
   567  	if language == LANGUAGE_CN {
   568  		if hour > 12 {
   569  			return "下午"
   570  		} else {
   571  			return "上午"
   572  		}
   573  	}
   574  
   575  	if hour > 12 {
   576  		return "PM"
   577  	} else {
   578  		return "AM"
   579  	}
   580  }
   581  
   582  /**
   583   * 将int值格式化成指定长度,长度不足前面补0,长度超过的取末尾指定长度
   584   */
   585  func (OracleDateFormat *oracleDateFormat) formatInt(value int, len int) string {
   586  	pow := int(math.Pow10(len))
   587  	if value >= pow {
   588  		value %= pow
   589  	}
   590  	value += pow
   591  	return strconv.FormatInt(int64(value), 10)[1:]
   592  }
   593  
   594  /**
   595   * 格式化毫秒值
   596   * @param ms
   597   * @param len <= 6
   598   */
   599  func (OracleDateFormat *oracleDateFormat) formatMilliSecond(ms int, len int) string {
   600  	var ret string
   601  	if ms < 10 {
   602  		ret = "00000" + strconv.FormatInt(int64(ms), 10)
   603  	} else if ms < 100 {
   604  		ret = "0000" + strconv.FormatInt(int64(ms), 10)
   605  	} else if ms < 1000 {
   606  		ret = "000" + strconv.FormatInt(int64(ms), 10)
   607  	} else if ms < 10000 {
   608  		ret = "00" + strconv.FormatInt(int64(ms), 10)
   609  	} else if ms < 100000 {
   610  		ret = "0" + strconv.FormatInt(int64(ms), 10)
   611  	} else {
   612  		ret = strconv.FormatInt(int64(ms), 10)
   613  	}
   614  
   615  	if len < 6 {
   616  		ret = ret[:len]
   617  	}
   618  	return ret
   619  }
   620  
   621  func getFormat() *oracleDateFormat {
   622  	format := new(oracleDateFormat)
   623  	format.PM = false
   624  	format.TZNegative = false
   625  	format.YearElement = yearElement{format, 4}
   626  	format.MonthElement = monthElement{format, false, false}
   627  	format.MonElement = monElement{format, false, false}
   628  	format.MMElement = mmElement{format}
   629  	format.DDElement = ddElement{format}
   630  	format.HH24Element = hh24Element{format}
   631  	format.HH12Element = hh12Element{format}
   632  	format.MIElement = miElement{format}
   633  	format.SSElement = ssElement{format}
   634  	format.FElement = fElement{format, -1}
   635  	format.TZHElement = tzhElement{format}
   636  	format.TZMElement = tzmElement{format}
   637  	format.AMElement = amElement{format}
   638  
   639  	return format
   640  }
   641  
   642  func (OracleDateFormat *oracleDateFormat) parse(str string) (ret []int, err error) {
   643  	defer func() {
   644  		if p := recover(); p != nil {
   645  			err = ECGO_INVALID_DATETIME_FORMAT.throw()
   646  		}
   647  	}()
   648  	OracleDateFormat.TZNegative = false
   649  	OracleDateFormat.PM = false
   650  	dt := make([]int, DT_LEN)
   651  	// oracle默认年月日为 当前时间
   652  	today := time.Now()
   653  	dt[OFFSET_YEAR] = today.Year()
   654  	dt[OFFSET_MONTH] = int(today.Month())
   655  	dt[OFFSET_DAY] = today.Day()
   656  	dt[OFFSET_TIMEZONE] = INVALID_VALUE
   657  	offset := 0
   658  	str = strings.TrimSpace(str)
   659  	for _, obj := range OracleDateFormat.FormatElementList {
   660  		// 跳过空格
   661  		for str[offset] == ' ' && fmt.Sprintf("%+v", obj) != " " {
   662  			offset++
   663  		}
   664  		if e, ok := obj.(element); ok {
   665  			offset, err = e.parse(str, offset, dt)
   666  			if err != nil {
   667  				return nil, err
   668  			}
   669  		} else {
   670  			offset += len(obj.(string))
   671  		}
   672  	}
   673  	if offset < len(str) {
   674  		//[6103]:文字与格式字符串不匹配.
   675  		return nil, ECGO_INVALID_DATETIME_VALUE.throw()
   676  	}
   677  
   678  	// 12小时制时间转换
   679  	if OracleDateFormat.PM {
   680  		dt[OFFSET_HOUR] = (dt[OFFSET_HOUR] + 12) % 24
   681  	}
   682  
   683  	// 时区符号保留
   684  	if OracleDateFormat.TZNegative {
   685  		dt[OFFSET_TIMEZONE] = -dt[OFFSET_TIMEZONE]
   686  	}
   687  
   688  	// check day
   689  	if dt[OFFSET_DAY] > getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH]) || dt[OFFSET_DAY] < 1 {
   690  		return nil, ECGO_INVALID_DATETIME_VALUE.throw()
   691  	}
   692  	// check timezone 兼容oracle
   693  	if dt[OFFSET_TIMEZONE] != INVALID_VALUE && (dt[OFFSET_TIMEZONE] > 14*60 || dt[OFFSET_TIMEZONE] <= -13*60) {
   694  		return nil, ECGO_INVALID_DATETIME_VALUE.throw()
   695  	}
   696  	return dt, nil
   697  }
   698  
   699  func parse(str string, pattern string, language int) ([]int, error) {
   700  	f := getFormat()
   701  	f.setPattern(pattern)
   702  	f.language = language
   703  	return f.parse(str)
   704  }
   705  
   706  func (OracleDateFormat *oracleDateFormat) setPattern(pattern string) {
   707  	if pattern != OracleDateFormat.pattern {
   708  		OracleDateFormat.pattern = pattern
   709  		OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:0]
   710  		OracleDateFormat.analysePattern(pattern)
   711  	}
   712  }
   713  
   714  func format(dt []int, pattern string, scale int32, language int) string {
   715  	f := getFormat()
   716  	f.setPattern(pattern)
   717  	f.language = language
   718  	f.scale = scale
   719  	ret := f.format(dt)
   720  	return ret
   721  }
   722  
   723  func (OracleDateFormat *oracleDateFormat) format(dt []int) string {
   724  	sf := strings.Builder{}
   725  	tzStart := false
   726  	for _, obj := range OracleDateFormat.FormatElementList {
   727  		_, ok1 := obj.(tzhElement)
   728  		_, ok2 := obj.(tzmElement)
   729  		if !tzStart && (ok1 || ok2) {
   730  			tzStart = true
   731  			if dt[OFFSET_TIMEZONE] < 0 {
   732  				sf.WriteString("-")
   733  			} else {
   734  				sf.WriteString("+")
   735  			}
   736  		}
   737  
   738  		if e, ok := obj.(element); ok {
   739  			sf.WriteString(e.format(dt))
   740  		} else {
   741  			sf.WriteString(obj.(string))
   742  		}
   743  	}
   744  	return sf.String()
   745  }
   746  
   747  /**
   748   * 解析格式串
   749   */
   750  func (OracleDateFormat *oracleDateFormat) analysePattern(pattern string) ([]interface{}, error) {
   751  
   752  	// 按分隔符split
   753  	pattern = strings.TrimSpace(pattern)
   754  	l := len(pattern)
   755  	var splitPatterns []string
   756  	starti := 0
   757  	var curChar rune
   758  	for i := 0; i < l; i++ {
   759  		curChar = rune(pattern[i])
   760  		if !unicode.IsDigit(curChar) && !unicode.IsLetter(curChar) {
   761  			if i > starti {
   762  				splitPatterns = append(splitPatterns, pattern[starti:i])
   763  			}
   764  
   765  			splitPatterns = append(splitPatterns, string(curChar))
   766  			starti = i + 1
   767  		} else if i == l-1 {
   768  			splitPatterns = append(splitPatterns, pattern[starti:i+1])
   769  		}
   770  	}
   771  
   772  	// 每个串按照从完整串,然后依次去掉一个末尾字符 来进行尝试规约
   773  	for _, subPattern := range splitPatterns {
   774  		if len(subPattern) != 1 || unicode.IsDigit(rune(subPattern[0])) || unicode.IsLetter(rune(subPattern[0])) {
   775  			fmtWord := subPattern
   776  			for subPattern != "" {
   777  				i := len(subPattern)
   778  				for ; i > 0; i-- {
   779  					fmtWord = subPattern[0:i]
   780  					element, err := OracleDateFormat.getFormatElement(fmtWord)
   781  					if err != nil {
   782  						return nil, err
   783  					}
   784  					if element != nil {
   785  						// 忽略时区前面的+-号
   786  						if element == OracleDateFormat.TZHElement || element == OracleDateFormat.TZMElement {
   787  							var lastFormatElement string = OracleDateFormat.FormatElementList[len(OracleDateFormat.FormatElementList)-1].(string)
   788  							if util.StringUtil.Equals("+", lastFormatElement) || util.StringUtil.Equals("-", lastFormatElement) {
   789  								OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:len(OracleDateFormat.FormatElementList)-2]
   790  							}
   791  						}
   792  						OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, element)
   793  						if i == len(subPattern) {
   794  							subPattern = ""
   795  						} else {
   796  							subPattern = subPattern[i:len(subPattern)]
   797  						}
   798  						break
   799  					}
   800  				}
   801  
   802  				if i == 0 {
   803  					// 非标识符串
   804  					OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
   805  					break
   806  				}
   807  			}
   808  
   809  		} else {
   810  			OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
   811  		}
   812  	}
   813  	return OracleDateFormat.FormatElementList, nil
   814  }
   815  
   816  func (OracleDateFormat *oracleDateFormat) getFormatElement(word string) (element, error) {
   817  	if util.StringUtil.EqualsIgnoreCase("HH", word) || util.StringUtil.EqualsIgnoreCase("HH12", word) {
   818  		return OracleDateFormat.HH12Element, nil
   819  	} else if util.StringUtil.EqualsIgnoreCase("HH24", word) {
   820  		return OracleDateFormat.HH24Element, nil
   821  	} else if util.StringUtil.EqualsIgnoreCase("MI", word) {
   822  		return OracleDateFormat.MIElement, nil
   823  	} else if util.StringUtil.EqualsIgnoreCase("SS", word) {
   824  		return OracleDateFormat.SSElement, nil
   825  	} else if util.StringUtil.EqualsIgnoreCase("AM", word) || util.StringUtil.EqualsIgnoreCase("A.M.", word) || util.StringUtil.EqualsIgnoreCase("PM", word) || util.StringUtil.EqualsIgnoreCase("P.M.", word) {
   826  		return OracleDateFormat.AMElement, nil
   827  	} else if util.StringUtil.Equals("MONTH", word) {
   828  		OracleDateFormat.MonthElement.upperCase = true
   829  		OracleDateFormat.MonthElement.lowerCase = false
   830  		return OracleDateFormat.MonthElement, nil
   831  	} else if util.StringUtil.Equals("month", word) {
   832  		OracleDateFormat.MonthElement.upperCase = false
   833  		OracleDateFormat.MonthElement.lowerCase = true
   834  		return OracleDateFormat.MonthElement, nil
   835  	} else if util.StringUtil.EqualsIgnoreCase("Month", word) {
   836  		OracleDateFormat.MonthElement.upperCase = false
   837  		OracleDateFormat.MonthElement.lowerCase = false
   838  		return OracleDateFormat.MonthElement, nil
   839  	} else if util.StringUtil.Equals("MON", word) {
   840  		OracleDateFormat.MonElement.upperCase = true
   841  		OracleDateFormat.MonElement.lowerCase = false
   842  		return OracleDateFormat.MonElement, nil
   843  	} else if util.StringUtil.Equals("mon", word) {
   844  		OracleDateFormat.MonElement.upperCase = false
   845  		OracleDateFormat.MonElement.lowerCase = true
   846  		return OracleDateFormat.MonElement, nil
   847  	} else if util.StringUtil.EqualsIgnoreCase("Mon", word) {
   848  		OracleDateFormat.MonElement.upperCase = false
   849  		OracleDateFormat.MonElement.lowerCase = false
   850  		return OracleDateFormat.MonElement, nil
   851  	} else if util.StringUtil.EqualsIgnoreCase("MM", word) {
   852  		return OracleDateFormat.MMElement, nil
   853  	} else if util.StringUtil.EqualsIgnoreCase("DD", word) {
   854  		return OracleDateFormat.DDElement, nil
   855  	} else if util.StringUtil.EqualsIgnoreCase("TZH", word) {
   856  		return OracleDateFormat.TZHElement, nil
   857  	} else if util.StringUtil.EqualsIgnoreCase("TZM", word) {
   858  		return OracleDateFormat.TZMElement, nil
   859  	} else if strings.Index(word, "Y") == 0 || strings.Index(word, "y") == 0 {
   860  		OracleDateFormat.YearElement.len = len(word)
   861  		return OracleDateFormat.YearElement, nil
   862  	} else if strings.Index(word, "F") == 0 || strings.Index(word, "f") == 0 {
   863  
   864  		word = strings.ToUpper(word)
   865  		numIndex := strings.LastIndex(word, "F") + 1
   866  		var count int64
   867  		var err error
   868  		if numIndex < len(word) {
   869  			count, err = strconv.ParseInt(word[numIndex:len(word)], 10, 32)
   870  			if err != nil {
   871  				return nil, err
   872  			}
   873  		} else {
   874  			count = -1
   875  		}
   876  
   877  		OracleDateFormat.FElement.len = int(count)
   878  		return OracleDateFormat.FElement, nil
   879  	}
   880  
   881  	return nil, nil
   882  }