I have logs with timestamps that look like "2020-05-08 22:02:00,845". They have comma separated milliseconds, which is what is giving time.Parse issues. I can't seem to figure out how to make time.Parse happy with it. Here is sample code that produces the error in go version go1.13.4 darwin/amd64 (and in the playground linked below);
package main
import (
"time"
)
func main() {
ts := "2020-05-08 22:02:00,845"
_, err := time.Parse("2006-01-02 15:04:05,000", ts)
print(err.Error())
}
Running that code produces this error
parsing time "2020-05-08 22:02:00,845" as "2006-01-02 15:04:05,000": cannot parse "845" as ",000"
Here a link to the code in the go playground
So what would a format look like to parse this? Thanks for your help.
It's a bug already filed here
The behaviour is documented as such: "A fractional second is represented by adding a period and zeros to the end of the seconds section of layout string, as in "15:04:05.000" to format a time stamp with millisecond precision.
Workaround for that would be replacing "," with "."
package main
import (
"time"
"fmt"
"strings"
)
func main() {
ts := "2020-05-08 22:02:00,845"
ts = strings.Replace(ts, ",", ".", -1)
d, err := time.Parse("2006-01-02 15:04:05.000", ts)
if err != nil{
print(err.Error())
}
fmt.Println(d)
}
here is the Playground
Related
I wish to convert a string timestamp (for which no timezone was provided) to a time with timezone of UTC -08:00.
Code:
package main
import (
"fmt"
"log"
"time"
)
func main() {
layout := "1/02/2006 15:04:05 -700"
cellContent := "7/28/2021 22:45:34"
t, err := time.Parse(layout, fmt.Sprintf("%s %s", cellContent, "-800"))
if err == nil {
fmt.Println(t.String())
} else {
log.Fatal(err)
}
}
This fails with message:
parsing time "7/28/2021 22:45:34 -800" as "1/02/2006 15:04:05 -700":
cannot parse "800" as " -700"
I believe I have an error in my layout string, but haven't been able to identify it. What am I doing wrong?
Go Playground
See comment from #Adrian, who nailed it.
The layout timezone must have a leading zero. Thanks!
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)
My date looks like this
2019-03-29T09:32:52Z
Please help me parse it using Go's standard time package
Nevermind, I just had the wrong layout
package main
import (
"fmt"
"time"
)
func main() {
layout := "2006-01-02T15:04:05Z07:00"
t, err := time.Parse(layout, "2019-03-29T09:32:52Z")
fmt.Println(t, err)
}
I'm new to Go and I was creating a little console script. You can check my code here:
package main
import (
"bufio"
"fmt"
"os"
"time"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("Calculate")
fmt.Print("Hours and minutes: ")
start, _, _ := reader.ReadLine()
begin, err := time.Parse("2016-12-25 00:00:00", "2016-12-25 "+string(start)+":00")
if err != nil {
fmt.Println(err)
}
fmt.Println(begin)
}
I've seen a related question but I couldn't understand why.
This is the error I'm getting after running my code:
parsing time "2016-12-25 22:40:00": month out of range
0001-01-01 00:00:00 +0000 UTC
Any ideas on what am I doing wrong?
Thanks
You're using the wrong reference time in the layout parameter of time.Parse which should be Jan 2, 2006 at 3:04pm (MST)
Change your begin line to the following and it will work:
begin, err := time.Parse("2006-01-02 15:04:05", "2016-12-25 "+string(start)+":00")
func Parse
To avoid having to remember the special date, I usually wrap the logic in a
function:
package main
import (
"fmt"
"time"
)
func parseDate(value string) (time.Time, error) {
layout := time.RFC3339[:len(value)]
return time.Parse(layout, value)
}
func main() {
start := "15:04"
d, e := parseDate("2016-12-25T" + start)
if e != nil {
panic(e)
}
fmt.Println(d)
}
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