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 }