Golang Time Format Examples [With Explanation]


GO

Author: Tuan Nguyen
Reviewer: Deepak Prasad

Out of the box, Go (Golang) supports time formatting. In this tutorial, we will walk through some examples of working with time formatting in Golang. When formatting a date time, you have to specify pattern-based layouts and use the Format() function in the time package:

func (t Time) Format(layout string) string: Format returns a textual representation of the time value formatted according to the layout defined by the argument. See the documentation for the constant called Layout to see how to represent the layout format.

 

The Unique Nature of Golang's Time Formatting

Golang, in its commitment to clarity and simplicity, handles time formatting and parsing in a way distinct from most other programming languages. Instead of using format specifiers like %Y, %m, %d, etc., as seen in languages like Python or C, Go uses a reference time to dictate the layout.

The Reference Time: "Mon Jan 2 15:04:05 MST 2006"

This string is a representation of a specific moment: Monday, 02 January 2006, 15:04:05 PM, in the Mountain Standard Time zone. This moment is not arbitrary, though; each component of the reference time serves as a placeholder:

  • Mon - abbreviated weekday
  • Jan - abbreviated month
  • 2 - day of the month
  • 15 - hour (24-hour clock)
  • 04 - minute
  • 05 - second
  • MST - timezone abbreviation
  • 2006 - year

When you want to format (or parse) a time in Go, you provide a layout string that uses these components in the desired order and format.

For example, if you want a layout that represents a date in the format "YYYY-MM-DD", you'd use the layout 2006-01-02. If you're looking to format a time like "HH:mm:ss", then the layout string would be 15:04:05.

 

Supported Golang Time Layouts

You can refer golang time format page to get the list of supported cost values to manipulate the time output. Here is a table depicting the same information:

Unit Golang Layout Examples Note
Year 06 21, 81, 01
Year 2006 2021, 1981, 0001
Month January January, February, December
Month Jan Jan, Feb, Dec
Month 1 1, 2, 12
Month 01 01, 02, 12
Day Monday Monday, Wednesday, Sunday
Day Mon Mon, Wed, Sun
Day 2 1, 2, 11, 31
Day 02 01, 02, 11, 31 zero padded day of the month
Day _2 ⎵1, ⎵2, 11, 31 space padded day of the month
Day 002 001, 002, 011, 031, 145, 365, 366 zero padded day of the year
Day __2 ⎵⎵1, ⎵⎵2, ⎵11, ⎵31, 365, 366 space padded day of the year
Part of day PM AM, PM
Part of day pm am, pm
Hour 24h 15 00, 01, 12, 23
Hour 12h 3 1, 2, 12
Hour 12h 03 01, 02, 12
Minute 4 0, 4 ,10, 35
Minute 04 00, 04 ,10, 35
Second 5 0, 5, 25
Second 05 00, 05, 25
10-1 to 10-9 s .0 .000000000 .1, .199000000 Trailing zeros included
10-1 to 10-9 s .9 .999999999 .1, .199 Trailing zeros omitted
Time zone MST UTC, MST, CET
Time zone Z07 Z, +08, -05 Z is for UTC
Time zone Z0700 Z, +0800, -0500 Z is for UTC
Time zone Z070000 Z, +080000, -050000 Z is for UTC
Time zone Z07:00 Z, +08:00, -05:00 Z is for UTC
Time zone Z07:00:00 Z, +08:00:00, -05:00:00 Z is for UTC
Time zone -07 +00, +08, -05
Time zone -0700 +0000, +0800, -0500
Time zone -070000 +000000, +080000, -050000
Time zone -07:00 +00:00, +08:00, -05:00
Time zone -07:00:00 +00:00:00, +08:00:00, -05:00:00

 

Supported Golang Time Formats

You can refer golang time format page to get the list of supported cost values to manipulate the time output. Here is a table depicting the same information:

Format Example
ANSIC Tue Oct 4 18:54:28 2022
UnixDate Tue Oct 4 18:54:28 +07 2022
RubyDate Tue Oct 04 18:54:28 +0700 2022
RFC822 04 Oct 22 18:54 +07
RFC822Z 04 Oct 22 18:56 +0700
RFC850 Tuesday, 04-Oct-22 18:54:28 +07
RFC1123 Tue, 04 Oct 2022 18:54:28 +07
RFC1123Z Tue, 04 Oct 2022 18:54:28 +0700
RFC3339 2022-10-04T18:54:28+07:00
RFC3339Nano 2022-10-04T18:54:28.0977814+07:00

 

Format time output with a pre-defined format

Based on the above formats, we can easily format a time value using any of those constants. Let's look at an example.

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now.Format(time.ANSIC))          // Tue Oct  4 18:56:48 2022
	fmt.Println(now.Format(time.UnixDate))       // Tue Oct  4 18:56:48 +07 2022
	fmt.Println(now.Format(time.RubyDate))       // Tue Oct 04 18:56:48 +0700 2022
	fmt.Println(now.Format(time.RFC822))         // 04 Oct 22 18:56 +07
	fmt.Println(now.Format(time.RFC822Z))        // 04 Oct 22 18:56 +0700
	fmt.Println(now.Format(time.RFC850))         // Tuesday, 04-Oct-22 18:56:48 +07
	fmt.Println(now.Format(time.RFC1123))        // Tue, 04 Oct 2022 18:56:48 +07
	fmt.Println(now.Format(time.RFC1123Z))       // Tue, 04 Oct 2022 18:56:48 +0700
	fmt.Println(now.Format(time.RFC3339))        // 2022-10-04T18:56:48+07:00
	fmt.Println(now.Format(time.RFC3339Nano))    // 2022-10-04T18:56:48.74371+07:00
}

 

Format a time with a customized layout (YYYYMMDDHHMMSS)

In the below example, we will use Format() function to change the date time's format. We have to define the layout first, then pass it as parameter to Format() function:

package main

import (
	"fmt"
	"time"
)

func displayDate(format string) {
	fmt.Println(time.Now().Format(format))
}

func main() {
	// The output time will vary for you
	// but you can check the time format in which we get the output
	displayDate("20060102150405")                    // YYYYMMDDHHMMSS Format
	displayDate("2006/01/02 15/04/05")               // YYYY/MM/DD HH/MM/SS Format
	displayDate("02/01/2006 15/04/05")               // DD/MM/YYYY HH/MM/SS Format
	displayDate("02/01/06 15/04/05")                 // DD/MM/YY HH/MM/SS Format
	displayDate("2006-01-02 15:04:05")               // YYYY-MM-DD HH:MM:SS Format
	displayDate("15:04:05, 2006-Jan-02 Mon")         // HH:MM:SS, YYYY-Mon-DD DayShort Format
	displayDate("15:04:05, 2006-Jan-02 Monday")      // HH:MM:SS, YYYY-Mon-DD DayLong Format
	displayDate("15:04:05, 2006-January-02 MST Mon") // HH:MM:SS, YYYY-Mon-DD TZ DayShort Format
	displayDate("3:4:05, 2006-1-02 MST Mon")         // H:M:SS, YYYY-M-DD TZ DayShort Format
	displayDate("3:4:05 pm, 2006-1-02 MST Mon")      // H:M:SS Part_of_day(small), YYYY-M-DD TZ DayShort Format
	displayDate("3:4:05 PM, 2006-1-02 MST Mon")      // H:M:SS Part_of_day(small), YYYY-M-DD TZ DayShort Format
	displayDate("03:04:05.000")                      // HH:MM:SS.MilliSeconds
	displayDate("03:04:05.000000")                   // HH:MM:SS.MicroSeconds
	displayDate("03:04:05.000000000")                // HH:MM:SS.NanoSeconds
}

Output:

# go run main.go 
20221007002045
2022/10/07 00/20/45
07/10/2022 00/20/45
07/10/22 00/20/45
2022-10-07 00:20:45
00:20:45, 2022-Oct-07 Fri
00:20:45, 2022-Oct-07 Friday
00:20:45, 2022-October-07 IST Fri
12:20:45, 2022-10-07 IST Fri
12:20:45 am, 2022-10-07 IST Fri
12:20:45 AM, 2022-10-07 IST Fri
12:20:45.618
12:20:45.618877
12:20:45.618882881

Time is measured in nanosecond precision, but the computer may not be able to measure time passing at this resolution, so steps in time may happen in multiple nanoseconds. The time package has these durations built-in:

  • Nanosecond Duration = 1
  • Microsecond = 1000 * Nanosecond
  • Millisecond = 1000 * Microsecond
  • Second = 1000 * Millisecond
  • Minute = 60 * Second
  • Hour = 60 * Minute

 

Golang time parse format from strings

The time package provides support for creating Time values from strings

  • Parse(layout, str): This function parses a string using the specified layout to create a Time value. An error is returned to indicate problems parsing the string.
  • ParseInLocation(layout, str, location): This function parses a string, using the specified layout and using the Location if no time zone is included in the string. An error is returned to indicate problems parsing the string.

 

Using Parse() function

The Parse function assumes that dates and times expressed without a time zone are defined in Coordinated Universal Time (UTC). The ParseInLocation method can be used to specify a location that is used when no time zone is specified

func Parse(layout, value string) (Time, error): Parse parses a formatted string and returns the time value it represents. The second argument must be parseable using the format string (layout) provided as the first argument.

We can use a pre-defined layout, as shown in Example 1, or a customized one, as shown in Example 2. Here's an example of a string being parsed to a specific data format using Parse() function:

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("Time parsing")

	dateString := "2014-11-09T12:40:45.15Z"
	dateString2 := "2022-10-12T10:15:16.371+07:00"

	time1, err := time.Parse(time.RFC3339, dateString)
	if err != nil {
		fmt.Println("Error while parsing date :", err)
	}
	fmt.Println(time1)

	time2, err := time.Parse(time.RFC3339, dateString2)
	if err != nil {
		fmt.Println("Error while parsing date :", err)
	}
	fmt.Println(time2)

	dateString3 := "2007-10-09 22:50:02.023"
	time3, err := time.Parse("2006-01-02 15:04:05.000", dateString3)
	if err != nil {
		fmt.Println("Error while parsing date :", err)
	}
	fmt.Println(time3)
}

Output:

Time parsing
2014-11-09 12:40:45.15 +0000 UTC
2022-10-12 10:15:16.371 +0700 +07
2007-10-09 22:50:02.023 +0000 UTC

 

Using ParseInLocation() function

func ParseInLocation(layout, value string, loc *Location) (Time, error): ParseInLocation is like Parse but differs in two important ways. First, in the absence of time zone information, Parse interprets a time as UTC; ParseInLocation interprets the time as in the given location. Second, when given a zone offset or abbreviation, Parse tries to match it against the Local location; ParseInLocation uses the given location.

Here's an example convert a string to a specific data format, consider the location and time zone:

package main

import (
	"fmt"
	"time"
)

func PrintTime(label string, t *time.Time) {
	fmt.Println(label, t.Format(time.RFC822Z))
}
func main() {
	// Choose your layout MM YYY DD HH:SS
	layout := "02 Jan 06 15:04"
	// Format this date with Location Timezone
	date := "09 Jun 22 19:30"
	// Load the locations to Parse
	india, inerr := time.LoadLocation("Asia/Kolkata")
	newyork, nycerr := time.LoadLocation("America/New_York")
	if inerr == nil && nycerr == nil {
		nolocation, _ := time.Parse(layout, date)
		indiaTime, _ := time.ParseInLocation(layout, date, india)
		newyorkTime, _ := time.ParseInLocation(layout, date, newyork)
		PrintTime("No location:", &nolocation)
		PrintTime("India:", &indiaTime)
		PrintTime("New York:", &newyorkTime)
	} else {
		fmt.Println(inerr.Error(), nycerr.Error())
	}

}

Output:

$ go run main.go 
No location: 09 Jun 22 19:30 +0000
India: 09 Jun 22 19:30 +0530
New York: 09 Jun 22 19:30 -0400

 

Using time.ParseDuration() function

The time.ParseDuration function parses strings to create Duration values. This function returns a Duration and an error, indicating if there were problems parsing the specified string.

Following table describes the Duration String Unit Indicators

Unit Description
h This unit denotes hours.
m This unit denotes minutes.
s This unit denotes seconds.
ms This unit denotes milliseconds.
us or μs These units denotes microseconds.
ns This unit denotes nanoseconds.

No spaces are allowed between values, which can be specified as integer or floating-point amounts.

package main

import (
	"fmt"
	"time"
)

func Printfln(template string, values ...interface{}) {
	fmt.Printf(template+"\n", values...)
}

func main() {
	d, err := time.ParseDuration("1h30m")
	if err == nil {
		Printfln("Hours: %v", d.Hours())
		Printfln("Mins: %v", d.Minutes())
		Printfln("Seconds: %v", d.Seconds())
		Printfln("Millseconds: %v", d.Milliseconds())
	} else {
		fmt.Println(err.Error())
	}
}

The string specifies 1 hour and 30 minutes.

$ go run main.go 
Hours: 1.5
Mins: 90
Seconds: 5400
Millseconds: 5400000 

 

Localized Time Formatting in Go

When building applications that cater to a global audience or operate across multiple geographies, dealing with time in various locales and time zones becomes essential. This section will discuss handling different locales and time zones in Go and some challenges and solutions associated with it.

Golang's standard library doesn't provide direct locale-based date and time formatting out of the box. However, locales influence several aspects of time representation:

  1. Weekday and Month Names: In English, we have "Monday" or "January." In French, they'd be "Lundi" or "Janvier."
  2. Order of Elements: Some locales might represent dates as YYYY-MM-DD, while others may prefer DD-MM-YYYY.
  3. First Day of the Week: In many western countries, Sunday is the first day of the week. In others, it's Monday.

Use third-party libraries like golang.org/x/text/message for localization. This package provides functionality for locale-specific messaging.

 

Handling Different Time Zones

With Go's time package, handling different time zones becomes relatively straightforward:

Loading a Location:

loc, err := time.LoadLocation("America/New_York")
if err != nil {
    panic(err)
}

Converting a Time to a Specific Location:

t := time.Now()
tInNewYork := t.In(loc)

UTC: UTC is the universal time standard. To get a time in UTC, use:

tUTC := t.UTC()

 

Operations with Time in Go

When working with time in Go, there are often needs to perform various arithmetic operations, such as adding or subtracting intervals, or even comparing two time points. The Go time package offers robust tools for these tasks.

Differences between time.Duration and Formatted Time

  1. time.Duration:
    • Represents a span of time.
    • Is an int64 representation of nanoseconds, so it's a precise value.
    • Has constants like time.Second, time.Minute, etc., for human-readable duration values.
    • Can be positive (to represent durations after a time point) or negative (for durations before a time point).
  2. Formatted Time:
    • Represents a specific point in time.
    • Is an instance of the time.Time type.
    • Can be output in various string formats using the Format method.
    • Is timezone-aware, whereas time.Duration is just a span of time and doesn't concern itself with time zones.

 

Arithmetic Operations

Adding Time:

To add a duration to a time.Time value, use the Add method.

t := time.Now()
oneHourLater := t.Add(1 * time.Hour)

Subtracting Time:

To subtract a duration, you can use the Add method with a negative duration, or the Sub method to get the duration between two times.

t := time.Now()
oneHourEarlier := t.Add(-1 * time.Hour)  // Using Add with negative duration

timePassed := t.Sub(oneHourEarlier)      // Using Sub to get the duration

Comparing Times:

Use the methods Before, After, and Equal on a time.Time value to compare it with another.

t1 := time.Now()
t2 := t1.Add(1 * time.Hour)

if t1.Before(t2) {
    fmt.Println("t1 is before t2")
}

if t1.Equal(t2) {
    fmt.Println("t1 is the same time as t2")
}

Duration Arithmetic:

You can also perform arithmetic operations on time.Duration values directly.

duration1 := 2 * time.Hour
duration2 := 30 * time.Minute

total := duration1 + duration2   // Results in 2.5 hours

Round and Truncate:

  • The Round method rounds a time.Duration to the nearest multiple of another duration.
  • The Truncate method truncates a time.Duration to the nearest multiple of another duration but doesn't round up.
d := 1*time.Hour + 41*time.Minute
fmt.Println(d.Round(1 * time.Hour))    // 2h0m0s
fmt.Println(d.Truncate(1 * time.Hour)) // 1h0m0s

 

Summary

In this article, I demonstrated how to perform golang time format using a predefine layout such as YYYYDDMM HH:MM:SS or print the time in nanoseconds, milliseconds, microseconds etc. Convert a string to a specific date format with time.Parse() and time.Format(). We can use either predefined or custom layouts.

 

References

https://www.timeanddate.com/time/map/
https://pkg.go.dev/time#ParseInLocation

 

Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment