I'm trying to format a series a date such as:
2013-03-12-15.txt
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 !
In case you need 24-hour format and don't want the leading zero for hour < 10
I only see a custom string format:
date := fmt.Sprintf("%d-%d-%d-%d", 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("%s-%d.txt", t.Format("2006-01-02"), t.Hour())
fmt.Println(date)
Use Time.Format
only to format year/month and format the time yourself.
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)
}
You can see the number conversion table in the source code of format.go. Relevant part:
const (
// ...
stdHour = iota + stdNeedClock // "15"
stdHour12 // "3"
stdZeroHour12 // "03"
// ...
)
There's no such thing as stdZeroHour
, so no alternative behaviour for stdHour
.
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)
}
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 (
"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())
}