golang时间操作基础及重要操作总结
时间常量
const ( Nanosecond Duration = 1 // 纳秒 Microsecond = 1000 * Nanosecond // 微妙 Millisecond = 1000 * Microsecond // 毫秒 Second = 1000 * Millisecond // 秒 Minute = 60 * Second // 分钟 Hour = 60 * Minute // 小时 )
time.Second // 代表1秒 100 * time.Millisecond // 代表100毫秒
init方法初始化本地时区
package time_module import "time" var TIME_LOCATION *time.Location func init() { var err error TIME_LOCATION, err = time.LoadLocation("Asia/Shanghai") if err != nil { panic(err) } } // 当前时区的当前时间 func GetCurrentTime() time.Time { return time.Now().In(TIME_LOCATION) }
常用的操作
package time_module import ( "fmt" "testing" "time" ) // 基础 func TestTimeOperation(t *testing.T) { // 0、时间常量 oneSecond := time.Second time.Sleep(oneSecond) // =================================================================== // 1、当前时间 currentTime := GetCurrentTime() fmt.Println("currentTime>>> ", currentTime) // =================================================================== // 2-1、将本地时区的时间转换为0时区的时间 utcNow := currentTime.UTC() fmt.Println("utcNow>> ", utcNow)
// 2-2、将时间直接转为字符串
currTimeStr := currentTime.String()
fmt.Println(currTimeStr)
// ===================================================================== // 3、创造一个时间 myTime := time.Date(2019, 02, 23, 10, 11, 12, 0, TIME_LOCATION) fmt.Println("myTIme>>> ", myTime) // =================================================================== // 4、获取time对象 包含年/月/日/时/分/秒/周的一些方法 // Date() 年月日 year, month, day := myTime.Date() fmt.Println(year, month, day) // Clock() 时分秒 hour, minute, second := myTime.Clock() fmt.Println(hour, minute, second) // Weekday() 周几 fmt.Println(GetCurrentTime().Weekday()) // =================================================================== // 5、时间比较 // 比较两个时间是否相等 fmt.Println(currentTime.Equal(myTime)) // false // now 是否在 myTime 之前 fmt.Println(currentTime.Before(myTime)) // false // now是否在 myTime 之后 fmt.Println(currentTime.After(myTime)) // true // =================================================================== // 6、时间计算 // 计算时间差 —— 靠后的时间放在前面 timeDuration := currentTime.Sub(myTime) fmt.Println("timeDuration>> ", timeDuration) // 15965h15m5.224671s // 时间差的小时数 fmt.Println(timeDuration.Hours()) // 15965.271575873056 // 时间差的分钟数 fmt.Println(timeDuration.Minutes()) // 957916.80486195 // 时间差的秒数 fmt.Println(timeDuration.Seconds()) // 5.7475023995509e+07 // 时间段用字符串表示 fmt.Printf("ret.String(): %v, %T \n", timeDuration.String(), timeDuration.String()) /* ret.String(): 15965h18m48.126891s, string */ // =================================================================== // 时间加 // 当前时间点 +1 天 (前面2个是 年 月) tomorrow := currentTime.AddDate(0, 0, 1) fmt.Println(tomorrow) // 2020-12-20 15:43:54.56172 +0800 CST // 当前时间 加 10秒 after10Seconds := currentTime.Add(10 * time.Second) fmt.Println(after10Seconds) // 2020-12-19 15:44:55.1963771 +0800 CST m=+0.000777051 }
本地时区时间与UTC时区时间转换
// 0、本地时区时间与UTC时区时间转换 func Time2UTC(t time.Time) time.Time { // 时间转换成 UTC时区的时间 return t.UTC() } // 转成本地时区时间 func Time2Local(t time.Time) time.Time { return t.Local() }
时间转时间戳
time包只提供了直接转秒级别的时间戳与纳秒级别的时间戳的方法,获取毫秒级别的时间戳可以先计算出纳秒级别的时间戳然后除以1e6即可:
// 秒级别 func Time2TimeStampSecond(t time.Time) int64 { return t.Unix() } // 纳秒级别 func Time2TimeStampNano(t time.Time) int64 { return t.UnixNano() } // 毫秒级别 - 常用 func Time2TimeStampMill(t time.Time) int64 { return t.UnixNano() / 1e6 }
时间转字符串
如果没有特殊要求可以直接使用String()方法;如果有规定转换成字符串的格式,需要特别注意字符串的时区要与当前时间的时区保持一致!
// 按照当前时间的格式来 —— (同一个时区转换推荐这种方法!) func Time2Str(t time.Time) string { return t.String() }
-------------------------------------------------------------- // 有风险,注意必须在同一个时区 // 按照指定的格式 -- 格式化的字符串记得与时间要在同一个时区! /* 如果time是:2021-08-14 18:53:58.782548 +0800 CST timeFormat是:2006-01-02 15:04:05 +0000 UTC 结果会是 错误 的:2021-08-14 18:58:23 +0000 UTC */
// 最好用In方法转到同一个时区处理!
const timeFormat = "2006-01-02T15:04:05+0800"
var timeLocation *time.Location
func init() {
var err error
timeLocation, err = time.LoadLocation("Asia/Shanghai")
if err != nil {
panic(err)
}
}
func Time2StrAsFormat(t time.Time, timeFormat string) string { // 先将输入的时间转换到指定的时区,然后再转换格式 return t.In(timeLocation).Format(timeFormat) }
时间戳转时间
使用内置的Unix方法,注意,第一个参数表示秒级别的时间戳,第二个参数表示纳秒级别的时间戳,如果是毫秒级别的时间戳需要先乘以1e6然后放入第二个参数即可:
// 3、时间戳转时间 time.Unix // TODO time.Unix 方法默认返回的是操作系统本地的时区的时间 // TODO 可以在电脑上验证一下:修改时区的话,结果会不一样!
// Timestamp2Time 时间戳转时间 func Timestamp2Time(stamp int64, nsec int64) time.Time { return time.Unix(stamp, nsec) } // 纳秒时间戳转时间 func TimestampNano2Time(stamp int64) time.Time { return Timestamp2Time(0, stamp) } // 毫秒时间戳转时间 —— 毫秒 *1e6 先转成纳秒 func TimestampMil2Time(stamp int64) time.Time { return Timestamp2Time(0, stamp*1e6) } // 秒级别时间戳转时间 func TimestampSec2Time(stamp int64) time.Time { return Timestamp2Time(stamp, 0) }
字符串转时间1:简单的方法
//简单的~~ time.ParseInLocation方法~ 推荐使用带本地时区的方法 第一个参数是format字符串 func TimeStr2TimeInLocation(timeFormat, timeStr string) (time.Time, error) { // 第一个参数是Format字符串的格式 timeRet, err := time.ParseInLocation(timeFormat, timeStr, TIME_LOCATION) return timeRet, err }
// 不推荐的方法~~默认会转换到UTC 0时区没有转换过的时间 func TimeStr2TimeEasy(timeFormat, timeStr string) (time.Time, error) { // TODO 即使用 CST格式的时间戳去格式化,转换的还是UTC时间! /* 比如:timeStr是:"2021-08-14 17:27:31 +0800 CST" 转换的结果会是 错误的:2021-08-14 17:27:31 +0000 UTC */ timeRet, err := time.Parse(timeFormat, timeStr) return timeRet, err }
字符串转时间2:自己封装的方法 ***
const ( MYNano = "2006-01-02 15:04:05.000000000" MYMicro = "2006-01-02 15:04:05.000000" MYMil = "2006-01-02 15:04:05.000" MYSec = "2006-01-02 15:04:05" MYCST = "2006-01-02 15:04:05 +0800 CST" MYUTC = "2006-01-02 15:04:05 +0000 UTC" MYDate = "2006-01-02" MYTime = "15:04:05" FBTIME = "2006-01-02T15:04:05+0800" APPTIME = "2006-01-02T15:04:05.000" TWITTERTIME = "2006-01-02T15:04:05Z" ) func TimeStr2Time(timeStr string) (time.Time, error) { // 可能的转换格式 useFormat := []string{ MYNano, MYMicro, MYMil, MYSec, MYCST, MYUTC, MYDate, MYTime, FBTIME, APPTIME, TWITTERTIME, time.RFC3339, time.RFC3339Nano, } var t time.Time for _, useF := range useFormat { tt, err1 := time.ParseInLocation(useF, timeStr, TIME_LOCATION) if err1 != nil { continue } t = tt break } if t == getTimeDefault() { // 0001-01-01 00:00:00 +0000 UTC return t, errors.New("时间字符串格式错误") } return t, nil } func getTimeDefault() time.Time { t, _ := time.ParseInLocation("2006-01-02 15:04:05", "", TIME_LOCATION) return t }
字符串转时间戳 - 先转时间再转时间戳
使用上面封装好的方法转时间,然后再转成毫秒级别的时间戳:
func TimeStr2TimestampMill(timeStr string) (int64, error) { t, err := TimeStr2Time(timeStr) if err != nil { return -1., err } // 毫秒级别 return (t.UnixNano()) / 1e6, nil }
20210222这种格式的时间数据转换
const TimeActivitiesLayout = "20060102" // 时间是个int:20210222 func NumberToDate(number int) time.Time { var year = number / 10000 var month = number % 10000 / 100 var day = number % 100 return time.Date(year, time.Month(month), day, 0, 0, 0, 0, Location) } // 时间字符串的格式必须是:"20210222" func StringToDate(s string) (time.Time, error) { timeRet, err := time.ParseInLocation(TimeActivitiesLayout, s, Location) if err != nil { return timeRet, err } return timeRet, nil } // 特殊时间格式的处理 func TestSpecialTimeFormat(t *testing.T) { // 时间字符串格式:"20210222",转化为time.Time类型 s1 := "20210222" t1, err := utils.StringToDate(s1) if err != nil{ panic(err) } fmt.Println("t1>>> ", t1) // 2021-09-10 00:00:00 +0800 CST // 时间int格式:20210222,转化为time.Time类型 i2 := 20220313 t2 := utils.NumberToDate(i2) fmt.Println("t2>>> ", t2) // 2022-03-13 00:00:00 +0800 CST // time.Time类型转化为20210222这种类型(int) ———— 转这种类型的字符串的话,先转int然后再转string即可 now := utils.CurrentTime() t3 := utils.DateNumber(now) fmt.Println("t3>>> ", t3) // 20210821 s4 := utils.AnyToString(t3) fmt.Println("s4: >>> ", s4) }
utils.AnyToInt方法:
func AnyToInt(value interface{}) int { if value == nil { return 0 } switch val := value.(type) { case int: return val case int8: return int(val) case int16: return int(val) case int32: return int(val) case int64: return int(val) case uint: return int(val) case uint8: return int(val) case uint16: return int(val) case uint32: return int(val) case uint64: return int(val) case *string: v, err := strconv.Atoi(*val) if err != nil { return 0 } return v case string: v, err := strconv.Atoi(val) if err != nil { return 0 } return v case float32: return int(val) case float64: return int(val) case bool: if val { return 1 } else { return 0 } case json.Number: v, _ := val.Int64() return int(v) } return 0 }
~~~