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

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