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
}
AnyToInt

~~~

posted on 2020-12-31 15:23  江湖乄夜雨  阅读(583)  评论(0编辑  收藏  举报