Golang time - time zone showing twice - go

On running this code the result should show date time and zone
Surprisingly the result shows time zone twice and am not able to figure out why
package main
import (
"fmt"
"time"
)
func main() {
mytime, _ := time.Parse("02/Jan/2006:15:04:05 -0700", "07/Apr/2017:01:26:05 +0530")
fmt.Println(mytime)
}
Output of this is
2017-04-07 01:26:05 +0530 +0530
So my question is why timezone showing twice ?

The fmt.Println invokes the Time's .String() function that returns the time in the following format:
"2006-01-02 15:04:05.999999999 -0700 MST"
Which as you see contains both the timezone offset and the timezone name.
In your case there is no timezone name known for the time, so it outputs the offset twice.
References:
https://golang.org/pkg/time/#Time.String

Related

Subtracting time to get age

My aim is to calculate the age of the pod by doing the subtraction of "current_time - pod_creation_time" so that I will get the age, I am getting creation time from metadata but it's in the format "2021-07-13 16:34:22 +0530 IST", so when I trying to subtract it from time.Now(), I am getting parsing error like below:
invalid operation: "t2 : " + t2 (mismatched types string and time.Time)
Anyone could please help how to have creation time "2021-07-13 16:34:22 +0530 IST" from metadata in the proper format so that I can do "time.Now - (creation time)"
I tried some workaround like below:
creatTime, err := time.Parse("2006-01-02 15:04:05 -0700 MST",
pod.ObjectMeta.CreationTimestamp.String())
and then subtracted creationTime from Current Time. It works, but I think this is not the right way.
There's a type mismatch as time.Now() return the current time stored in the type time.Time whereas 2021-07-13 16:34:22 +0530 IST is a string. You can perform the required subtraction operation on mismatched types i.e., time.Time and string.
You have to parse the string by specifying the layout. I'd recommend reading the time package's doc.
I've explained every operation in the sample code below; I hope it helps. If you understand this, you can also then look at helper functions like time.Since that can help you write the same program in fewer lines.
package main
import (
"fmt"
"time"
)
func main() {
// K8s timestamp
t := "2021-07-13 16:34:22 +0530 IST"
// Format of K8s timestamp
format := "2006-01-02 15:04:05 -0700 MST" // Mon Jan 2 15:04:05 -0700 MST 2006
// Parse the timestamp so that it's stored in time.Time
cur, err := time.Parse(format, t)
if err != nil {
panic(err)
}
// Current time
now := time.Now()
// As both are of type time.Time, it's subtractable
dur := now.Sub(cur)
// Print duration
fmt.Println(dur)
// Print duration (in seconds)
fmt.Println(dur.Seconds())
}
Also, I'd like you to learn how to write questions on StackOverflow. The formatting of your question is pretty bad. When seeking good solutions; it is the OP's duty to post the question correctly first so that everybody could understand it and then expect answers.
Read: https://stackoverflow.com/help/how-to-ask

IST time zone error in time package go golang

I need to convert any given time zone in RFC3339 format to system time in RFC3339 format.But for few time zone like IST it is throwing the error and the time is still in UTC.
For conversion which function service as better? time.parse or time.In.
I tried to convert the UTC to IST but it failed.
package main
import (
"fmt"
"time"
)
func main() {
//now time
now := time.Now()
fmt.Println("now ", now)
zone, _ := now.Zone()
fmt.Println("zone->", zone)
ll, llerr := time.LoadLocation(zone)
fmt.Println("Load Location", ll, llerr)
// Convert the given time to system based time zone
t, err := time.ParseInLocation(time.RFC3339, "2017-04-25T23:03:00Z", ll)
fmt.Println("t - parsein", t)
fmt.Println("err - parsein", err)
//fmt.Println("t2 - parse", t.In(ll))
}
Error : unknown time zone IST
Expected: Need to convert any time zone to system time zone.
You can't load Indian IST time zone by that name because the name "IST" is ambiguous. It could mean India, Ireland, Israel, etc. time zones, which have different zone offsets and rules. For details, see Why is time.Parse not using the timezone?
If IST is your local zone, the time.Local variable will denote that time zone. If you have a time.Time, you can "switch" to another zone using Time.In(), also Time.Local() returns the time in your local zone.
Of course this code would "break" when ran in another zone. To make sure it behaves the same everywhere, load the Indian IST zone explicitly like this:
loc, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
panic(err)
}
fmt.Println(time.Now())
fmt.Println(time.Now().In(loc))
On the Go Playground it will output:
2009-11-10 23:00:00 +0000 UTC m=+0.000000001
2009-11-11 04:30:00 +0530 IST

How to convert UTC time to unix timestamp

I am looking for an option to convert UTC time string to unix timestamp.
The string variable I have is 02/28/2016 10:03:46 PM and it needs to be converted to a unix timestamp like 1456693426
Any idea how to do that?
First of, the unix timestamp 1456693426 does not have the time 10:03:46 PM but 9:03:46 PM in UTC.
In the time package there is the function Parse with expects a layout to parse the time. The layout is constructed from the reference time Mon Jan 2 15:04:05 -0700 MST 2006. So in your case the layout would be 01/02/2006 3:04:05 PM. After using Parse you get a time.Time struct on which you can call Unix to receive the unix timestamp.
package main
import (
"fmt"
"time"
)
func main() {
layout := "01/02/2006 3:04:05 PM"
t, err := time.Parse(layout, "02/28/2016 9:03:46 PM")
if err != nil {
fmt.Println(err)
}
fmt.Println(t.Unix())
}

How can I extract the value of my current local time offset?

I'm struggling a bit trying to format and display some IBM mainframe TOD clock data. I want to format the data in both GMT and local time (as the default -- otherwise in the zone the user specifies).
For this, I need to get the value of the local time offset from GMT as a signed integer number of seconds.
In zoneinfo.go (which I confess I don't fully understand), I can see
// A zone represents a single time zone such as CEST or CET.
type zone struct {
name string // abbreviated name, "CET"
offset int // seconds east of UTC
isDST bool // is this zone Daylight Savings Time?
}
but this is not, I think, exported, so this code doesn't work:
package main
import ( "time"; "fmt" )
func main() {
l, _ := time.LoadLocation("Local")
fmt.Printf("%v\n", l.zone.offset)
}
Is there a simple way to get this information?
You can use the Zone() method on the time type:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
zone, offset := t.Zone()
fmt.Println(zone, offset)
}
Zone computes the time zone in effect at time t, returning the abbreviated name of the zone (such as "CET") and its offset in seconds east of UTC.
Package time
func (Time) Local
func (t Time) Local() Time
Local returns t with the location set to local time.
func (Time) Zone
func (t Time) Zone() (name string, offset int)
Zone computes the time zone in effect at time t, returning the
abbreviated name of the zone (such as "CET") and its offset in seconds
east of UTC.
type Location
type Location struct {
// contains filtered or unexported fields
}
A Location maps time instants to the zone in use at that time.
Typically, the Location represents the collection of time offsets in
use in a geographical area, such as CEST and CET for central Europe.
var Local *Location = &localLoc
Local represents the system's local time zone.
var UTC *Location = &utcLoc
UTC represents Universal Coordinated Time (UTC).
func (Time) In
func (t Time) In(loc *Location) Time
In returns t with the location information set to loc.
In panics if loc is nil.
For example,
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
// For a time t, offset in seconds east of UTC (GMT)
_, offset := t.Local().Zone()
fmt.Println(offset)
// For a time t, format and display as UTC (GMT) and local times.
fmt.Println(t.In(time.UTC))
fmt.Println(t.In(time.Local))
}
Output:
-18000
2016-01-24 16:48:32.852638798 +0000 UTC
2016-01-24 11:48:32.852638798 -0500 EST
I don't think it makes sense to manually convert time to another TZ. Use time.Time.In function:
package main
import (
"fmt"
"time"
)
func printTime(t time.Time) {
zone, offset := t.Zone()
fmt.Println(t.Format(time.Kitchen), "Zone:", zone, "Offset UTC:", offset)
}
func main() {
printTime(time.Now())
printTime(time.Now().UTC())
loc, _ := time.LoadLocation("America/New_York")
printTime(time.Now().In(loc))
}

why does time.Parse parse the time incorrectly?

I'm trying to parse a string as time with but unfortunately go gets the wrong month (January instead of June)
package main
import "fmt"
import "time"
func main() {
t := "2014-06-23T20:29:39.688+01:00"
tc, _ := time.Parse("2006-01-02T15:04:05.000+01:00", t)
fmt.Printf("t was %v and tc was %v", t, tc)
}
Play
The problem is that your timezone offset is ill-defined in the layout: the reference offset is -0700. You defined yours as +01:00, so the 01 is interpreted as the month and erase the previously defined one. And as your working offset is 01 as well, it is parsed as january.
The following example works for me playground
package main
import "fmt"
import "time"
func main() {
t := "2014-06-23T20:29:39.688+01:00"
tc, _ := time.Parse("2006-01-02T15:04:05.000-07:00", t)
fmt.Printf("t was %v and tc was %v", t, tc)
}
Your layout string is incorrect. The numbers in the layout string have special meanings, and you are using 1 twice: once in the month portion and once in the time zone portion. The time zone in the string you are parsing is 01:00, so you are storing 1 into the month. This explains why the returned month was January (the first month).
A corrected layout string is 2006-01-02T15:04:05.000-07:00. Or, if you're happy with using Z to represent UTC, the time.RFC3339 constant might be appropriate.

Resources