V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
meta
V2EX  ›  Go 编程语言

关于golang的Time格式

  •  
  •   meta · 2013-11-26 18:58:59 +08:00 · 3837 次点击
    这是一个创建于 3766 天前的主题,其中的信息可能已经有所发展或是发生改变。
    golang的Time格式是不是太诡异了一点啊。
    我想输出一个带毫秒的时间,看到标准库里说支持到纳秒,我想这应该没问题。
    但是在常量表里的格式就那么几种,其中带纳秒的是RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"。

    那么就只能输出15:04:05.999999999这样的格式,但我实际上是想输出15:04:05,999999999这样的格式啊,看了半天也没找到该怎么做。

    我现在只能一个一个字段从Time里面拽出来再组合起来,但是我这边不只是要输出,还需要输入的,我还想Parse一个这样格式的字符串到Time里面,那该怎么搞呢。
    11 条回复    2015-09-02 22:26:11 +08:00
    rwx
        1
    rwx  
       2013-11-26 19:29:38 +08:00   ❤️ 1
    刚测试了一下,time包里nano的格式好像只能是带「.」的「.000000000」或者「.999999999」才能识别,格式化出来的字符串,也带「.」……
    time.Now().Format("15:04:05,.999999999") //19:21:04,.583492285
    所以一个一个的读然后再组合可能还是最清晰的方式了

    然后就是Parse用的格式和Format一样,并且如果你的格式里没给人家带出年份的话,它会甩给你一个巨大的负数时间戳,估计年份直接是0000年了
    t, err := time.ParseInLocation("2006-01-02 15:04:05.999999999", "2013-11-26 19:08:17.583492285", time.Local)
    fmt.Println(t.Unix(), t.Nanosecond(), err)
    meta
        2
    meta  
    OP
       2013-11-26 19:59:11 +08:00
    年份到无所谓,我测试过,可以忽略掉,计算还是准确的,不显示就行了。倒是这个格式太坑爹了,看来只能自己写代码匹配了。
    gihnius
        3
    gihnius  
       2013-11-26 20:13:14 +08:00   ❤️ 1
    通过 Sprintf 转换一下吧
    rlx
        4
    rlx  
       2013-11-28 10:08:45 +08:00
    试试这个行不行

    import "time"
    import "fmt"
    import "strings"

    const DefaultTimeFormat1 = "2006-01-02T15:04:05,999999999"
    const DefaultTimeFormat2 = "2006-01-02T15:04:05.999999999"

    func main() {
    fmt.Printf("Time: %s\n, time.Now().Format(DefaultTimeFormat1))

    // Transfer 2013-11-26 19:08:17,583492285 to time
    timeStr = "2013-11-26 19:08:17,583492285"
    timeStr = strings.Replace(timeStr, ",", ".", 1)

    t, err := time.Prase(timeStr, DefaultTimeFormat2)
    if err != nil {
    fmt.Println(err)
    return
    }

    fmt.Printf("TimeTransfer: %s\n, t.Format(DefaultTimeFormat1))
    }
    rlx
        5
    rlx  
       2013-11-28 10:10:22 +08:00
    e, fmt.Printf里面漏掉了一个 "。
    rlx
        6
    rlx  
       2013-11-28 10:24:09 +08:00   ❤️ 1
    修改了一下。

    package main

    import (
    "time"
    "fmt"
    "strings"
    )

    const (
    DefaultTimeFormat = "2006-01-02 15:04:05.999999999"
    )

    func main() {
    timeStr := time.Now().Format(DefaultTimeFormat)
    timeStr = strings.Replace(timeStr, ".", ",", 1)
    fmt.Printf("TimeNow: %s\n", timeStr)

    timeStr = "2013-11-26 19:08:17,583492285"
    fmt.Println("TimeTransferBefore:", timeStr)

    timeStr = strings.Replace(timeStr, ",", ".", 1)

    t, err := time.Parse(DefaultTimeFormat, timeStr)
    if err != nil {
    fmt.Println(err)
    return
    }

    timeStr = t.Format(DefaultTimeFormat)
    timeStr = strings.Replace(timeStr, ".", ",", 1)
    fmt.Println("TimeTransferAfter:", timeStr)
    }
    meta
        7
    meta  
    OP
       2013-11-28 12:58:24 +08:00
    @rlx 我也考虑过直接替换的办法,但这只是个临时办法,只能解决这一种情况,还是不定自由的设置格式。
    其实要解决并不困难,用自己的Parse就行了。我只是觉得golang的这种设计很奇怪,为什么一个时间模板的前面几段都是整数和字符串,最后一段必须要是一个小数。
    rlx
        8
    rlx  
       2013-11-29 12:43:48 +08:00
    嗯,那可以fork 一下 $GOROOT/src/pkg/time/format.go
    meta
        9
    meta  
    OP
       2013-11-29 13:21:54 +08:00
    看过了,写死的:
    if len(value) >= 2 && value[0] == '.' && isDigit(value, 1)
    DawnDIY
        10
    DawnDIY  
       2014-01-17 15:29:21 +08:00
    @meta Golang 这样设计是有原因的2006-01-02T15:04:05Z07:00 这个时间是有意义的,换一种方式就是 “01/02 03:04:05PM '06 -0700” 表示为 月、日、时、分、秒、年、时区。你按1~7记好以后会很方便的。
    chenwl
        11
    chenwl  
       2015-09-02 22:26:11 +08:00
    @DawnDIY 学习了,传入的模板确实诡异。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3205 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:03 · PVG 22:03 · LAX 07:03 · JFK 10:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.