time conversion using time.In() is not accurate

84 Views Asked by At

When I tried to convert time 12:30 UTC into desired timezone ie. Asia/Calcutta (+5:30), which is expected to return 18:00 IST using t.In() function, actually returning 18:23

package main

import (
    "fmt"
    "os"
    "strconv"
    "time"
)

const timeLayout string = "15:04"

func main() {
    location, err := time.LoadLocation("Asia/Calcutta")
    if err != nil {
        fmt.Printf("unable to understand the timezone: %v", err)
        os.Exit(0)
    }

    t, err := time.Parse(timeLayout, "12:30") // 12:30 is in UTC
    if err != nil {
        fmt.Printf("unable to parse the time timezone: %v", err)
        os.Exit(0)
    }

    timeAsPerTimeZone := t.In(location) // expected: 12:30 + 5:30 = 18:00 IST
    fmt.Println(timeAsPerTimeZone.String())

    timing := "Minutes: " + strconv.Itoa(timeAsPerTimeZone.Minute()) + " Hours: " + strconv.Itoa(timeAsPerTimeZone.Hour())
    fmt.Println(timing)

}

Playground Link: https://go.dev/play/p/OdlFYTPfcNM

1

There are 1 best solutions below

1
Mohit Patil On

I found a related github issue time.Format invalid data

Comment from member: #issuecomment-88140297

Timezone depends on the date, according to 2015b version of tzdata:

To make it work as expected we also need to consider the date while parsing the time.

Go Playground: Solution

package main

import (
    "fmt"
    "os"
    "strconv"
    "time"
)

// considered year in the format
const timeLayout string = "2006 15:04"

func main() {
    location, err := time.LoadLocation("Asia/Calcutta")
    if err != nil {
        fmt.Printf("unable to understand the timezone: %v", err)
        os.Exit(0)
    }

    t, err := time.Parse(timeLayout, "2023 12:30") // 12:30 is in UTC
    if err != nil {
        fmt.Printf("unable to parse the time timezone: %v", err)
        os.Exit(0)
    }

    timeAsPerTimeZone := t.In(location) // expected: 12:30 + 5:30 = 18:00 IST
    fmt.Println(timeAsPerTimeZone.String())

    timing := "Minutes: " + strconv.Itoa(timeAsPerTimeZone.Minute()) + " Hours: " + strconv.Itoa(timeAsPerTimeZone.Hour())
    fmt.Println(timing)

}

Another detailed blog around this issue: https://www.sobyte.net/post/2022-01/golang-time/