Truncate a time duration by minutes - go

I want to subtract 30 minutes from orderDeliveryStartTime by using the Truncate function of the time library in Go. But it's subtracting 30 seconds instead. How can I subtract exactly 30 minutes from a time.Time?
package main
import (
"fmt"
"time"
)
func main() {
var pickingTimeConfig int
pickingTimeConfig = 30
layoutTime := "2006-01-02 15:04:05"
pickingTime := time.Duration(pickingTimeConfig) * time.Minute
fmt.Println(pickingTime.Nanoseconds())
vcmTimeLocation := time.FixedZone("UTC+7", 25200)
orderDeliveryStartTime := time.Date(2019, 4, 11, 13, 0, 30, 0, vcmTimeLocation)
fmt.Println(orderDeliveryStartTime.Format(layoutTime))
fmt.Println(orderDeliveryStartTime.Truncate(pickingTime).Format(layoutTime))
}
Actual Result:
1800000000000
2019-04-11 13:00:30
2019-04-11 13:00:00
Expected Result:
1800000000000
2019-04-11 13:00:30
2019-04-11 12:30:30

Simply use the Time.Add() method, passing -30 * time.Minute:
t2 := orderDeliveryStartTime.Add(-30 * time.Minute)
fmt.Println(t2.Format(layoutTime))
Outputs (try it on the Go Playground):
2019-04-11 13:00:30
2019-04-11 12:30:30

Related

How to update hour, min, sec in golang time?

Ex: How can I update hour in t time?
fmt.Println(t)
//=> 2006-01-02 15:04:05 +0000 UTC
Expect to get: 2006-01-02 00:00:00 +0000 UTC
Edited: similar to: time.Time Round to Day
Use:
t1 := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, t.Nanosecond(), t.Location())
Ref: https://golang.org/pkg/time/#Date
This seems to do it:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now().UTC()
t = t.Truncate(24 * time.Hour)
fmt.Println(t)
}
https://golang.org/pkg/time#Time.Truncate

In golang, Time.Format() removes trailing zeros from fractional part

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)
}
}

How i can to convert RFC3339 to UNIX in golang

I want to show some RFC3339 time as seconds. I found how to parse times string, but it not that
t, _ := time.Parse(time.RFC3339, "2012-11-01T22:08:41+00:00")
For example,
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse(time.RFC3339, "2012-11-01T22:08:41+00:00")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(t)
// Unix returns t as a Unix time,
// the number of seconds elapsed since January 1, 1970 UTC.
fmt.Println(t.Unix())
}
Playground: https://play.golang.org/p/LG6G4lMIWt
Output:
2012-11-01 22:08:41 +0000 UTC
1351807721

Is there a way to invoke a cron job on a certain date/time?

I am using what seems to be the most popular cron package by robfig: https://godoc.org/github.com/robfig/cron. Currently I know that I can invoke an hourly cron job with:
c.AddFunc("#hourly", func() { fmt.Println("Every hour") })
However I wonder if it is possible to set it so that it only starts after (for example) Sep 1st, 2017? If it's not possible using that package, how else can I achieve that? Thanks.
If you want a custom scheduling, implements your own scheduler, then register the job using Cron.Schedule. Below is an example implementation of repeating a CRON job after a certain time:
package main
import (
"fmt"
"time"
"github.com/robfig/cron"
)
type MyScheduler struct {
At time.Time
Every time.Duration
}
func (s *MyScheduler) Next(t time.Time) time.Time {
if t.After(s.At) {
return t.Add(s.Every)
}
return s.At
}
func main() {
c := cron.New()
//Execute every 2 seconds after a certain time (5 second from now)
now := time.Now()
at := now.Add(5 * time.Second) //In your case, this should be: Sep 1st, 2017
s := &MyScheduler{at, 2 * time.Second}
c.Schedule(s, cron.FuncJob(
func() {
cur := time.Now()
fmt.Printf(" [%v] CRON job executed after %v\n", cur, cur.Sub(now))
}))
fmt.Printf("Now: %v\n", now)
c.Start()
time.Sleep(10 * time.Second)
c.Stop()
}
Adding to #Adrians Comments,
The package robfig/cron supports cron expression format. To have the cron run 30 mins past every hour viz on 9:30 am,10:30 am, 11:30 am. You could use
c.AddFunc("0 30 * * * *", func() {})
an implementation to have the cron run after Sep 1, 2017
package main
import (
"fmt"
"time"
"github.com/robfig/cron"
)
func main() {
// time set to Sep 1, 2017 00:00 Hours UTC
t := time.Date(2017, time.September, 1, 0, 0, 0, 0, time.UTC)
c := cron.New()
//using cron expression format to have the function run every hour on the half hour
c.AddFunc("0 30 * * * *", func() {
if time.Now.After(t){
fmt.Println("yay")
//insert logic block
}
})
}
Note: The cron expression format used by this package is different from the standard unix cron format. The expression format used by this package allows for second precision unlike unix cron format.

Calculate number of days between two dates?

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...!?")
}
}

Resources