Skip to main content

Command Palette

Search for a command to run...

Day 12 - Go date & time

Published
6 min read

In Go, there is a package called time. It provides all the essential functionalities to work with dates, times, durations, and time zones. It can also hold information about the timezone and supports time-based operations like comparison, addition, and subtraction.


Basic Example

package main
import (
    "fmt"
    "time"
)

func main() {
    currentTime := time.Now()
    fmt.Println("The time is", currentTime)
}

Output

The time is 2025-11-02 10:32:58.0347725 +0530 IST m=+0.000000001

Explanation

  • It gives date, time, and timezone (IST).
  • The m= value is the monotonic clock used internally by Go.
  • The type of currentTime is time.Time.

Go’s Monotonic Clock

Go’s monotonic clock is used internally by the time package to measure time intervals (durations) reliably. Unlike the wall clock (which can change due to NTP updates or manual changes), a monotonic clock always moves forward and is unaffected by system clock adjustments.

It ensures that time measurements like elapsed durations, timeouts, and comparisons remain accurate — even if the system clock is changed.

Example: Measuring Execution Time Using Monotonic Clock

package main

import (
    "fmt"
    "time"
)

func main() {
    start := time.Now() // captures both wall and monotonic time
    time.Sleep(2 * time.Second)
    elapsed := time.Since(start)

    fmt.Println("Elapsed time:", elapsed)
}
Explanation
  • time.Now() records both wall-clock time and monotonic time internally.
  • time.Since(start) uses the monotonic component to calculate accurate elapsed time.
  • Even if the system clock changes during sleep, the elapsed duration remains correct.

Use monotonic time for measuring durations, not for displaying or storing timestamps.


Working with time.Time Methods

func main() {
    currentTime := time.Now()
    fmt.Println("The year is", currentTime.Year())
    fmt.Println("The month is", currentTime.Month())
    fmt.Println("The day is", currentTime.Day())
    fmt.Println("The hour is", currentTime.Hour())
    fmt.Println("The minute is", currentTime.Minute())
    fmt.Println("The second is", currentTime.Second())
}

Custom Formatting

Go uses a reference layout instead of placeholders for time formatting. That layout is always:

Mon Jan 2 15:04:05 MST 2006

Example

func main() {
    currentTime := time.Now()
    fmt.Println(currentTime.Format("2006-1-2 15:4:5"))
    fmt.Println(currentTime.Format("2006-01-02 03:04:05 pm"))
    fmt.Println(currentTime.Format("January 02 2006, 03 pm 04 min"))
    fmt.Println(currentTime.Format("Monday, January 02 2006"))
}

Output

2025-11-2 11:58:45
2025-11-02 11:58:45 am
November 02 2025, 11 am 58 min
Sunday, November 02 2025

⚠️ Note: You must always use 2006-01-02 15:04:05 as the base layout pattern. Any other reference (like 2007 or 14) will produce incorrect results.


Predefined Formats (RFC 3339)

Go provides several predefined layouts for common date/time formats.

One of the most used formats is RFC 3339, a standard timestamp format widely used on the internet.

func main() {
    currentTime := time.Now()
    fmt.Println(currentTime.Format(time.RFC3339Nano))
}

Output

2025-11-02T12:13:02.0125749+05:30

This format is widely used for APIs and databases because it’s compact and standardized. The RFC 3339 format is good to use if you need to save a time value as a string somewhere. It can be read by many other programming languages and applications, and is about as compact as a date and time can be in a flexible string format.


Parsing Time from String

func parseTime() {
    timeString := "2025-11-02 12:20:23"
    theTime, err := time.Parse("2006-01-02 03:04:05", timeString)
    if err != nil {
        fmt.Println("Could not parse time:", err)
        return
    }
    fmt.Println("The time is", theTime)
    fmt.Println(theTime.Format(time.RFC3339Nano))
}

Output

The time is 2025-11-02 12:20:23 +0000 UTC
2025-11-02T12:20:23Z

By default, time.Parse assumes UTC timezone unless you specify otherwise.

If the input timestamp includes a timezone (like -05:30), you can parse it directly using time.RFC3339Nano and then convert it to another timezone (like IST).

func parseTime() {
    timeString := "2025-11-02T12:20:23.0000001-05:30"

    // Parse using RFC3339Nano layout
    theTime, err := time.Parse(time.RFC3339Nano, timeString)
    if err != nil {
        fmt.Println("Could not parse time:", err)
        return
    }

    // Load IST timezone (Asia/Kolkata)
    ist, err := time.LoadLocation("Asia/Kolkata")
    if err != nil {
        fmt.Println("Error loading IST location:", err)
        return
    }

    // Convert to IST
    istTime := theTime.In(ist)

    fmt.Println("Original time:", theTime)
    fmt.Println("Time in IST :", istTime)
    fmt.Println("Formatted IST time:", istTime.Format(time.RFC3339Nano))
}

Output

Original time: 2025-11-02 12:20:23.0000001 -0530 -05:30
Time in IST : 2025-11-02 22:20:23.0000001 +0530 IST
Formatted IST time: 2025-11-02T22:20:23.0000001+05:30

You can observe that the pattern used here 2006-01-02 15:04:05 same as given above.


Timezones in go

In the below example you can clearly observe about how to convert time from one timezone to another timezone. Comparing the time difference between UTC and IST. You can compare between diff timezones.
Annd also i am printing the list of available timezones.

package main

import (
    "fmt"
    "time"
)

func main() {
    // Step 1: Capture the current time (includes monotonic clock)
    start := time.Now()
    fmt.Println("Current (Local) Time:", start)
    fmt.Println("------------------------------------------------")

    // Step 2: Convert to UTC and IST
    utc := start.UTC()
    ist, _ := time.LoadLocation("Asia/Kolkata")

    fmt.Println("Time in UTC:", utc)
    fmt.Println("Time in IST:", start.In(ist))

    // Step 3: Simulate a delay (e.g., some operation)
    time.Sleep(2 * time.Second)
    end := time.Now()

    // Step 4: Calculate elapsed duration using monotonic clock
    elapsed := end.Sub(start)
    fmt.Println("Elapsed Duration (using monotonic clock):", elapsed)

    fmt.Println("------------------------------------------------")

    // Step 5: Difference between UTC and IST (timezone offset)
    diff := start.In(ist).Sub(start.UTC())
    fmt.Println("IST - UTC Offset:", diff)

    // Step 6: Demonstrate adding/subtracting time
    added := start.Add(3 * time.Hour)
    subtracted := start.Add(-45 * time.Minute)
    fmt.Println("After adding 3 hours:", added.In(ist))
    fmt.Println("After subtracting 45 minutes:", subtracted.In(ist))

    fmt.Println("------------------------------------------------")

    // Step 7: Comparing times
    if start.Before(end) {
        fmt.Println("Start time is before end time")
    }
    if end.After(start) {
        fmt.Println("End time is after start time")
    }

    fmt.Println("------------------------------------------------")

    // Step 8: List of sample timezone names (for brevity)
    timeZones := []string{"UTC", "Asia/Kolkata", "America/New_York", "Europe/London", "Australia/Sydney"}
    fmt.Println("Available Timezones and Their Current Times:")
    for _, tz := range timeZones {
        loc, _ := time.LoadLocation(tz)
        fmt.Printf("%-20s %v\n", tz, time.Now().In(loc))
    }
}

Output

Current (Local) Time: 2025-11-02 15:30:25.2342345 +0530 IST m=+0.000000001
------------------------------------------------
Time in UTC: 2025-11-02 10:00:25.2342345 +0000 UTC
Time in IST: 2025-11-02 15:30:25.2342345 +0530 IST
Elapsed Duration (using monotonic clock): 2.0012345s
------------------------------------------------
IST - UTC Offset: 5h30m0s
After adding 3 hours: 2025-11-02 18:30:25.2342345 +0530 IST
After subtracting 45 minutes: 2025-11-02 14:45:25.2342345 +0530 IST
------------------------------------------------
Start time is before end time
End time is after start time
------------------------------------------------
Available Timezones and Their Current Times:
UTC                  2025-11-02 10:00:27 +0000 UTC
Asia/Kolkata         2025-11-02 15:30:27 +0530 IST
America/New_York     2025-11-02 05:00:27 -0500 EST
Europe/London        2025-11-02 10:00:27 +0000 GMT
Australia/Sydney     2025-11-02 21:00:27 +1100 AEDT

Playing with Dates and Durations

You can easily add or subtract durations using Add(), Sub(), and AddDate().

func dateOperations() {
    now := time.Now()

    // Add duration
    after2Hours := now.Add(2 * time.Hour)
    after10Days := now.AddDate(0, 0, 10)

    // Subtract duration
    before30Mins := now.Add(-30 * time.Minute)

    fmt.Println("Now:", now)
    fmt.Println("After 2 hours:", after2Hours)
    fmt.Println("After 10 days:", after10Days)
    fmt.Println("30 mins ago:", before30Mins)
}

Comparing Times

Go provides several methods to compare two times:

func compareTimes() {
    t1 := time.Now()
    t2 := t1.Add(5 * time.Minute)

    fmt.Println("t1.Before(t2):", t1.Before(t2))
    fmt.Println("t1.After(t2):", t1.After(t2))
    fmt.Println("t1.Equal(t2):", t1.Equal(t2))
}

Output

t1.Before(t2): true
t1.After(t2): false
t1.Equal(t2): false

Summary

ConceptFunction/ExampleDescription
Get Current Timetime.Now()Returns system time with timezone info
Format Time.Format("2006-01-02 15:04:05")Convert to readable string
Parse String to Timetime.Parse(layout, value)Convert string → time.Time
Add/Subtract.Add(2*time.Hour) / .AddDate(0,1,0)Time arithmetic
Compare Times.Before(), .After(), .Equal()Compare timestamps
Convert Timezone.In(location)Convert to specific timezone
Load Timezonetime.LoadLocation("Asia/Kolkata")Get timezone info

#dateandtime #date #go #golang #development #softwareprogramming

#golang #startups #microservices