7f7b585ffb
- 在应用程序中新增对达梦数据库(DM)的配置和连接支持 - 实现 SetDmDB 函数以配置达梦数据库连接 - 更新数据库操作逻辑,支持达梦特有的 SQL 语法和功能 - 在相关文件中添加达梦数据库的处理逻辑,包括表创建、数据插入和查询 - 更新 go.mod 和 go.sum 文件以引入达梦数据库驱动 - 增强文档,详细说明达梦数据库的配置和使用方法
883 lines
23 KiB
Go
883 lines
23 KiB
Go
/*
|
|
* Copyright (c) 2000-2018, 达梦数据库有限公司.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
package dm
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
|
|
"gitee.com/chunanyong/dm/util"
|
|
)
|
|
|
|
type oracleDateFormat struct {
|
|
PM bool
|
|
TZNegative bool
|
|
pattern string
|
|
language int
|
|
scale int32
|
|
FormatElementList []interface{}
|
|
YearElement yearElement
|
|
MonthElement monthElement
|
|
MonElement monElement
|
|
MMElement mmElement
|
|
DDElement ddElement
|
|
HH24Element hh24Element
|
|
HH12Element hh12Element
|
|
MIElement miElement
|
|
SSElement ssElement
|
|
FElement fElement
|
|
TZHElement tzhElement
|
|
TZMElement tzmElement
|
|
AMElement amElement
|
|
}
|
|
|
|
type element interface {
|
|
/**
|
|
* 从字符串中解析出对应的值,
|
|
* @param str 完整的字符串
|
|
* @param offset 当前偏移
|
|
* @return 解析后的offset
|
|
*/
|
|
parse(str string, offset int, dt []int) (int, error)
|
|
|
|
/**
|
|
* 将时间值value格式化成字符串
|
|
*/
|
|
format(dt []int) string
|
|
}
|
|
|
|
type yearElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
len int
|
|
}
|
|
|
|
func (YearElement yearElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+YearElement.len && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
if YearElement.len < 4 {
|
|
today := strconv.FormatInt(int64(dt[OFFSET_YEAR]), 10)
|
|
i, err := strconv.ParseInt(today[:4-YearElement.len]+str, 10, 32)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
dt[OFFSET_YEAR] = int(i)
|
|
} else {
|
|
i, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
dt[OFFSET_YEAR] = int(i)
|
|
}
|
|
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (YearElement yearElement) format(dt []int) string {
|
|
return YearElement.OracleDateFormat.formatInt(dt[OFFSET_YEAR], YearElement.len)
|
|
}
|
|
|
|
type monthElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
upperCase bool
|
|
lowerCase bool
|
|
}
|
|
|
|
var monthNameList = []string{"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
|
|
|
func (MonthElement monthElement) parse(str string, offset int, dt []int) (int, error) {
|
|
|
|
if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
|
|
index := strings.IndexRune(str[offset:], '月')
|
|
if index == -1 {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
index += offset
|
|
|
|
mon, err := strconv.ParseInt(str[offset:index], 10, 32)
|
|
if err != nil {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
|
|
if mon > 12 || mon < 1 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_MONTH] = int(mon)
|
|
return index + utf8.RuneLen('月'), nil
|
|
} else {
|
|
str = str[offset:]
|
|
mon := 0
|
|
for i := 1; i < len(monthNameList); i++ {
|
|
if util.StringUtil.StartWithIgnoreCase(str, monthNameList[i]) {
|
|
mon = i
|
|
break
|
|
}
|
|
}
|
|
if mon == 0 {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
dt[OFFSET_MONTH] = mon
|
|
return offset + len(monthNameList[mon]), nil
|
|
}
|
|
}
|
|
|
|
func (MonthElement monthElement) format(dt []int) string {
|
|
value := dt[OFFSET_MONTH]
|
|
|
|
if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
|
|
return strconv.FormatInt(int64(value), 10) + "月"
|
|
}
|
|
|
|
if MonthElement.upperCase {
|
|
return strings.ToUpper(monthNameList[value])
|
|
} else if MonthElement.lowerCase {
|
|
return strings.ToLower(monthNameList[value])
|
|
} else {
|
|
return monthNameList[value]
|
|
}
|
|
|
|
}
|
|
|
|
type monElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
upperCase bool
|
|
lowerCase bool
|
|
}
|
|
|
|
var monNameList []string = []string{"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
|
|
|
|
func (MonElement monElement) parse(str string, offset int, dt []int) (int, error) {
|
|
|
|
if MonElement.OracleDateFormat.language == LANGUAGE_CN {
|
|
index := strings.IndexRune(str[offset:], '月') + offset
|
|
if index == -1+offset {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
|
|
mon, err := strconv.ParseInt(str[offset:index], 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if mon > 12 || mon < 1 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_MONTH] = int(mon)
|
|
return index + utf8.RuneLen('月'), nil
|
|
} else {
|
|
str = str[offset : offset+3]
|
|
mon := 0
|
|
for i := 1; i < len(monNameList); i++ {
|
|
if util.StringUtil.EqualsIgnoreCase(str, monNameList[i]) {
|
|
mon = i
|
|
break
|
|
}
|
|
}
|
|
if mon == 0 {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
dt[OFFSET_MONTH] = mon
|
|
return offset + 3, nil
|
|
}
|
|
|
|
}
|
|
|
|
func (MonElement monElement) format(dt []int) string {
|
|
value := dt[OFFSET_MONTH]
|
|
language := int(0)
|
|
if language == LANGUAGE_CN {
|
|
return strconv.FormatInt(int64(value), 10) + "月"
|
|
}
|
|
|
|
if MonElement.upperCase {
|
|
return strings.ToUpper(monNameList[value])
|
|
} else if MonElement.lowerCase {
|
|
return strings.ToLower(monNameList[value])
|
|
} else {
|
|
return monNameList[value]
|
|
}
|
|
}
|
|
|
|
type mmElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (MMElement mmElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
month, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
|
|
if month > 12 || month < 1 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_MONTH] = int(month)
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (MMElement mmElement) format(dt []int) string {
|
|
return MMElement.OracleDateFormat.formatInt(dt[OFFSET_MONTH], 2)
|
|
}
|
|
|
|
type ddElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (DDElement ddElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
day, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if day > 31 || day < 1 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_DAY] = int(day)
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (DDElement ddElement) format(dt []int) string {
|
|
return DDElement.OracleDateFormat.formatInt(dt[OFFSET_DAY], 2)
|
|
}
|
|
|
|
type hh24Element struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (HH24Element hh24Element) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
hour, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if hour > 23 || hour < 0 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_HOUR] = int(hour) // 0-23
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (HH24Element hh24Element) format(dt []int) string {
|
|
return HH24Element.OracleDateFormat.formatInt(dt[OFFSET_HOUR], 2) // 0-23
|
|
}
|
|
|
|
type hh12Element struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (HH12Element hh12Element) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
hour, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if hour > 12 || hour < 1 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_HOUR] = int(hour)
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (HH12Element hh12Element) format(dt []int) string {
|
|
var ret string
|
|
value := dt[OFFSET_HOUR]
|
|
if value > 12 || value == 0 {
|
|
ret = HH12Element.OracleDateFormat.formatInt(int(math.Abs(float64(value-12))), 2) // 1-12
|
|
} else {
|
|
ret = HH12Element.OracleDateFormat.formatInt(value, 2)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
type miElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (MIElement miElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
minute, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if minute > 59 || minute < 0 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_MINUTE] = int(minute) // 0-59
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (MIElement miElement) format(dt []int) string {
|
|
return MIElement.OracleDateFormat.formatInt(dt[OFFSET_MINUTE], 2) // 0-59
|
|
}
|
|
|
|
type ssElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (SSElement ssElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
second, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if second > 59 || second < 0 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
dt[OFFSET_SECOND] = int(second) // 0-59
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (SSElement ssElement) format(dt []int) string {
|
|
return SSElement.OracleDateFormat.formatInt(dt[OFFSET_SECOND], 2) // 0-59
|
|
}
|
|
|
|
type fElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
len int
|
|
}
|
|
|
|
func (FElement fElement) parse(str string, offset int, dt []int) (int, error) {
|
|
strLen := 0
|
|
maxLen := 0
|
|
if FElement.len > 0 {
|
|
maxLen = FElement.len
|
|
} else {
|
|
maxLen = NANOSECOND_DIGITS
|
|
}
|
|
for i := offset; i < offset+maxLen && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
ms, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if strLen < NANOSECOND_DIGITS {
|
|
ms *= int64(math.Pow10(NANOSECOND_DIGITS - strLen))
|
|
} else {
|
|
ms /= int64(math.Pow10(strLen - NANOSECOND_DIGITS))
|
|
}
|
|
|
|
dt[OFFSET_NANOSECOND] = int(ms)
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (FElement fElement) format(dt []int) string {
|
|
msgLen := 0
|
|
if FElement.len > 0 {
|
|
msgLen = FElement.len
|
|
} else {
|
|
msgLen = int(FElement.OracleDateFormat.scale)
|
|
}
|
|
return FElement.OracleDateFormat.formatMilliSecond(dt[OFFSET_NANOSECOND], msgLen)
|
|
}
|
|
|
|
type tzhElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (TZHElement tzhElement) parse(str string, offset int, dt []int) (int, error) {
|
|
if str[offset] == '+' {
|
|
offset += 1
|
|
} else if str[offset] == '-' {
|
|
offset += 1
|
|
TZHElement.OracleDateFormat.TZNegative = true
|
|
}
|
|
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
|
|
tzh, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
|
|
if tzh > 23 || tzh < 0 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
|
|
tzh *= 60
|
|
if dt[OFFSET_TIMEZONE] == int(INVALID_VALUE) {
|
|
dt[OFFSET_TIMEZONE] = int(tzh)
|
|
} else {
|
|
dt[OFFSET_TIMEZONE] += int(tzh)
|
|
}
|
|
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (TZHElement tzhElement) format(dt []int) string {
|
|
var value int
|
|
if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
|
|
value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) / 60
|
|
} else {
|
|
value = 0
|
|
}
|
|
|
|
return TZHElement.OracleDateFormat.formatInt(value, 2)
|
|
}
|
|
|
|
type tzmElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (TZMElement tzmElement) parse(str string, offset int, dt []int) (int, error) {
|
|
if str[offset] == '+' {
|
|
offset += 1
|
|
} else if str[offset] == '-' {
|
|
offset += 1
|
|
TZMElement.OracleDateFormat.TZNegative = true
|
|
}
|
|
|
|
strLen := 0
|
|
for i := offset; i < offset+2 && i < len(str); i++ {
|
|
if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
|
|
break
|
|
}
|
|
strLen++
|
|
}
|
|
str = str[offset : offset+strLen]
|
|
|
|
tzm, err := strconv.ParseInt(str, 10, 32)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
if tzm > 59 || tzm < 0 {
|
|
return -1, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
|
|
if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
|
|
dt[OFFSET_TIMEZONE] = int(tzm)
|
|
} else {
|
|
dt[OFFSET_TIMEZONE] += int(tzm)
|
|
}
|
|
return offset + strLen, nil
|
|
}
|
|
|
|
func (TZMElement tzmElement) format(dt []int) string {
|
|
var value int
|
|
if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
|
|
value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) % 60
|
|
} else {
|
|
value = 0
|
|
}
|
|
|
|
return TZMElement.OracleDateFormat.formatInt(value, 2)
|
|
}
|
|
|
|
type amElement struct {
|
|
OracleDateFormat *oracleDateFormat
|
|
}
|
|
|
|
func (AMElement amElement) parse(str string, offset int, dt []int) (int, error) {
|
|
runeStr := ([]rune(str))[offset : offset+2]
|
|
|
|
if AMElement.OracleDateFormat.language == LANGUAGE_CN {
|
|
if util.StringUtil.EqualsIgnoreCase("下午", string(runeStr)) {
|
|
AMElement.OracleDateFormat.PM = true
|
|
return offset + utf8.RuneLen('下') + utf8.RuneLen('午'), nil
|
|
} else {
|
|
AMElement.OracleDateFormat.PM = false
|
|
return offset + utf8.RuneLen('上') + utf8.RuneLen('午'), nil
|
|
}
|
|
|
|
} else if util.StringUtil.EqualsIgnoreCase("PM", string(runeStr)) {
|
|
AMElement.OracleDateFormat.PM = true
|
|
} else {
|
|
AMElement.OracleDateFormat.PM = false
|
|
}
|
|
|
|
return offset + 2, nil
|
|
}
|
|
|
|
func (AMElement amElement) format(dt []int) string {
|
|
hour := dt[OFFSET_HOUR]
|
|
language := int(0)
|
|
if language == LANGUAGE_CN {
|
|
if hour > 12 {
|
|
return "下午"
|
|
} else {
|
|
return "上午"
|
|
}
|
|
}
|
|
|
|
if hour > 12 {
|
|
return "PM"
|
|
} else {
|
|
return "AM"
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将int值格式化成指定长度,长度不足前面补0,长度超过的取末尾指定长度
|
|
*/
|
|
func (OracleDateFormat *oracleDateFormat) formatInt(value int, len int) string {
|
|
pow := int(math.Pow10(len))
|
|
if value >= pow {
|
|
value %= pow
|
|
}
|
|
value += pow
|
|
return strconv.FormatInt(int64(value), 10)[1:]
|
|
}
|
|
|
|
/**
|
|
* 格式化毫秒值
|
|
* @param ms
|
|
* @param len <= 6
|
|
*/
|
|
func (OracleDateFormat *oracleDateFormat) formatMilliSecond(ms int, len int) string {
|
|
var ret string
|
|
if ms < 10 {
|
|
ret = "00000" + strconv.FormatInt(int64(ms), 10)
|
|
} else if ms < 100 {
|
|
ret = "0000" + strconv.FormatInt(int64(ms), 10)
|
|
} else if ms < 1000 {
|
|
ret = "000" + strconv.FormatInt(int64(ms), 10)
|
|
} else if ms < 10000 {
|
|
ret = "00" + strconv.FormatInt(int64(ms), 10)
|
|
} else if ms < 100000 {
|
|
ret = "0" + strconv.FormatInt(int64(ms), 10)
|
|
} else {
|
|
ret = strconv.FormatInt(int64(ms), 10)
|
|
}
|
|
|
|
if len < 6 {
|
|
ret = ret[:len]
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func getFormat() *oracleDateFormat {
|
|
format := new(oracleDateFormat)
|
|
format.PM = false
|
|
format.TZNegative = false
|
|
format.YearElement = yearElement{format, 4}
|
|
format.MonthElement = monthElement{format, false, false}
|
|
format.MonElement = monElement{format, false, false}
|
|
format.MMElement = mmElement{format}
|
|
format.DDElement = ddElement{format}
|
|
format.HH24Element = hh24Element{format}
|
|
format.HH12Element = hh12Element{format}
|
|
format.MIElement = miElement{format}
|
|
format.SSElement = ssElement{format}
|
|
format.FElement = fElement{format, -1}
|
|
format.TZHElement = tzhElement{format}
|
|
format.TZMElement = tzmElement{format}
|
|
format.AMElement = amElement{format}
|
|
|
|
return format
|
|
}
|
|
|
|
func (OracleDateFormat *oracleDateFormat) parse(str string) (ret []int, err error) {
|
|
defer func() {
|
|
if p := recover(); p != nil {
|
|
err = ECGO_INVALID_DATETIME_FORMAT.throw()
|
|
}
|
|
}()
|
|
OracleDateFormat.TZNegative = false
|
|
OracleDateFormat.PM = false
|
|
dt := make([]int, DT_LEN)
|
|
// oracle默认年月日为 当前时间
|
|
today := time.Now()
|
|
dt[OFFSET_YEAR] = today.Year()
|
|
dt[OFFSET_MONTH] = int(today.Month())
|
|
dt[OFFSET_DAY] = today.Day()
|
|
dt[OFFSET_TIMEZONE] = INVALID_VALUE
|
|
offset := 0
|
|
str = strings.TrimSpace(str)
|
|
for _, obj := range OracleDateFormat.FormatElementList {
|
|
// 跳过空格
|
|
for str[offset] == ' ' && fmt.Sprintf("%+v", obj) != " " {
|
|
offset++
|
|
}
|
|
if e, ok := obj.(element); ok {
|
|
offset, err = e.parse(str, offset, dt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
offset += len(obj.(string))
|
|
}
|
|
}
|
|
if offset < len(str) {
|
|
//[6103]:文字与格式字符串不匹配.
|
|
return nil, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
|
|
// 12小时制时间转换
|
|
if OracleDateFormat.PM {
|
|
dt[OFFSET_HOUR] = (dt[OFFSET_HOUR] + 12) % 24
|
|
}
|
|
|
|
// 时区符号保留
|
|
if OracleDateFormat.TZNegative {
|
|
dt[OFFSET_TIMEZONE] = -dt[OFFSET_TIMEZONE]
|
|
}
|
|
|
|
// check day
|
|
if dt[OFFSET_DAY] > getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH]) || dt[OFFSET_DAY] < 1 {
|
|
return nil, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
// check timezone 兼容oracle
|
|
if dt[OFFSET_TIMEZONE] != INVALID_VALUE && (dt[OFFSET_TIMEZONE] > 14*60 || dt[OFFSET_TIMEZONE] <= -13*60) {
|
|
return nil, ECGO_INVALID_DATETIME_VALUE.throw()
|
|
}
|
|
return dt, nil
|
|
}
|
|
|
|
func parse(str string, pattern string, language int) ([]int, error) {
|
|
f := getFormat()
|
|
f.setPattern(pattern)
|
|
f.language = language
|
|
return f.parse(str)
|
|
}
|
|
|
|
func (OracleDateFormat *oracleDateFormat) setPattern(pattern string) {
|
|
if pattern != OracleDateFormat.pattern {
|
|
OracleDateFormat.pattern = pattern
|
|
OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:0]
|
|
OracleDateFormat.analysePattern(pattern)
|
|
}
|
|
}
|
|
|
|
func format(dt []int, pattern string, scale int32, language int) string {
|
|
f := getFormat()
|
|
f.setPattern(pattern)
|
|
f.language = language
|
|
f.scale = scale
|
|
ret := f.format(dt)
|
|
return ret
|
|
}
|
|
|
|
func (OracleDateFormat *oracleDateFormat) format(dt []int) string {
|
|
sf := strings.Builder{}
|
|
tzStart := false
|
|
for _, obj := range OracleDateFormat.FormatElementList {
|
|
_, ok1 := obj.(tzhElement)
|
|
_, ok2 := obj.(tzmElement)
|
|
if !tzStart && (ok1 || ok2) {
|
|
tzStart = true
|
|
if dt[OFFSET_TIMEZONE] < 0 {
|
|
sf.WriteString("-")
|
|
} else {
|
|
sf.WriteString("+")
|
|
}
|
|
}
|
|
|
|
if e, ok := obj.(element); ok {
|
|
sf.WriteString(e.format(dt))
|
|
} else {
|
|
sf.WriteString(obj.(string))
|
|
}
|
|
}
|
|
return sf.String()
|
|
}
|
|
|
|
/**
|
|
* 解析格式串
|
|
*/
|
|
func (OracleDateFormat *oracleDateFormat) analysePattern(pattern string) ([]interface{}, error) {
|
|
|
|
// 按分隔符split
|
|
pattern = strings.TrimSpace(pattern)
|
|
l := len(pattern)
|
|
var splitPatterns []string
|
|
starti := 0
|
|
var curChar rune
|
|
for i := 0; i < l; i++ {
|
|
curChar = rune(pattern[i])
|
|
if !unicode.IsDigit(curChar) && !unicode.IsLetter(curChar) {
|
|
if i > starti {
|
|
splitPatterns = append(splitPatterns, pattern[starti:i])
|
|
}
|
|
|
|
splitPatterns = append(splitPatterns, string(curChar))
|
|
starti = i + 1
|
|
} else if i == l-1 {
|
|
splitPatterns = append(splitPatterns, pattern[starti:i+1])
|
|
}
|
|
}
|
|
|
|
// 每个串按照从完整串,然后依次去掉一个末尾字符 来进行尝试规约
|
|
for _, subPattern := range splitPatterns {
|
|
if len(subPattern) != 1 || unicode.IsDigit(rune(subPattern[0])) || unicode.IsLetter(rune(subPattern[0])) {
|
|
fmtWord := subPattern
|
|
for subPattern != "" {
|
|
i := len(subPattern)
|
|
for ; i > 0; i-- {
|
|
fmtWord = subPattern[0:i]
|
|
element, err := OracleDateFormat.getFormatElement(fmtWord)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if element != nil {
|
|
// 忽略时区前面的+-号
|
|
if element == OracleDateFormat.TZHElement || element == OracleDateFormat.TZMElement {
|
|
var lastFormatElement string = OracleDateFormat.FormatElementList[len(OracleDateFormat.FormatElementList)-1].(string)
|
|
if util.StringUtil.Equals("+", lastFormatElement) || util.StringUtil.Equals("-", lastFormatElement) {
|
|
OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:len(OracleDateFormat.FormatElementList)-2]
|
|
}
|
|
}
|
|
OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, element)
|
|
if i == len(subPattern) {
|
|
subPattern = ""
|
|
} else {
|
|
subPattern = subPattern[i:len(subPattern)]
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
if i == 0 {
|
|
// 非标识符串
|
|
OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
|
|
break
|
|
}
|
|
}
|
|
|
|
} else {
|
|
OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
|
|
}
|
|
}
|
|
return OracleDateFormat.FormatElementList, nil
|
|
}
|
|
|
|
func (OracleDateFormat *oracleDateFormat) getFormatElement(word string) (element, error) {
|
|
if util.StringUtil.EqualsIgnoreCase("HH", word) || util.StringUtil.EqualsIgnoreCase("HH12", word) {
|
|
return OracleDateFormat.HH12Element, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("HH24", word) {
|
|
return OracleDateFormat.HH24Element, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("MI", word) {
|
|
return OracleDateFormat.MIElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("SS", word) {
|
|
return OracleDateFormat.SSElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("AM", word) || util.StringUtil.EqualsIgnoreCase("A.M.", word) || util.StringUtil.EqualsIgnoreCase("PM", word) || util.StringUtil.EqualsIgnoreCase("P.M.", word) {
|
|
return OracleDateFormat.AMElement, nil
|
|
} else if util.StringUtil.Equals("MONTH", word) {
|
|
OracleDateFormat.MonthElement.upperCase = true
|
|
OracleDateFormat.MonthElement.lowerCase = false
|
|
return OracleDateFormat.MonthElement, nil
|
|
} else if util.StringUtil.Equals("month", word) {
|
|
OracleDateFormat.MonthElement.upperCase = false
|
|
OracleDateFormat.MonthElement.lowerCase = true
|
|
return OracleDateFormat.MonthElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("Month", word) {
|
|
OracleDateFormat.MonthElement.upperCase = false
|
|
OracleDateFormat.MonthElement.lowerCase = false
|
|
return OracleDateFormat.MonthElement, nil
|
|
} else if util.StringUtil.Equals("MON", word) {
|
|
OracleDateFormat.MonElement.upperCase = true
|
|
OracleDateFormat.MonElement.lowerCase = false
|
|
return OracleDateFormat.MonElement, nil
|
|
} else if util.StringUtil.Equals("mon", word) {
|
|
OracleDateFormat.MonElement.upperCase = false
|
|
OracleDateFormat.MonElement.lowerCase = true
|
|
return OracleDateFormat.MonElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("Mon", word) {
|
|
OracleDateFormat.MonElement.upperCase = false
|
|
OracleDateFormat.MonElement.lowerCase = false
|
|
return OracleDateFormat.MonElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("MM", word) {
|
|
return OracleDateFormat.MMElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("DD", word) {
|
|
return OracleDateFormat.DDElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("TZH", word) {
|
|
return OracleDateFormat.TZHElement, nil
|
|
} else if util.StringUtil.EqualsIgnoreCase("TZM", word) {
|
|
return OracleDateFormat.TZMElement, nil
|
|
} else if strings.Index(word, "Y") == 0 || strings.Index(word, "y") == 0 {
|
|
OracleDateFormat.YearElement.len = len(word)
|
|
return OracleDateFormat.YearElement, nil
|
|
} else if strings.Index(word, "F") == 0 || strings.Index(word, "f") == 0 {
|
|
|
|
word = strings.ToUpper(word)
|
|
numIndex := strings.LastIndex(word, "F") + 1
|
|
var count int64
|
|
var err error
|
|
if numIndex < len(word) {
|
|
count, err = strconv.ParseInt(word[numIndex:len(word)], 10, 32)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
count = -1
|
|
}
|
|
|
|
OracleDateFormat.FElement.len = int(count)
|
|
return OracleDateFormat.FElement, nil
|
|
}
|
|
|
|
return nil, nil
|
|
}
|