How to add 1 sec to the date in golang? - go

How to add 1 sec to the date in golang ? I have:
t := time.Now().Format("2006/02/01 03:04:05")
and want something like below but so far getting mismatched types string and time.Duration error
t1, t2, t3 = t + 1*time.Second, t+3*time.Second, t+2*time.Second

func (t Time) Add(d Duration) Time
https://golang.org/pkg/time/#Time.Add

You are asigning a string to t (the result of calling Format) instead of a Time (the result of calling Now). Here's an working example:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Println(t.Format(time.RFC3339))
t = t.Add(time.Second)
fmt.Println(t.Format(time.RFC3339))
}
// prints
// 2017-01-21T16:51:31-05:00
// 2017-01-21T16:51:32-05:00

Related

Convert timestamp as string [duplicate]

This question already has answers here:
Convert time.Time to string
(6 answers)
Closed 2 years ago.
I want to get a timestamp as string. If I use string conversion I got no error but the output is not readable.
Later, I want us it as a part of a filename.
It looks like a question mark for e.g. �
I found some examples like this: https://play.golang.org/p/bq2h3h0YKp
not solves completely me problem. thanks
now := time.Now() // current local time
sec := now.Unix() // number of seconds since January 1, 1970 UTC
fmt.Println(string(sec))
How could I get the timestamp as string?
Something like this works for me
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
now := time.Now()
unix := now.Unix()
fmt.Println(strconv.FormatInt(unix, 10))
}
Here are two examples of how you can convert a unix timestamp to a string.
The first example (s1) uses the strconv package and its function FormatInt. The second example (s2) uses the fmt package (documentation) and its function Sprintf.
Personally, I like the Sprintf option more from an aesthetic point of view. I did not check the performance yet.
package main
import "fmt"
import "time"
import "strconv"
func main() {
t := time.Now().Unix() // t is of type int64
// use strconv and FormatInt with base 10 to convert the int64 to string
s1 := strconv.FormatInt(t, 10)
fmt.Println(s1)
// Use Sprintf to create a string with format:
s2 := fmt.Sprintf("%d", t)
fmt.Println(s2)
}
Golang Playground: https://play.golang.org/p/jk_xHYK_5Vu

Easy way to receive a string from day from time.Now()

I'm trying to get the day as a string from a time.Now() instance.
now := time.Now() // .String() would give me the entire date as a string which I don't need
day := now.Day()) // is what I want but as a String.
So string(day) tells me "can not convert day to string".
For me now.Day().String() would be nice but there is no such method...
I could now try to take time.Now().String() and manipulate until the day is left over. But there should be a easier way to do it...
Use strconv to convert int to string
strconv.Itoa(day)
You can import and use strconv as KibGzr mentioned. Just to give a complete example:
package main
import (
"fmt"
"time"
"strconv"
)
func main() {
now := time.Now()
day := now.Day()
fmt.Printf("%T\n",(day))
fmt.Println(strconv.Itoa(day))
dayString := strconv.Itoa(day)
fmt.Printf("%T",(dayString))
}
https://play.golang.org/p/Mqs24FJhCoi

Why time.Time not equal after bson.Marshal and bson.Unmarshal?

Why does it output false? I was expecting true...
package main
import (
"fmt"
"time"
"gopkg.in/mgo.v2/bson"
)
type S struct {
T time.Time
}
func main() {
t := S{time.Now()}
bytes, _ := bson.Marshal(t)
var dt S
bson.Unmarshal(bytes, &dt)
fmt.Println(dt.T.Equal(t.T))
}
go run the above will output false, why Marshal/Unmarshal doesn't preserve the original value?
Bson stores time with lower precision than a time.Time, the value returned from Bson may not equal the value you stored.
You need to use bson.Now():
package main
import (
"fmt"
"gopkg.in/mgo.v2/bson"
"time"
)
type S struct {
T time.Time
}
func main() {
t := S{bson.Now()}
bytes, _ := bson.Marshal(t)
var dt S
bson.Unmarshal(bytes, &dt)
fmt.Println(dt.T)
fmt.Println(t.T)
fmt.Println(dt.T.Equal(t.T))
}
Output:
$> go run main.go
2018-09-08 10:48:42.45 +0300 MSK
2018-09-08 10:48:42.45 +0300 MSK
true

Generating Random Timestamps in Go

I'd like to generate a random timestamp within the last relative 3 years and have it be printed out with this format: %d/%b/%Y:%H:%M:%S %z
Here is what I have right now:
package main
import (
"strconv"
"time"
"math/rand"
"fmt"
)
func randomTimestamp() time.Time {
randomTime := rand.Int63n(time.Now().Unix() - 94608000) + 94608000
randomNow, err := time.Parse("10/Oct/2000:13:55:36 -0700", strconv.FormatInt(randomTime, 10))
if err != nil {
panic(err)
}
return randomNow
}
func main() {
fmt.Println(randomTimestamp().String())
}
This always throws: panic: parsing time "...": month out of range. How can I generate a random timestamp for a given range, then convert it to the string format I want with the standard library?
Don't use time.Parse. You have a Unix time, not a time string. Use the Unix() method instead. https://golang.org/pkg/time/#Unix. You can also choose a minimum time value, say 1/1/1900 and add a random Duration of seconds to the time using the Add method on Time and passing a Duration you made with the Ticks() method. https://golang.org/pkg/time/#Duration
Here's a Go Playground link. Just remember that the Go Playground doesn't support actual randomness. https://play.golang.org/p/qYTpnbml_N
package main
import (
"time"
"math/rand"
"fmt"
)
func randomTimestamp() time.Time {
randomTime := rand.Int63n(time.Now().Unix() - 94608000) + 94608000
randomNow := time.Unix(randomTime, 0)
return randomNow
}
func main() {
fmt.Println(randomTimestamp().String())
}

go mismatched types uint64 and int32

I don't see what I'm doing wrong here with this error, both are of type syscall.Timeval Usec
Thanks
package common
import (
"syscall"
)
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
for now.Sec > oldTime.Sec {
result += 1000000
now.Sec--
}
return result + (now.Usec - oldTime.Usec)
}
./common.go:15: invalid operation: result + (now.Usec - oldTime.Usec) (mismatched types uint64 and int32)
Use a signed return value (int64), like Timeval.Sec and Timeval.Usec. Use TimevalToNsec for portability across operating systems. For example, Timeval fields may be int32 or int64. For a correct result, use,
package main
import (
"fmt"
"syscall"
"time"
)
func getUsecSince(old syscall.Timeval) int64 {
var now syscall.Timeval
syscall.Gettimeofday(&now)
nsecs := syscall.TimevalToNsec(now) - syscall.TimevalToNsec(old)
return nsecs / int64(time.Microsecond)
}
func main() {
old := syscall.Timeval{}
syscall.Gettimeofday(&old)
time.Sleep(2*time.Second + 42*time.Microsecond)
fmt.Println(getUsecSince(old))
}
Output:
2000377
The simplest solution to this is:
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
// Automatically ignore cases like 12.5 - 11.8
result = uint64((now.Sec - oldTime.Sec) * 1000000 + int64(now.Usec - oldTime.Usec))
return result
}
By converting to the smallest unit you can ignore the boundary conditions easily as long as there is no overflow during conversion.
Note that if you purposely test the above by using an oldTime in the future, the function will fail. You will need to do a check (with both times converted to Usec) if you want to cover such cases.
Timeval.Usec is defined as int32. Maybe result should be also int32? Alternatively if you want to use uint64 you can cast it by uint64(now.Usec - oldTime.Usec).
result is uint64.
The other operands are int32
Running this
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
typeUsec := reflect.TypeOf(now.Usec)
fmt.Printf("type %s, value %d \n", typeUsec, now.Usec)
will print
type int32, value 238376
Strangely, the go documents have the following
type Timeval struct {
Sec int64
Usec int64
}

Resources