github.com/wanlay/gorm-dm8@v1.0.5/dmr/zs.go (about)

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