使用golang的time包,将单个数字的小时转换为0开头的格式。

huangapple go评论76阅读模式
英文:

Losing 0 for single-digit hours with golang time package

问题

我正在尝试格式化一系列日期,例如:

  • 2013年3月12日下午3点 的格式为:2013-03-12-15.txt
  • 2013年3月12日上午4点 的格式为:2013-03-12-4.txt

使用golang和Time包:

package main

import (
	"time"
	"fmt"
)

const layout = "2006-01-02-15.txt"

func main() {
	t := time.Date(2013, time.March, 12, 4, 0, 0, 0, time.UTC)
	fmt.Println(t.Format(layout))
}

不幸的是,这会在单个数字的小时前面添加一个零:2013-03-12-04.txt

有没有一种惯用的方法来达到期望的输出,或者我必须自己使用String包进行调整?

提前感谢你的帮助!

英文:

I'm trying to format a series a date such as:

  • March 12th, 2013, 3pm looks like : 2013-03-12-15.txt
  • March 12th, 2013, 4am looks like : 2013-03-12-4.txt

Using golang and the Time package

package main

import (
	"time"
	"fmt"
)

const layout = "2006-01-02-15.txt"

func main() {
	t := time.Date(2013, time.March, 12, 4, 0, 0, 0, time.UTC)
	fmt.Println(t.Format(layout))
}

Which unfortunately add a zero in front of the single-digit hour : 2013-03-12-04.txt

Is there an idiomatic way to reach the desired output, or I must tweak myself something with the String package ?

Thanks in advance for your help !

答案1

得分: 10

如果你需要24小时制的时间格式,并且不想在hour < 10时显示前导零,我只能看到一个自定义的字符串格式化方法:

date := fmt.Sprintf("%d-%d-%d-%d", t.Year(), t.Month(), t.Day(), t.Hour())

当然,这不是Go语言中格式化日期的惯用方式。

更新(感谢评论):

t := time.Now()
date := fmt.Sprintf("%s-%d.txt", t.Format("2006-01-02"), t.Hour())
fmt.Println(date)
英文:

In case you need 24-hour format and don't want the leading zero for hour &lt; 10 I only see a custom string format:

date := fmt.Sprintf(&quot;%d-%d-%d-%d&quot;, t.Year(), t.Month(), t.Day(), t.Hour())

Of course not an idiomatic way to format a date in Go.

Update (thanks for the comment):

t := time.Now()	
date := fmt.Sprintf(&quot;%s-%d.txt&quot;, t.Format(&quot;2006-01-02&quot;), t.Hour())
fmt.Println(date)

答案2

得分: 4

使用Time.Format仅格式化年/月,并自己格式化时间。

package main

import (
	"fmt"
	"time"
)

const layout = "2006-01-02-%d.txt"

func main() {
	t := time.Date(2013, time.March, 12, 4, 0, 0, 0, time.UTC)
	f := fmt.Sprintf(t.Format(layout), 4)

	fmt.Printf(f)
}

你可以在这里播放

你可以在format.go的源代码中查看数字转换表。相关部分如下:

const (
// ...
	stdHour                  = iota + stdNeedClock // "15"
	stdHour12                                      // "3"
	stdZeroHour12                                  // "03"
// ...
)

没有stdZeroHour这样的东西,所以对于stdHour没有替代行为。

英文:

Use Time.Format only to format year/month and format the time yourself.

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

const layout = &quot;2006-01-02-%d.txt&quot;

func main() {
	t := time.Date(2013, time.March, 12, 4, 0, 0, 0, time.UTC)
	f := fmt.Sprintf(t.Format(layout), 4)

	fmt.Printf(f)
}

(Click to play)

You can see the number conversion table in the source code of format.go. Relevant part:

const (
// ...
	stdHour                  = iota + stdNeedClock // &quot;15&quot;
	stdHour12                                      // &quot;3&quot;
	stdZeroHour12                                  // &quot;03&quot;
// ...
)

There's no such thing as stdZeroHour, so no alternative behaviour for stdHour.

答案3

得分: 0

我在格式化时添加了填充以获得任何整数之前所需的前导零

package main

import (
	"fmt"
	"time"
)

var TimeFormat string = "%04d-%02d-%02d %02d:%02d:%02d"

func main() {
	fmt.Printf(TimeFormat, time.Now().Year(), time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second())
}

它的输出结果如下:

2022-07-13 18:41:50

从而得到了所需的前导零。

英文:

I added padding while I was formatting to get the desired leading 0's before any integer.

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

var TimeFormat string = &quot;%04d-%02d-%02d %02d:%02d:%02d&quot;

func main() {
	fmt.Printf(TimeFormat, time.Now().Year(), time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second())
}

It results in the following output

2022-07-13 18:41:50

resulting in the required leading 0's.

答案4

得分: -1

const (
    H12Format = "2006/1/2/3/4.txt"
    H24Format = "2006/1/2/15/4.txt"
)
func path(date time.Time) string {
    if date.Hour() < 10 {
        return date.Format(H12Format)
    }
    return date.Format(H24Format)
}

不幸的是[go playground] 不允许运行测试和基准测试

以下代码包含了之前的解决方案以及我的解决方案并进行了基准测试

在我的电脑上结果如下

BenchmarkA-4     5000000               293 ns/op              32 B/op          1 allocs/op
BenchmarkB-4     5000000               380 ns/op              48 B/op          2 allocs/op
BenchmarkC-4     3000000               448 ns/op              56 B/op          4 allocs/op

要自行测试请将代码复制到本地并运行`go test -benchmem -run=XXX -bench=Benchmark`

package format

import (
    "fmt"
    "testing"
    "time"
)

const (
    layout    = "2006-01-02-3.txt"
    layoutd   = "2006-01-02-%d.txt"
    H12Format = "2006/1/2/3/4.txt"
    H24Format = "2006/1/2/15/4.txt"
)

func BenchmarkA(b *testing.B) {
    for n := 0; n < b.N; n++ {
        path(time.Now())
    }
}

func BenchmarkB(b *testing.B) {
    for n := 0; n < b.N; n++ {
        fmtpath(time.Now())
    }
}

func BenchmarkC(b *testing.B) {
    for n := 0; n < b.N; n++ {
        longpath(time.Now())
    }
}
func path(date time.Time) string {
    if date.Hour() < 10 {
        return date.Format(H12Format)
    }
    return date.Format(H24Format)
}

func fmtpath(date time.Time) string {
    return fmt.Sprintf(date.Format(layoutd), 4)
}

func longpath(date time.Time) string {
    return fmt.Sprintf("%s-%d.txt", date.Format("2006-01-02"), date.Hour())
}

[go playground]: https://play.golang.org
英文:
const (
H12Format = &quot;2006/1/2/3/4.txt&quot;
H24Format = &quot;2006/1/2/15/4.txt&quot;
)    
func path(date time.Time) string {
if date.Hour() &lt; 10 {
return date.Format(H12Format)
}
return date.Format(H24Format)
}

Unfortunately the go playground doesn't allow running tests and benchmarks.

The following code contain the previous solutions and mine with benchmark.

On my computer these are the result:

BenchmarkA-4     5000000               293 ns/op              32 B/op          1 allocs/op
BenchmarkB-4     5000000               380 ns/op              48 B/op          2 allocs/op
BenchmarkC-4     3000000               448 ns/op              56 B/op          4 allocs/op

To test it yourself copy the code locally and run it: go test -benchmem -run=XXX -bench=Benchmark

package format
import (
&quot;fmt&quot;
&quot;testing&quot;
&quot;time&quot;
)
const (
layout    = &quot;2006-01-02-3.txt&quot;
layoutd   = &quot;2006-01-02-%d.txt&quot;
H12Format = &quot;2006/1/2/3/4.txt&quot;
H24Format = &quot;2006/1/2/15/4.txt&quot;
)
func BenchmarkA(b *testing.B) {
for n := 0; n &lt; b.N; n++ {
path(time.Now())
}
}
func BenchmarkB(b *testing.B) {
for n := 0; n &lt; b.N; n++ {
fmtpath(time.Now())
}
}
func BenchmarkC(b *testing.B) {
for n := 0; n &lt; b.N; n++ {
longpath(time.Now())
}
}
func path(date time.Time) string {
if date.Hour() &lt; 10 {
return date.Format(H12Format)
}
return date.Format(H24Format)
}
func fmtpath(date time.Time) string {
return fmt.Sprintf(date.Format(layoutd), 4)
}
func longpath(date time.Time) string {
return fmt.Sprintf(&quot;%s-%d.txt&quot;, date.Format(&quot;2006-01-02&quot;), date.Hour())
}

huangapple
  • 本文由 发表于 2014年5月2日 20:19:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/23428033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定