改进gtime模块,并增加时区转换方法

This commit is contained in:
john
2018-10-16 15:49:30 +08:00
parent dc28b93f4a
commit cc2e891980
5 changed files with 85 additions and 31 deletions

View File

@ -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))

View File

@ -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()

View File

@ -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)

View File

@ -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 {

View File

@ -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}))
}