From cc2e8919802aefbb69b5ae8ff8432753c0181b67 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 16 Oct 2018 15:49:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgtime=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=A2=9E=E5=8A=A0=E6=97=B6=E5=8C=BA=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/os/gtime/gtime.go | 85 ++++++++++++++++++++++----------- g/os/gtime/gtime_time.go | 13 ++++- geg/os/gtime/gtime_regex.go | 5 ++ geg/os/gtime/gtime_strtotime.go | 5 ++ geg/other/test.go | 8 +++- 5 files changed, 85 insertions(+), 31 deletions(-) diff --git a/g/os/gtime/gtime.go b/g/os/gtime/gtime.go index 863efd213..0b8647f8e 100644 --- a/g/os/gtime/gtime.go +++ b/g/os/gtime/gtime.go @@ -16,18 +16,24 @@ import ( ) const ( - TIME_REAGEX_PATTERN = `(\d{4}[-/]\d{2}[-/]\d{2})[\sT]{0,1}(\d{2}:\d{2}:\d{2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)` + // 常用时间格式正则匹配,支持的标准时间格式: + // "2017-12-14 04:51:34 +0805 LMT", + // "2017-12-14 04:51:34 +0805 LMT", + // "2006-01-02T15:04:05Z07:00", + // "2014-01-17T01:19:15+08:00", + // "2018-02-09T20:46:17.897Z", + // "2018-02-09 20:46:17.897", + // "2018-02-09T20:46:17Z", + // "2018-02-09 20:46:17", + // "2018-02-09", + // 日期连接符号支持'-'或者'/' + TIME_REAGEX_PATTERN = `(\d{2,4}[-/]\d{2}[-/]\d{2})[\sT]{0,1}(\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)` ) var ( - // 用于time.Time转换使用,防止多次Compile - timeRegex *regexp.Regexp -) - -func init() { // 使用正则判断会比直接使用ParseInLocation挨个轮训判断要快很多 timeRegex, _ = regexp.Compile(TIME_REAGEX_PATTERN) -} +) // 类似与js中的SetTimeout,一段时间后执行回调函数 func SetTimeout(t time.Duration, callback func()) { @@ -50,7 +56,7 @@ func SetInterval(t time.Duration, callback func() bool) { }() } -// 设置当前进程全局的默认时区 +// 设置当前进程全局的默认时区,如: Asia/Shanghai func SetTimeZone(zone string) error { location, err := time.LoadLocation(zone) if err == nil { @@ -89,47 +95,50 @@ func Datetime() string { return time.Now().Format("2006-01-02 15:04:05") } -// 字符串转换为时间对象,支持的标准时间格式: -// "2017-12-14 04:51:34 +0805 LMT", -// "2006-01-02T15:04:05Z07:00", -// "2014-01-17T01:19:15+08:00", -// "2018-02-09T20:46:17.897Z", -// "2018-02-09 20:46:17.897", -// "2018-02-09T20:46:17Z", -// "2018-02-09 20:46:17", -// "2018-02-09", +// 字符串转换为时间对象 func StrToTime(str string) (time.Time, error) { var result time.Time var local = time.Local if match := timeRegex.FindStringSubmatch(str); len(match) > 0 { var year, month, day, hour, min, sec, nsec int var array []string - // 日期 + // 日期(支持'-'或'/'连接符号) array = strings.Split(match[1], "-") + if len(array) < 3 { + array = strings.Split(match[1], "/") + } if len(array) >= 3 { + // 年是否为缩写,如果是,那么需要补上前缀 year, _ = strconv.Atoi(array[0]) + if year < 100 { + year = int(time.Now().Year()/100)*100 + year + } month, _ = strconv.Atoi(array[1]) day, _ = strconv.Atoi(array[2]) } // 时间 - array = strings.Split(match[2], ":") - if len(array) >= 3 { - hour, _ = strconv.Atoi(array[0]) - min, _ = strconv.Atoi(array[1]) - sec, _ = strconv.Atoi(array[2]) + if len(match[2]) > 0 { + array = strings.Split(match[2], ":") + hour, _ = strconv.Atoi(array[0]) + if len(array) >= 2 { + min, _ = strconv.Atoi(array[1]) + } + if len(array) >= 3 { + sec, _ = strconv.Atoi(array[2]) + } } - array = strings.Split(match[1], "-") - // 纳秒,检查病执行位补齐 - if match[3] != "" { + // 纳秒,检查并执行位补齐 + if len(match[3]) > 0 { nsec, _ = strconv.Atoi(match[3]) for i := 0; i < 9 - len(match[3]); i++ { nsec *= 10 } } - // 如果字符串中有时区信息,那么执行时区转换,将时区转成UTC + // 如果字符串中有时区信息(具体时间信息),那么执行时区转换,将时区转成UTC if match[4] != "" && match[6] == "" { match[6] = "000000" } + // 如果offset有值优先处理offset,否则处理后面的时区名称 if match[6] != "" { zone := strings.Replace(match[6], ":", "", -1) zone = strings.TrimLeft(zone, "+-") @@ -137,7 +146,7 @@ func StrToTime(str string) (time.Time, error) { h, _ := strconv.Atoi(zone[0 : 2]) m, _ := strconv.Atoi(zone[2 : 4]) s, _ := strconv.Atoi(zone[4 : 6]) - // 判断字符串输入的时区是否和当前程序时区相等,不相等则将对象统一转换为UTC时区 + // 判断字符串输入的时区是否和当前程序时区相等(使用offset判断),不相等则将对象统一转换为UTC时区 // 当前程序时区Offset(秒) _, localOffset := time.Now().Zone() if (h * 3600 + m * 60 + s) != localOffset { @@ -178,6 +187,26 @@ func StrToTime(str string) (time.Time, error) { return result, errors.New("unsupported time format") } +// 时区转换 +func ConvertZone(strTime string, toZone string, fromZone...string) (time.Time, error) { + t, err := StrToTime(strTime) + if err != nil { + return time.Time{}, err + } + if len(fromZone) > 0 { + if l, err := time.LoadLocation(fromZone[0]); err != nil { + return time.Time{}, err + } else { + t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), l) + } + } + if l, err := time.LoadLocation(toZone); err != nil { + return time.Time{}, err + } else { + return t.In(l), nil + } +} + // 字符串转换为时间对象,指定字符串时间格式,format格式形如:Y-m-d H:i:s func StrToTimeFormat(str string, format string) (time.Time, error) { return StrToTimeLayout(str, formatToStdLayout(format)) diff --git a/g/os/gtime/gtime_time.go b/g/os/gtime/gtime_time.go index b94043ff8..9d99dabda 100644 --- a/g/os/gtime/gtime_time.go +++ b/g/os/gtime/gtime_time.go @@ -117,12 +117,23 @@ func (t *Time) Add(d time.Duration) *Time { return t } -// 时区转换为指定的时区 +// 时区转换为指定的时区(通过time.Location) func (t *Time) ToLocation(location *time.Location) *Time { t.Time = t.Time.In(location) return t } +// 时区转换为指定的时区(通过时区名称,如:AsiaShanghai) +func (t *Time) ToZone(zone string) *Time { + if l, err := time.LoadLocation(zone); err == nil { + t.Time = t.Time.In(l) + return t + } else { + panic(err) + return nil + } +} + // 时区转换为UTC时区 func (t *Time) UTC() *Time { t.Time = t.Time.UTC() diff --git a/geg/os/gtime/gtime_regex.go b/geg/os/gtime/gtime_regex.go index b34af30f0..4f4463a28 100644 --- a/geg/os/gtime/gtime_regex.go +++ b/geg/os/gtime/gtime_regex.go @@ -20,6 +20,11 @@ func main() { "2018-02-09T20:46:17Z", "2018-02-09 20:46:17", "2018-02-09", + "2017/12/14 04:51:34 +0805 LMT", + "2018/02/09 12:00:15", + "18/02/09 12:16", + "18/02/09 12", + "18/02/09 +0805 LMT", } for _, s := range array { fmt.Println(s) diff --git a/geg/os/gtime/gtime_strtotime.go b/geg/os/gtime/gtime_strtotime.go index d06e6421c..e5c3237a4 100644 --- a/geg/os/gtime/gtime_strtotime.go +++ b/geg/os/gtime/gtime_strtotime.go @@ -16,6 +16,11 @@ func main() { "2018-02-09T20:46:17Z", "2018-02-09 20:46:17", "2018-02-09", + "2017/12/14 04:51:34 +0805 LMT", + "2018/02/09 12:00:15", + "18/02/09 12:16", + "18/02/09 12", + "18/02/09 +0805 LMT", } cstLocal, _ := time.LoadLocation("Asia/Shanghai") for _, s := range array { diff --git a/geg/other/test.go b/geg/other/test.go index 42c384027..2b6da3e60 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,10 +1,14 @@ package main import ( + "gitee.com/johng/gf/g/os/gtime" "fmt" ) func main() { - fmt.Println(string([]byte{48})) - fmt.Println(string([]byte{112,108,97,121,101,114,105,100})) + t := gtime.Now() + err := t.ToZone("Asia/Aden") + fmt.Println(err) + fmt.Println(t.String()) + //fmt.Println(string([]byte{112,108,97,121,101,114,105,100})) }