为什么是2006-01-02 15:04:05?

需求:将传参中的时间分割成为24小时的整点。例如:req:2022-01-01,respone:[2022-01-01 00:00:00,2022-01-01 01:00:00...2022-01-01 23:00:00]

如果在php中处理需求,2行代码就搞定,首先将req转换为时间戳,然后循环累加3600*i,i=i,i<24。最后date('Y-m-s H:i:s,$time);即可。

带着这样的思路,在go中开始实践:
1.不同与php,go是强类型语言,不能直接对日期进行时间戳转化,但是可以通过字符串拼接,将date先转为UTC标准字符串。
2.通过time包的ParseInLocation可以获取一个CST标注你时间格式。
3.通过Unix()转化为时间戳。
4.时间戳进行循环累加,再转换为respone需要的日期格式。

代码如下:

package main

import (
    "fmt"
    "time"
)

func main() {
    datetime := "2022-02-14" //待转化为时间戳的字符串
    useTime := datetime + " 00:00:00"
    //日期转化为时间戳
    timeLayout := "2006-01-02 15:04:05"  //转化所需模板
    loc, _ := time.LoadLocation("Local") //获取时区
    tmp, _ := time.ParseInLocation(timeLayout, useTime, loc)
    
    timestamp := tmp.Unix() //转化为时间戳 类型是int64

    //时间戳转化为日期
    datetime = time.Unix(timestamp, 0).Format(timeLayout)
    fmt.Println(datetime)
    var i int64
    for i = 1; i < 24; i++ {
        b := timestamp + (i * 3600)
        datetime1 := time.Unix(b, 0).Format(timeLayout)
        println(datetime1)
    }
}

执行一下上述代码:结果如下

是我们想要的。但是注意代码的第12行,time.ParseInLocation第一个参数需要一个时间模版,这个模版格式为“2006-01-02 15:04:05”,咋一看,像一个随机定义的时间格式,那么我们将这个时间改一下。

package main

import (
    "fmt"
    "time"
)

func main() {
    datetime := "2022-02-14" //待转化为时间戳的字符串
    useTime := datetime + " 00:00:00"
    //日期转化为时间戳
    timeLayout := "2007-01-01 15:04:05"  //转化所需模板
    loc, _ := time.LoadLocation("Local") //获取时区
    tmp, _ := time.ParseInLocation(timeLayout, useTime, loc)

    timestamp := tmp.Unix() //转化为时间戳 类型是int64

    //时间戳转化为日期
    datetime = time.Unix(timestamp, 0).Format(timeLayout)
    fmt.Println(datetime)
    var i int64
    for i = 1; i < 24; i++ {
        b := timestamp + (i * 3600)
        datetime1 := time.Unix(b, 0).Format(timeLayout)
        println(datetime1)
    }
}

将时间改为"2007-01-01 15:04:05",执行一下看会怎么样:

可以看到,结果并不是我们想要的。那为什么会这样呢。我们追进time包看下发生了什么!

首先是常量定义:

const (
    Layout      = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
    ANSIC       = "Mon Jan _2 15:04:05 2006"
    UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
    RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
    RFC822      = "02 Jan 06 15:04 MST"
    RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
    RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
    RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
    RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
    RFC3339     = "2006-01-02T15:04:05Z07:00"
    RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
    Kitchen     = "3:04PM"
    // Handy time stamps.
    Stamp      = "Jan _2 15:04:05"
    StampMilli = "Jan _2 15:04:05.000"
    StampMicro = "Jan _2 15:04:05.000000"
    StampNano  = "Jan _2 15:04:05.000000000"
)

const (
    _                        = iota
    stdLongMonth             = iota + stdNeedDate  // "January"
    stdMonth                                       // "Jan"
    stdNumMonth                                    // "1"
    stdZeroMonth                                   // "01"
    stdLongWeekDay                                 // "Monday"
    stdWeekDay                                     // "Mon"
    stdDay                                         // "2"
    stdUnderDay                                    // "_2"
    stdZeroDay                                     // "02"
    stdUnderYearDay                                // "__2"
    stdZeroYearDay                                 // "002"
    stdHour                  = iota + stdNeedClock // "15"
    stdHour12                                      // "3"
    stdZeroHour12                                  // "03"
    stdMinute                                      // "4"
    stdZeroMinute                                  // "04"
    stdSecond                                      // "5"
    stdZeroSecond                                  // "05"
    stdLongYear              = iota + stdNeedDate  // "2006"
    stdYear                                        // "06"
    stdPM                    = iota + stdNeedClock // "PM"
    stdpm                                          // "pm"
    stdTZ                    = iota                // "MST"
    stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
    stdISO8601SecondsTZ                            // "Z070000"
    stdISO8601ShortTZ                              // "Z07"
    stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
    stdISO8601ColonSecondsTZ                       // "Z07:00:00"
    stdNumTZ                                       // "-0700"  // always numeric
    stdNumSecondsTz                                // "-070000"
    stdNumShortTZ                                  // "-07"    // always numeric
    stdNumColonTZ                                  // "-07:00" // always numeric
    stdNumColonSecondsTZ                           // "-07:00:00"
    stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
    stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted

    stdNeedDate       = 1 << 8             // need month, day, year
    stdNeedClock      = 2 << 8             // need hour, minute, second
    stdArgShift       = 16                 // extra argument in high bits, above low stdArgShift
    stdSeparatorShift = 28                 // extra argument in high 4 bits for fractional second separators
    stdMask           = 1<<stdArgShift - 1 // mask out argument
)

接下来是具体替换逻辑:

func nextStdChunk(layout string) (prefix string, std int, suffix string) {
    for i := 0; i < len(layout); i++ {
        switch c := int(layout[i]); c {
        case 'J': // January, Jan
            if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
                if len(layout) >= i+7 && layout[i:i+7] == "January" {
                    return layout[0:i], stdLongMonth, layout[i+7:]
                }
                if !startsWithLowerCase(layout[i+3:]) {
                    return layout[0:i], stdMonth, layout[i+3:]
                }
            }

        case 'M': // Monday, Mon, MST
            if len(layout) >= i+3 {
                if layout[i:i+3] == "Mon" {
                    if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
                        return layout[0:i], stdLongWeekDay, layout[i+6:]
                    }
                    if !startsWithLowerCase(layout[i+3:]) {
                        return layout[0:i], stdWeekDay, layout[i+3:]
                    }
                }
                if layout[i:i+3] == "MST" {
                    return layout[0:i], stdTZ, layout[i+3:]
                }
            }

        case '0': // 01, 02, 03, 04, 05, 06, 002
            if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
                return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
            }
            if len(layout) >= i+3 && layout[i+1] == '0' && layout[i+2] == '2' {
                return layout[0:i], stdZeroYearDay, layout[i+3:]
            }

        case '1': // 15, 1
            if len(layout) >= i+2 && layout[i+1] == '5' {
                return layout[0:i], stdHour, layout[i+2:]
            }
            return layout[0:i], stdNumMonth, layout[i+1:]

        case '2': // 2006, 2
            if len(layout) >= i+4 && layout[i:i+4] == "2006" {
                return layout[0:i], stdLongYear, layout[i+4:]
            }
            return layout[0:i], stdDay, layout[i+1:]

        case '_': // _2, _2006, __2
            if len(layout) >= i+2 && layout[i+1] == '2' {
                //_2006 is really a literal _, followed by stdLongYear
                if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
                    return layout[0 : i+1], stdLongYear, layout[i+5:]
                }
                return layout[0:i], stdUnderDay, layout[i+2:]
            }
            if len(layout) >= i+3 && layout[i+1] == '_' && layout[i+2] == '2' {
                return layout[0:i], stdUnderYearDay, layout[i+3:]
            }

        case '3':
            return layout[0:i], stdHour12, layout[i+1:]

        case '4':
            return layout[0:i], stdMinute, layout[i+1:]

        case '5':
            return layout[0:i], stdSecond, layout[i+1:]

        case 'P': // PM
            if len(layout) >= i+2 && layout[i+1] == 'M' {
                return layout[0:i], stdPM, layout[i+2:]
            }

        case 'p': // pm
            if len(layout) >= i+2 && layout[i+1] == 'm' {
                return layout[0:i], stdpm, layout[i+2:]
            }

        case '-': // -070000, -07:00:00, -0700, -07:00, -07
            if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
                return layout[0:i], stdNumSecondsTz, layout[i+7:]
            }
            if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
                return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
            }
            if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
                return layout[0:i], stdNumTZ, layout[i+5:]
            }
            if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
                return layout[0:i], stdNumColonTZ, layout[i+6:]
            }
            if len(layout) >= i+3 && layout[i:i+3] == "-07" {
                return layout[0:i], stdNumShortTZ, layout[i+3:]
            }

        case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
            if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
                return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
            }
            if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
                return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
            }
            if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
                return layout[0:i], stdISO8601TZ, layout[i+5:]
            }
            if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
                return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
            }
            if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
                return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
            }

        case '.', ',': // ,000, or .000, or ,999, or .999 - repeated digits for fractional seconds.
            if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
                ch := layout[i+1]
                j := i + 1
                for j < len(layout) && layout[j] == ch {
                    j++
                }
                // String of digits must end here - only fractional second is all digits.
                if !isDigit(layout, j) {
                    code := stdFracSecond0
                    if layout[i+1] == '9' {
                        code = stdFracSecond9
                    }
                    std := stdFracSecond(code, j-(i+1), c)
                    return layout[0:i], std, layout[j:]
                }
            }
        }
    }
    return layout, 0, ""
}

这段代码有点长,不过逻辑还是很清楚的,我们吧上面表格中的那些常用项的先进行排序,然后根据排序结果,对首个字符进行分类,相同首字符的项放在一个case里面判断处理。看起来这里是简单的进行判断处理,其实这就是编译里面词法分析的一个步骤(分词)。

纵观整个format.go文件,其实这个日期处理还是挺复杂的,包括日期计算,格式解析,对日期进行格式化等。

为何要写一个具体的时间日期字符串而不用“YYYY-MM-DD H:i:s”这样的简单明了的占位符呢?

有一种说法是2006 表示年份,好像是 Go 开始设计的年份,而后面 1 2 3 4 5 6 7,通过简单的顺序就可以记忆。如果要表示 pm,就可以用 15(3 表示 am),而且如果月份希望用英文表示的话,将 1 改为 January,简写 Jan,星期的话,只需要 Mon、Monday 表示简称全称。

好吧!你开心就好

已有 49 条评论

  1. 博主真是太厉害了!!!

  2. 不错不错,我喜欢看

  3. 看的我热血沸腾啊

  4. 看的我热血沸腾啊https://www.237fa.com/

  5. 不错不错,我喜欢看 https://www.ea55.com/

  6. 看的我热血沸腾啊https://www.ea55.com/

  7. 看的我热血沸腾啊www.jiwenlaw.com

  8. 看的我热血沸腾啊www.jiwenlaw.com

  9. 文章的确不错啊https://www.cscnn.com/

  10. 《大神偷卡门第三季》欧美动漫高清在线免费观看:https://www.jgz518.com/xingkong/38093.html

  11. 绝世揭秘:顶级精品系列传奇私服,重温热血江湖巅峰之战!:https://501h.com/fugu/20369.html

  12. 你的文章充满了智慧,让人敬佩。 http://www.55baobei.com/4usAjb1EuU.html

  13. 每次看到你的文章,我都觉得时间过得好快。 https://www.4006400989.com/qyvideo/17490.html

  14. 真好呢

  15. 每次看到你的文章,我都觉得时间过得好快。 https://www.4006400989.com/qyvideo/17490.html

  16. 你的文章让我感受到了快乐,每天都要来看一看。 http://www.55baobei.com/xKFXrBN7Og.html

  17. 你的才华让人惊叹,请继续保持。 http://www.55baobei.com/M2djvfpE9z.html

  18. 你的文章让我感受到了无尽的欢乐,谢谢分享。 https://www.4006400989.com/qyvideo/17913.html

  19. 《咒怨2 录像带版》科幻片高清在线免费观看:https://www.jgz518.com/xingkong/121081.html

  20. 你的才华横溢,让人敬佩。 https://www.yonboz.com/video/80639.html

  21. 你的文章让我心情愉悦,每天都要来看一看。 https://www.yonboz.com/video/74671.html

  22. 你的文章充满了创意,真是让人惊喜。 https://www.4006400989.com/qyvideo/58411.html

  23. 《大项目》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/129403.html

  24. 《越过山丘》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/143923.html

  25. 《寻找多莉帕顿》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/71795.html

  26. 《遇见闪亮的自己第二季》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/43972.html

  27. 你的文章让我感受到了正能量,非常棒! https://www.4006400989.com/qyvideo/82976.html

  28. 你的文章充满了创意,真是让人惊喜。 https://www.4006400989.com/qyvideo/18384.html

  29. 《俏皮女学生》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/57322.html

  30. 《2024抖音美好奇妙夜》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/155212.html

  31. 《西谎极落之太爆太子太空舱》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/7837.html

  32. 《要一起过吗?》韩国剧高清在线免费观看:https://www.jgz518.com/xingkong/29928.html

  33. 哈哈哈,写的太好了https://www.lawjida.com/

  34. 新盘新项目,不再等待,现在就是最佳上车机会!

  35. 华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099

  36. 华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
    如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
    华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
    华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?

  37. 华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
    如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
    华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
    华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?

  38. 华纳东方明珠客服电话是多少?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
    华纳东方明珠开户专线联系方式?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】

  39. 华纳东方明珠客服电话是多少?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
    华纳东方明珠开户专线联系方式?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】

  40. 新盛客服电话是多少?(?183-8890-9465—《?薇-STS5099】【
    新盛开户专线联系方式?(?183-8890--9465—《?薇-STS5099】【?扣6011643??】
    新盛客服开户电话全攻略,让娱乐更顺畅!(?183-8890--9465—《?薇-STS5099】客服开户流程,华纳新盛客服开户流程图(?183-8890--9465—《?薇-STS5099】

  41. 果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
    果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  42. 果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
    果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  43. 东方明珠客服开户联系方式【182-8836-2750—】?μ- cxs20250806
    东方明珠客服电话联系方式【182-8836-2750—】?- cxs20250806】
    东方明珠开户流程【182-8836-2750—】?薇- cxs20250806】
    东方明珠客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  44. 东方明珠客服开户联系方式【182-8836-2750—】?μ- cxs20250806
    东方明珠客服电话联系方式【182-8836-2750—】?- cxs20250806】
    东方明珠开户流程【182-8836-2750—】?薇- cxs20250806】
    东方明珠客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  45. 华纳圣淘沙开户步骤详解(183-8890-9465—?薇-STS5099【6011643】

    华纳圣淘沙公司开户流程全解析(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司账户注册指南(183-8890-9465—?薇-STS5099【6011643】
    新手如何开通华纳圣淘沙公司账户(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙企业开户标准流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户:从零到一(183-8890-9465—?薇-STS5099【6011643】
    官方指南:华纳圣淘沙公司开户流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户流程说明书(183-8890-9465—?薇-STS5099【6011643】

  46. 华纳圣淘沙开户步骤详解(183-8890-9465—?薇-STS5099【6011643】

    华纳圣淘沙公司开户流程全解析(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司账户注册指南(183-8890-9465—?薇-STS5099【6011643】
    新手如何开通华纳圣淘沙公司账户(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙企业开户标准流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户:从零到一(183-8890-9465—?薇-STS5099【6011643】
    官方指南:华纳圣淘沙公司开户流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户流程说明书(183-8890-9465—?薇-STS5099【6011643】

  47. 华纳圣淘沙公司开户新手教程

    零基础学会(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)

    一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)

    华纳圣淘沙公司开户分步图解

    首次开户必看:(183-8890-9465薇-STS5099)
    华纳圣淘沙全攻略

    华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
    华纳圣淘沙开户流程视频教程

    手把手教学:(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)

  48. 寻找华纳圣淘沙公司开户代理(183-8890-9465薇-STS5099】

    华纳圣淘沙官方合作开户渠道(183-8890-9465薇-STS5099】

    华纳圣淘沙公司开户代理服务(183-8890-9465薇-STS5099】

    华纳圣淘沙公司开户咨询热线(183-8890-9465薇-STS5099】

    联系客服了解华纳圣淘沙开户

    (183-8890-9465薇-STS5099】
    华纳圣淘沙公司开户专属顾问

    (183-8890-9465薇-STS5099】

  49. 《华纳圣淘沙公司开户流程全解析》→ 官方顾问一对一指导??? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙开户步骤详解》→ 」专属通道快速办理??? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙账户注册指南》→ 扫码获取完整资料清单?「微?? 安全联系:183第三段8890第四段9465
    《新手开通华纳圣淘沙公司账户指南》→ 限时免费咨询开放??? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙企业开户标准流程》→ 资深顾问实时解答疑问??? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙开户步骤全景图》→ 点击获取极速开户方案??? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙账户创建全流程手册》→ 预约顾问免排队服务?9?? 安全联系:183第三段8890第四段9465 《从零开通华纳圣淘沙公司账户》→ 添加客服领取开户工具包?? 安全联系:183第三段8890第四段9465
    《官方授权:华纳圣淘沙开户流程》→ 认证顾问全程代办?」?? 安全联系:183第三段8890第四段9465
    《华纳圣淘沙开户说明书》→立即联系获取电子版文件??? 安全联系:183第三段8890第四段9465

添加新评论