github.com/xiyichan/dm8@v0.0.0-20211213021639-be727be3e136/zr.go (about)

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