How can I prevent go's Time.Format() from removing trailing zeros from fractional part? I have following unit tests that fails.
package main
import (
"testing"
"time"
)
func TestTimeFormatting(t *testing.T) {
timestamp := time.Date(2017, 1,2, 3, 4, 5, 600000*1000, time.UTC)
timestamp_string := timestamp.Format("2006-01-02T15:04:05.999-07:00")
expected := "2017-01-02T03:04:05.600+00:00"
if expected != timestamp_string {
t.Errorf("Invalid timestamp formating, expected %v, got %v", expected, timestamp_string)
}
}
Output:
$ go test
--- FAIL: TestTimeFormatting (0.00s)
main_test.go:14: Invalid timestamp formating, expected 2017-01-02T03:04:05.600+00:00, got 2017-01-02T03:04:05.6+00:00
FAIL
exit status 1
FAIL _/home/sasa/Bugs/go-formatter 0.001s
Any idea how to solve this?
Ah, it was there in documentation. One should use 000 instead of 999 if you want to keep zeros.
package main
import (
"testing"
"time"
)
func TestTimeFormatting(t *testing.T) {
timestamp := time.Date(2017, 1,2, 3, 4, 5, 600000*1000, time.UTC)
timestamp_string := timestamp.Format("2006-01-02T15:04:05.000-07:00")
expected := "2017-01-02T03:04:05.600+00:00"
if expected != timestamp_string {
t.Errorf("Invalid timestamp formating, expected %v, got %v", expected, timestamp_string)
}
}
Related
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
It says:
Printf formats according to a format specifier and writes to standard output. It returns the number of bytes written and any write error encountered.
How do I create/test an error and show the error if it is stored in b
when I run the program it shows "nil" since no error, how can i show any error?
a,b :=fmt.Println("Hello, playground")
fmt.Println(a)
fmt.Println(b)
https://golang.org/pkg/fmt/#Println
func Println(a ...interface{}) (n int, err error)
https://play.golang.org/p/8Cjb2Sfunx7
It is unusual to have Println errors, the docs also this. But if you are really interesting in doing a test of it, it works:
package main
import (
"fmt"
"os"
"log"
)
func main() {
const name, age = "Kim", 22
os.Stdout.Close()
_, err := fmt.Println(name, "is", age, "years old.")
log.Fatal(err)
}
In order to artificially trigger an error we are closing the default Stdout file, used by Println. See the os documentation.
package main
import (
"fmt"
"strconv"
)
func main() {
v := "55"
if s, err := strconv.Atoi(v); err == nil {
fmt.Println(string(v)) // 55
fmt.Println(s) // 55
fmt.Println(string(s)) // 7
}
}
https://play.golang.org/p/8V1npFiC9iH
s is an integer with the value 55, which is the ASCII (and UTF-8) encoding of the character "7". That's what's printed from the last statement.
When you call s, err := strconv.Atoi("55") you turn s into an integer. When you do string(s) afterwards, you're asking for a string that contains the character represented by that integer.
That character happens to be '7'. Try v := "65" and you'll get 'A', etc.
I have some code that needs to be able to parse a string containing a 64-bit value into an int64. For example, ff11223344556677 is valid, but a downstream system wants that in an int64.
strconv.ParseInt("ff11223344556677", 16, 64) gives a range error - it only likes to parse positive integers. Is there a way to go about putting this value into an int64 even though it is going to be negative?
For example,
package main
import (
"fmt"
"strconv"
)
func main() {
u, err := strconv.ParseUint("ff11223344556677", 16, 64)
fmt.Printf("%x %v\n", u, err)
i := int64(u)
fmt.Println(i)
}
Output:
ff11223344556677 <nil>
-67234915848722825
How can I calculate the number of days between two dates? In the code below I should get the number of hours, which means that I should only need to divide by 24. However, the result I get is something like -44929.000000. I'm only looking a day or two back so I would expect 24 or 48 hours.
package main
import (
"fmt"
"time"
)
func main() {
timeFormat := "2006-01-02"
t, _ := time.Parse(timeFormat, "2014-12-28")
fmt.Println(t)
// duration := time.Since(t)
duration := time.Now().Sub(t)
fmt.Printf("%f", duration.Hours())
}
Here's the executable Go code: http://play.golang.org/p/1MV6wnLVKh
Your program seems to work as intended. I'm getting 45.55 hours. Have you tried to run it locally?
Playground time is fixed, time.Now() will give you 2009-11-10 23:00:00 +0000 UTC always.
package main
import (
"fmt"
"time"
)
func main() {
date := time.Now()
fmt.Println(date)
format := "2006-01-02 15:04:05"
then,_ := time.Parse(format, "2007-09-18 11:58:06")
fmt.Println(then)
diff := date.Sub(then)
//func Since(t Time) Duration
//Since returns the time elapsed since t.
//It is shorthand for time.Now().Sub(t).
fmt.Println(diff.Hours())// number of Hours
fmt.Println(diff.Nanoseconds())// number of Nanoseconds
fmt.Println(diff.Minutes())// number of Minutes
fmt.Println(diff.Seconds())// number of Seconds
fmt.Println(int(diff.Hours()/24))// number of days
}
Here is the running code https://play.golang.org/p/Vbhh1cBKnh
the below code gives the list of all the days along with the number of days between the from date and to date:
you can click on the link for the code in
Go PlayGround:https://play.golang.org/p/MBThBpTqjdz
to := time.Now()
from := to.AddDate(0, -1, 0)
fmt.Println("toDate", to)
fmt.Println("fromDate", from)
days := to.Sub(from) / (24 * time.Hour)
fmt.Println("days", int(days))
noofdays := int(days)
for i := 0; i <= noofdays; i++ {
fmt.Println(from.AddDate(0, 0, i))
}
One caveat to be mindful of when using this technique of timeOne.Sub(timeTwo).Hours() / 24 is that daylights savings can cause a day to contain only 23 hours, throwing this calculation off slightly.
Happy programmer's day
package main
import (
"fmt"
"time"
)
func main() {
loc, _ := time.LoadLocation("UTC")
now := time.Now().In(loc)
firstDate := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, loc)
diff := now.Sub(firstDate)
fmt.Printf("The difference between %s and today %s es %d days\n", now.String(), firstDate.String(), int(diff.Hours()/24)+1)
// Just a joke
if ( int(diff.Hours()/24)+1 == 256 ) {
fmt.Printf("¡Happy programmer's day!")
} else {
fmt.Printf("On my computer it works...!?")
}
}