How to format or parse a time in Golang

Category:
Tags:
Last Updated: 2022/02/09 03:25:35

I'm going to write about how to format or parse a time in Golang, because the usage of Golang time package is sometimes a little tricky for me.


# Format a time.Time Variable into a String

# Basic Usage

In other languages like PHP, Python, or SQL, date or time format patterns are usually like Y-m-d or %Y-%m-%d, but in Golang, time format argument should be a specific form of 2nd January 2006 15:04:05 MST -07:00.

package main

import (
	"fmt"
	"time"
)
func main() {
	t := time.Now()
	fmt.Println(string(t.Format("2006-01-02 15:04:05")),"\n") // 2022-01-05 14:57:24 
}
1
2
3
4
5
6
7
8
9
10

Why 2nd January 2006 15:04:05 MST -07:00? The answer is in the following line quoted from time/format.go (opens new window).

Layout      = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
1

# Format Parameters

I will write down here what characters can be put in a format parameters. You can find them also by looking at time/format.go (opens new window).

Format Description
Year 2006 A full numeric representation of a year, 4 digits
06 A two digit representation of a year
Month 1 Numeric representation of a month, with leading zeros
01 Numeric representation of a month, without leading zeros
Jan A short textual representation of a month, three letters
January A full textual representation of a month
Day 2 Day of the month without leading zeros
02 Day of the month, 2 digits with leading zeros
_2 Day of the month with leading spaces like " 2"
Week Mon A textual representation of a day, three letters
Monday A full textual representation of the day of the week
Hour 15 24-hour format of an hour with leading zeros
03 12-hour format of an hour with leading zeros
3 12-hour format of an hour without leading zeros
PM "AM" or "PM"
pm "am" or "pm"
Minute 04 Minutes with leading zeros
4 Minutes without leading zeros
Second 05 Seconds with leading zeros
5 Seconds without leading zeros
TimeZone MST Timezone identifier. Japanese timezone will be "JST" (not "Asia/Tokyo")
Z0700 Difference to Greenwich time (GMT) without colon. Japanese timezone would be "+0900", but UTC timezone will be just "Z".
Z07:00 Difference to Greenwich time (GMT) with colon. Japanese timezone would be "+09:00", but UTC timezone will be just "Z".
-07:00 Difference to Greenwich time (GMT) with colon. Japanese timezone would be "+0900"
-0700 Difference to Greenwich time (GMT) without colon. Japanese timezone would be "+09:00"
-07 GMT offset. In the case of Japan, it will be "+09"

24-hour format of 0 o'clock will be 12AM, and 12 o'clock will be 12PM.
(I feel it slight weird but it might be because I'm Japanese. In Japanese language, usually midnight is referred to as 午前0時 which literally means 0AM, and noon is referred to as 午前12時 or 午後0時 , which respectively means 12AM or 0PM. I don't know the situation of other languages)


# Standard Format

Actually some standard formats are defined in time/format.go (opens new window), so I would recommend to use this format to prevent typos.

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"
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

For example, time.RFC3339 may be usable to save or extract data using a database.

t := time.Now()
fmt.Println(string(t.Format(time.RFC3339)),"\n") // 2022-01-05T15:42:15+09:00
1
2

# Convert a String into time.Time Type

In Golang, you can use time.Parse method to convert a string into a time.Time variable.

t, err := time.Parse("2006-01-02 15:04:05", "2022-01-05 15:42:15")
if err != nil {
	panic(err)
}
fmt.Println(t) // 2022-01-05 15:42:15 +0000 UTC
1
2
3
4
5

As I wrote in the above, some format constants are defined in the time package, so you can actually use them.

t, err := time.Parse(time.RFC3339, "2022-01-05T15:42:15+09:00")
if err != nil {
	panic(err)
}
fmt.Println(t) // 2022-01-05 15:42:15 +0900 JST
1
2
3
4
5

With using time.Parse method, make sure that it doesn't work with slight differences between a format string and a parsed string such as unnecessary spaces or letters.


# Golang equivalent of PHP strtotime

I created a library to parse a datetime string on GitHub because time.Parse is sometimes tricky.

go-timeparser (opens new window)

import "github.com/kaz-yamam0t0/go-timeparser/timeparser"

// tdata, _ := Now()
// tdata, _ := New("2022-01-31 11:22:33.123456789")

// tdata, _ := NewAsUTC("2022-01-31 11:22:33.123456789")
tdata, _ := NewAsUTC("31st Jan 2022 11:22:33.123456789")

// 
// If you want to adjust the timezone offset difference from your local env, 
// first create a variable with `New()` and then convert it to UTC with `SetUTC()`
// 
// tdata, _ := New("2022-01-31 11:22:33.123456789")
// tdata.SetUTC()

fmt.Println(tdata.GetYear())        // 2022
fmt.Println(tdata.GetMonth())       // 1
fmt.Println(tdata.GetDay())         // 31
fmt.Println(tdata.GetHour())        // 11
fmt.Println(tdata.GetMinute())      // 22
fmt.Println(tdata.GetSecond())      // 33
fmt.Println(tdata.GetMillisecond()) // 123
fmt.Println(tdata.GetMicrosecond()) // 123456
fmt.Println(tdata.GetNanosecond())  // 123456789

// 
// Format
// 
fmt.Println(tdata.String()) // 2022-01-31T11:22:33+00:00
fmt.Println(tdata.Format("l jS \\of F Y h:i:s A")) // Monday 31st of January 2022 06:22:33 PM

// 
// Setter methods
// 
tdata.SetYear(2022)
tdata.SetMonth(1)
tdata.SetDay(31)
tdata.SetHour(11)
tdata.SetMinute(22)
tdata.SetSecond(33)

// 
// Difference 
// 
tm, _ := NewAsUTC("2020-12-31 11:22:33.123456789")
fmt.Println(tdata.DiffYears(tm))   // 1
fmt.Println(tdata.DiffMonths(tm))  // 13
fmt.Println(tdata.DiffDays(tm))    // 396
fmt.Println(tdata.DiffHours(tm))   // 9504
fmt.Println(tdata.DiffMinutes(tm)) // 570240
fmt.Println(tdata.DiffSeconds(tm)) // 34214400
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

Category:
Tags:
Last Updated: 2022/02/09 03:25:35
Copyright © Web Ninja All Rights Reserved.