Often we find ourselves with a Date Time that is not in some standard format. This is where we identify the pattern of the date time and then try to write a custom layout.
Let us see how we can achieve this in go using the standard time package. The time package provides us with several functionalities which includes functions like Parse and Format that serves our purpose.
Parse
Parse parses a formatted string and returns the time value it represents.
func Parse(layout, value string) (Time, error)
package main
import (
"fmt"
"time"
)
func main() {
const longForm = "Jan 2, 2006 at 3:04pm (MST)"
t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
fmt.Println(t)
const shortForm = "2006-Jan-02"
t, _ = time.Parse(shortForm, "2013-Feb-03")
fmt.Println(t)
}
Output:
2013-02-03 19:54:00 +0000 PST
2013-02-03 00:00:00 +0000 UTC
Go Playground Link: Parse Example
Format
Format returns a textual representation of the time value formatted according to the layout defined by the argument.
func (t Time) Format(layout string) string
func main() {
t, err := time.Parse(time.UnixDate, "Wed Feb 25 11:06:39 PST 2015")
if err != nil { // Always check errors even if they should not happen.
panic(err)
}
fmt.Println("default format:", t)
fmt.Println("Unix format:", t.Format(time.UnixDate))
}
Output:
default format: 2015-02-25 11:06:39 +0000 PST
Unix format: Wed Feb 25 11:06:39 PST 2015
Go Playground Link: Format Example
Predefined Layouts available in time package
Label | Definition |
---|---|
Layout | 01/02 03:04:05PM '06 -0700 |
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 |
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 |
RFC3339 | 2006-01-02T15:04:05Z07:00 |
RFC3339Nano | 2006-01-02T15:04:05.999999999Z07:00 |
Kitchen | 3:04PM |
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 |
Building Blocks for creating your own layout
Type | Options |
---|---|
Year | "2006", "06" |
Month | "Jan", "January", "1", "01" |
Textual day of the week | "Mon", "Monday" |
Numeric day of the month | "2", "_2", "02" |
Numeric day of the year | "__2", "002" |
Hour | "15", "3", "03" (PM or AM) |
Minute | "4", "04" |
Second | "5", "05" |
AM/PM mark | "PM" |
For layouts specifying the two-digit year 06, a value NN >= 69 will be treated as 19NN and a value NN < 69 will be treated as 20NN.
Numeric time zone offsets format as follows:
Value | Format |
---|---|
"-0700" | ±hhmm |
"-07:00" | ±hh:mm |
"-07" | ±hh |
Replacing the sign in the format with a Z triggers the ISO 8601 behavior of printing Z instead of an offset for the UTC zone. Thus:
Value | Format |
---|---|
"Z0700" | Z or ±hhmm |
"Z07:00" | Z or ±hh:mm |
"Z07" | Z or ±hh |
Final Example
func main() {
ipTimes := []string{
"24 Aug 2021 7:20:50 PM",
"Aug 24 2021 07:20:50PM",
"24-08-2021 17:20:50",
"08-24-2021 13:12:32",
"24/8/21 9:00:12",
"8/24/2021 10:10:10",
"1993-11-23 7**12**44PM",
"24 October 97 7:12:45PM+05:30", // 24 th January 1997
}
layouts := []string{
"2 Jan 2006 3:04:05 PM",
"Jan 2 2006 03:04:05PM",
"2-01-2006 15:04:05",
"01-02-2006 15:4:5",
"2/1/06 3:4:5",
"1/2/2006 3:4:5",
"2006-01-02 3**4**5PM",
"2 January 06 3:4:5PMZ07:00",
}
for i := 0; i < len(ipTimes); i++ {
t, err := time.Parse(layouts[i], ipTimes[i]) // parsing to get time value
if err != nil { // check for errors
fmt.Println(err)
return
}
fmt.Println(" Input DateTime String: ", ipTimes[i])
fmt.Println(" Layout: ", layouts[i])
fmt.Println("Time value Default Format: ", t)
fmt.Println(" Time in RFC3339 Format: ", t.Format(time.RFC3339))
}
}
Let us take one such example to iterate through it
Input: "24 October 97 7:12:45PM+05:30"
Layout: "2 January 06 3:4:5PMZ07:00"
From the building blocks listed above we can map things
Layout Key | Actual Value | Description |
---|---|---|
2 | 24 | Numeric day of the month |
January | October | month |
06 | 97 | Year (1997) |
3 | 7 | Hour |
4 | 12 | Minute |
5 | 45 | Second |
Z07:00 | +05:30 | Offset |
Since PM is specified 7:12:45 is in 12 hour format.
Using the Layout blocks specified we can easily see the pattern and can create our own layout.
Fun Tip
Ever wondered why time.Now()
on golang playground prints the same time (2009-11-10 23:00:00 +0000 UTC m=+0.000000001) ?
Drum roll!!!!!!
It is the time and date of Go Lang's birthday.
Hope you learnt something new or had your concepts revised.
Let me know if I missed something.
Complete Working Date Time Example
Top comments (0)