How to parse this date 2018-10-22T2250? - go

How to parse this strange datetime 2018-10-22T2250 in golang?
I couldn't find date layout

You can create your own custom format. In production, you should also handle the error.
package main
import (
"fmt"
"time"
)
func main() {
timeString := "2018-10-22T2250"
timeFormat := "2006-01-02T1504"
t, _ := time.Parse(timeFormat, timeString)
fmt.Println(t)
}
Playground link
This returns the time in UTC. You may need to adjust to another timezone, depending on your source.
//init the location
loc, _ := time.LoadLocation("Asia/Shanghai")
//localize the time
localTime := t.In(loc)

Related

golang timestamp in RFC3339 format

how do we convert time.now() in time.Time( RFC3339) format?
Eg:
var t time.Time
timeNow= time.Now()
I want to assign timeNow to t
Golang has support for various time formats.
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
r := t.Format(time.RFC3339)
fmt.Println("time.Now() ", t)
fmt.Println("RFC3339 ", r)
}

How to set a timezone to an existing timestamp without reinterpreting it?

I'm parsing timestamps sent by users. The timestamps are local to a location but the source string doesn't specify it. Server-side I'm looking up the timezone of the location and need to shift the time into that timezone, without changing its display value.
I know I can do this to give me the equivalent time at a different location:
package main
import (
"fmt"
"time"
)
func main() {
myTime := time.Now()
fmt.Println(myTime.Format(time.RFC3339))
loc, err := time.LoadLocation("America/New_York")
if err != nil {
panic(err)
}
fmt.Println(myTime.In(loc).Format(time.RFC3339))
}
This just prints:
2009-11-10T23:00:00Z
2009-11-10T18:00:00-05:00
Which isn't what I want.
I'm trying to find a way of setting the timezone to e.g. America/New_York, so I should get e.g. 2009-11-10T23:00:00-05:00, which is the original local time, but with the New York offset applied.
How can I do this in Go?
The confusion comes from the fact that the API that intuitively comes to mind In simply interprets the same point in time as if it were in a different time zone. So when you print it, the display isn't what you want.
To set the time zone to a timestamp while keeping the same display value you can simply construct the new timestamp with time.Date with the same values as the original timestamp and the new location:
t := time.Date(myTime.Year(), myTime.Month(), myTime.Day(), myTime.Hour(), myTime.Minute(), myTime.Second(), myTime.Nanosecond(), loc)
// 2009-11-10T23:00:00-05:00 in the playground
Another option is to set the time instance to the new time zone, then use Zone() to get the offset, and then subtract its value in seconds from the localized time.
package main
import (
"fmt"
"time"
)
func main() {
myTime := time.Now()
fmt.Println(myTime.Format(time.RFC3339))
loc, err := time.LoadLocation("America/New_York")
if err != nil {
panic(err)
}
locTime := myTime.In(loc)
_, zoneOffset := locTime.Zone()
inZoneTime := locTime.Add(-time.Duration(zoneOffset) * time.Second)
// handle DST transitions
if inZoneTime.IsDST() {
inZoneTime = inZoneTime.Add(1*time.Hour)
}
fmt.Println(inZoneTime.Format(time.RFC3339))
// 2009-11-10T23:00:00-05:00
}
To test the DST transition in your local machine today (assuming you are in a non-DST country, as I am) you can change the location to a place where DST is active, e.g. Australia/Canberra.
With an input of time.Now() without DST into Australia/Canberra, the above program prints the following:
2021-11-12T13:27:33+01:00
is DST: true
2021-11-12T13:27:33+11:00
Playground: https://play.golang.org/p/5qy2tOcIMwn

Why these two time.Time instances are same for UTC and different for another location?

I'm expecting these two time.Time instances are the same. But, I'm not sure why I got the compare result is false.
package main
import (
"fmt"
"time"
)
func main() {
t := int64(1497029400000)
locYangon, _ := time.LoadLocation("Asia/Yangon")
dt := fromEpoch(t).In(locYangon)
locYangon2, _ := time.LoadLocation("Asia/Yangon")
dt2 := fromEpoch(t).In(locYangon2)
fmt.Println(dt2 == dt)
}
func fromEpoch(jsDate int64) time.Time {
return time.Unix(0, jsDate*int64(time.Millisecond))
}
Playground
If I change "Asia/Yangon" to "UTC", they are the same.
package main
import (
"fmt"
"time"
)
func main() {
t := int64(1497029400000)
locYangon, _ := time.LoadLocation("UTC")
dt := fromEpoch(t).In(locYangon)
locYangon2, _ := time.LoadLocation("UTC")
dt2 := fromEpoch(t).In(locYangon2)
fmt.Println(dt2 == dt)
}
func fromEpoch(jsDate int64) time.Time {
return time.Unix(0, jsDate*int64(time.Millisecond))
}
Playground
Note: I'm aware of Equal method (in fact, I fixed with Equal method.) But after more testing, I found some interesting case which is "UTC" location vs "Asia/Yangon" location. I'm expecting either both equal or both not equal.
Update: Add another code snippet with "UTC".
Update2: Update title to be more precise (I hope it will help to avoid duplication)
LoadLocation seems to return a pointer to a new value every time.
Anyway, the good way to compare dates is Equal:
fmt.Println(dt2.Equal(dt))
Playground: https://play.golang.org/p/9GW-LSF0wg.

Go printing date to console

I'm trying to pint the month, day, and year, separately to the console.
I need to be able to access each section of the date individually. I can get the whole thing using time.now() from the "time" package but I'm stuck after that.
Can anyone show me where I am going wrong please?
You're actually pretty close :) Then return value from time.Now() is a Time type, and looking at the package docs here will show you some of the methods you can call (for a quicker overview, go here and look under type Time). To get each of the attributes you mention above, you can do this:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Println(t.Month())
fmt.Println(t.Day())
fmt.Println(t.Year())
}
If you are interested in printing the Month as an integer, you can use the Printf function:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Printf("%d\n", t.Month())
}
Day, Month and Year can be extracted from a time.Time type with the Date() method. It will return ints for both day and year, and a time.Month for the month. You can also extract the Hour, Minute and Second values with the Clock() method, which returns ints for all results.
For example:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
y, mon, d := t.Date()
h, m, s := t.Clock()
fmt.Println("Year: ", y)
fmt.Println("Month: ", mon)
fmt.Println("Day: ", d)
fmt.Println("Hour: ", h)
fmt.Println("Minute: ", m)
fmt.Println("Second: ", s)
}
Please remember that the Month variable (mon) is returned as a time.Month, and not as a string, or an int. You can still print it with fmt.Print() as it has a String() method.
Playground
You can just parse the string to get year, month, & day.
package main
import (
"fmt"
"strings"
)
func main() {
currTime := time.Now()
date := strings.Split(currTime.String(), " ")[0]
splits := strings.Split(date, "-")
year := splits[0]
month := splits[1]
day := splits[2]
fmt.Printf("%s-%s-%s\n", year, month, day)
}

How to get last-accessed date and time of file in Go?

Does anyone know how to check for a file access date and time? The function returns the modified date and time and I need something that compares the accessed date time to the current date and time.
You can use os.Stat to get a FileInfo struct which also contains the last access time (as well as the last modified and the last status change time).
info, err := os.Stat("example.txt")
if err != nil {
// TODO: handle errors (e.g. file not found)
}
// info.Atime_ns now contains the last access time
// (in nanoseconds since the unix epoch)
After that, you can use time.Nanoseconds to get the current time (also in nanoseconds since the unix epoch, January 1, 1970 00:00:00 UTC). To get the duration in nanoseconds, just subtract those two values:
duration := time.Nanoseconds() - info.Atime_ns
By casting os.FileInfo to *syscall.Stat_t:
package main
import ( "fmt"; "log"; "os"; "syscall"; "time" )
func main() {
for _, arg := range os.Args[1:] {
fileinfo, err := os.Stat(arg)
if err != nil {
log.Fatal(err)
}
atime := fileinfo.Sys().(*syscall.Stat_t).Atim
fmt.Println(time.Unix(atime.Sec, atime.Nsec))
}
}
Alternatively, after the Stat you can also do
statinfo.ModTime()
Also you can use Format() on it, should you need it eg for a webserver
see https://gist.github.com/alexisrobert/982674
For windows
syscall.Win32FileAttributeData
info, _ := os.Stat("test.txt")
fileTime := info.Sys().(*syscall.Win32FileAttributeData).LastAccessTime
aTime := time.Unix(0, fileTime.Nanoseconds())
Example
package main
import (
"fmt"
"log"
"os"
"syscall"
"time"
)
func main() {
info, _ := os.Stat("./test.txt")
fileTime := info.Sys().(*syscall.Win32FileAttributeData).LastAccessTime
// _ = info.Sys().(*syscall.Win32FileAttributeData).CreationTime
// _ = info.Sys().(*syscall.Win32FileAttributeData).LastWriteTime
fileAccessTime := time.Unix(0, fileTime.Nanoseconds())
// Compare
// t2, _ := time.Parse("2006/01/02 15:04:05 -07:00:00", "2023/02/08 13:18:00 +08:00:00")
now := time.Now()
log.Println(fileAccessTime)
log.Println(now.Add(-20 * time.Minute))
if fileAccessTime.After(now.Add(-20 * time.Minute)) {
fmt.Println("You accessed this file 20 minutes ago.")
}
}
Linux
see this answer

Resources