How I will make a perfect time Reduction in golang? - go

I'm making a cron job for the booking charge automatic. The admin set the automatic charge after 2 hour of booking completion then I Get all the booking completed before 2 hours from the current time and charge them automatic. But the problem arise in the end of the day is that current_date= 10/10/2018 current_time= 1:00AM and automatic_charge_hours= 2 (hours) means it will get all the bookings which are completed 2 hours before the current_time and current_date. In 24hour format it will get all the bookings of the 23 hours(11:00PM of date 09/10/2018) of the previous date . But in my condition it will turn it into zero below is my condition:-
package main
import (
"fmt"
"time"
"strings"
)
func main() {
timeZone, _ := time.LoadLocation("America/New_York")
currDate := time.Now().In(timeZone).Format("2006-01-02 00:00:00 -0000")
onlyDate := strings.Split(currDate, " ")
hours, _ := 1, 0
if hours-int(2) < 0 {
hours = 0
} else {
hours = hours - int(2)
}
fmt.Println(hours, onlyDate[0])
}
playground link https://play.golang.org/p/w7LIoTp9xN0
How will I change it. Any suggestions please.

if hours-int(2) < 0 {
hours = 0
} else {
hours = hours - int(2)
}
Explicitly sets hours to zero when hours are negative.
If you change hours = 0 to hours = 24 + (hours-int(2)) it returns 23.
See https://play.golang.org/p/FyXIn5gjIXk
Anyhow, Instead of manipulating hours by hand, you should use time functions.
Update: Use time functions:
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse("01.02.2006 03:04:00", "10.10.2018 01:00:00")
if err != nil {
panic(err)
}
then := t.Add(time.Duration( -2 ) * time.Hour)
fmt.Printf("%v\n", then)
}
https://play.golang.org/p/0r6q7Vvai2h

You only have to change the condition little bit for the hours like below:-
func main() {
timeZone, _ := time.LoadLocation("America/New_York")
currDate := time.Now().In(timeZone).Format("2006-01-02 00:00:00 -0000")
onlyDate := strings.Split(currDate, " ")
hours, _ := 1, 0
hours = hours-int(2)
fmt.Println(hours)
if hours <= -1 {
hours = 24 + hours
currDate = time.Now().In(timeZone).AddDate(0, 0, -1).Format("2006-01-02 00:00:00 -0000")
fmt.Println(currDate)
}
fmt.Println(hours, onlyDate[0])
}
AddDate() is the function in the time package you can see in the https://golang.org/pkg/time/

Related

How can I count mouse clicks in Go?

I'm trying to write a program which counts the number of mouse left and right buttons presses every 30 seconds since start in order to get statistics of mouse activity. But it doesn't count single rightclick, it counts rightclick as leftclick + rightclick combination. Also it doesn't output results after 30 seconds even if there was no clicks at all, instead it waits mouse button pressing after 30 seconds passed. I'm stumped. What should I change to fix this? Here is my code.
package main
import (
"fmt"
"github.com/go-vgo/robotgo"
"time"
)
const t = 30
func leftclickcounter () (int) {
nowTime := time.Now().Unix()
nowTime = time.Now().Unix()
NumOfLeftClick := 0
for {
lmb := robotgo.AddMouse("left" )
if lmb {
fmt.Println("leftclick")
NumOfLeftClick++
}
if time.Now().Unix()-nowTime >= t {
return NumOfLeftClick
}
}
}
func rightclickcounter () (int) {
nowTime := time.Now().Unix()
nowTime = time.Now().Unix()
NumOfRightClick := 0
for {
rmb := robotgo.AddMouse("right")
if rmb {
fmt.Println("rightclick")
NumOfRightClick++
}
if time.Now().Unix() - nowTime >= t {
return NumOfRightClick
}
}
}
func main() {
for {
lc := leftclickcounter()
rc := rightclickcounter()
fmt.Println("Number of leftclicks:", lc)
fmt.Println("Number of rightclicks:", rc)
}
var input string
fmt.Scanln(&input)
}
Besides the elapsed time mentioned by Flimzy
You are running an infinite loop within an infinite loop, rightclickcounter() gets never executed. At least not in your timeframe.
Currently, you are starting lc counter -> wait 30 secs -> start rc counter -> wait 30 secs
for {
lc := leftclickcounter()
rc := rightclickcounter()
fmt.Println("Number of leftclicks:", lc)
fmt.Println("Number of rightclicks:", rc)
}
take a look at https://gobyexample.com/goroutines and https://tour.golang.org/concurrency/2

How to write a function to check if current time is inside time window

I am trying to find a way to check if the current time is inside a time window.
The inputs are:
upgradeDay []string - a slice of days (for instance ["Sunday", "Tuesday"])
upgradetime string - hour:minute (for instance "22:04")
upgradeDuration int64 - amount of time, from the upgradetime at which the time window is valid. it can be up to 12 hours.
Full example:
upgradeDay = ["Sunday", Tuesday"] , upgradetime = "10:00", upgradeDuration = 2 -> the time windows is at every Sunday and Tuesday, from 10:00 to 12:00 o'clock.
I tried to write the following function, but it's not working in transition between days/months/years:
func isInsideTimeWindow(upgradeDay []string, upgradeTime string, upgradeDuration int64) bool {
now := time.Now()
ut := strings.Split(upgradeTime, ":")
hour, _ := strconv.Atoi(ut[0])
min, _ := strconv.Atoi(ut[1])
// !! not working when now it's Monday 00:01 and got: upgradeDay = ["Sunday"], upgradeTime = 23:59, upgradeDuration = 2
twStart := time.Date(now.Year(), now.Month(), now.Day(), hour, min, 0, 0, now.Location())
twEnd := twStart.Add(time.Hour * time.Duration(upgradeDuration))
if !(now.After(twStart) && now.Before(twEnd)) {
return false
}
wd := now.Weekday().String()
for i := range upgradeDay {
if upgradeDay[i] == wd {
return true
}
}
return false
}
Does someone got an idea on how to solve that in Go?
Here is one approach to the problem:
package main
import "time"
type window struct { time.Time }
func (w window) isDay(s string) bool {
return w.Weekday().String() == s
}
func (w window) isHourRange(begin, end int) bool {
return w.Hour() >= begin && w.Hour() <= end
}
func main() {
w := window{
time.Now(),
}
{
b := w.isDay("Friday")
println(b)
}
{
b := w.isHourRange(20, 23)
println(b)
}
}
This assume only one day is valid, so you would need to modify this to handle
multiple days. This should get you started though.
There is a lot of complexity in times. For instance:
What if an upgrade day is "Søndag" (Danish) instead of "Sunday"?
Should we work in local time, or UTC? If local, whose location counts? If the server is in London and I am in San Francisco, do we use the server's time, or my time?
If the upgrade interval includes 2 AM, does that count 2 AM PDT and then 2 AM PST as well? These times are one hour apart where I live. If the interval starts at 2 AM and ends at 2:59:59, that time does not exist on one day of the year in many areas with one hour DST shift.
If you get to ignore all these complexities—internationalization (i18n), localization (l10n), DST, and so on—there's still a bit of a problem with the fact that someone can set the date and time, or the upgrade itself might take some time, but usually we get to ignore these too.
Note that Go's time.Now() returns local time—but, whose location? As we have not yet answered the whose time zone to use question yet, we might want to avoid worrying about this. Given the rest of your input constraints, let's write a function to determine if a supplied time meets the input constraints, rather than if time.Now() does so. The caller can then provide either a UTC time or a wall-clock time in the user's location:
someNow = time.Time()
localNow = someNow.In(location) // from time.LoadLocation() or similar
We also have something that seems at odds with your types:
upgradeDuration int64 - amount of time, from the upgradetime at which the time window is valid. it can be up to 12 hours
A value in hours that is between 0 and 12 inclusive fits easily in plain int. Is this already a time.Duration value expressed in nanoseconds? If so, why is it int64 and not time.Duration? Or is it a value in seconds, and therefore can be between 0 and 43200? If so, it still fits in int.
I made a bunch of assumptions and came up with the following, which you can try out on the Go Playground.
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
// startOK determines whether the given starting-time is within a
// time window.
//
// The window starts at a time given as two integers,
// h and m, representing hours and minutes, and extends for
// the given duration d in hours, which in general should not
// extend into another day. If it does extend past the end of
// the day into the next day, we ignore the extension.
//
// The days on which the time *is* in that window are further
// limited by the days[] slice of Weekday values.
//
// Note: it would probably be sensible to return a time.Duration
// value that is how long it will be until the next OK time, but
// we leave that as an exercise.
//
// It would also be sensible to allow the duration d to extend
// into the next day, which is also left as an exercise.
func startOK(when time.Time, days []time.Weekday, h, m, d int) bool {
// Find OK-to-start time, and end-time. If end exceeds
// 24*60, we ignore the extra end time, rather than
// allowing some minutes into the next day.
start := h*60 + m
end := start + d*60
// Convert when to hour-and-minute and see if we are
// in the allowed range.
wh, wm, _ := when.Clock()
now := wh*60 + wm
if now < start || now >= end {
// Not in hh:mm through hh+d:mm; say no.
return false
}
// The time-of-day is OK; check the day-of-week.
// We could do this earlier but by positioning it
// here, we leave room to check to see if it's
// the *next* day, if needed.
if !func(wd time.Weekday) bool {
for _, allowed := range days {
if wd == allowed {
return true
}
}
return false
}(when.Weekday()) {
return false // when.Weekday() not in days[]
}
// time is OK, day is OK
return true
}
// startOKstr is like startOK but the window starts at a time
// given as a string encoded as hh:mm, with the days being a
// slice of strings instead of Weekday. Because of these strings,
// parsing can produce an error, so this function has an error
// return.
func startOKStr(when time.Time, days []string, hhmm string, d int) (bool, error) {
parts := strings.Split(hhmm, ":")
// optional: be strict about two-digit values
if len(parts) != 2 {
return false, fmt.Errorf("invalid time string %q", hhmm)
}
h, err := strconv.Atoi(parts[0])
if err != nil {
return false, err
}
if h < 0 || h >= 60 {
return false, fmt.Errorf("invalid hour value %s", parts[0])
}
m, err := strconv.Atoi(parts[1])
if err != nil {
return false, err
}
if m < 0 || m >= 60 {
return false, fmt.Errorf("invalid minute value %s", parts[1])
}
var wd []time.Weekday
for _, s := range days {
w, err := parseWeekday(s)
if err != nil {
return false, err
}
wd = append(wd, w)
}
ok := startOK(when, wd, h, m, d)
return ok, nil
}
// parseWeekday handles weekday strings.
//
// Ideally we'd use time.Parse for this, as it already has
// these in it, but they are not exported in usable form.
func parseWeekday(s string) (time.Weekday, error) {
strToWeekday := map[string]time.Weekday{
"Sunday": time.Sunday,
"Monday": time.Monday,
"Tuesday": time.Tuesday,
"Wednesday": time.Wednesday,
"Thursday": time.Thursday,
"Friday": time.Friday,
"Saturday": time.Saturday,
}
if v, ok := strToWeekday[s]; ok {
return v, nil
}
return time.Sunday, fmt.Errorf("invalid day-of-week %q", s)
}
// tests should be converted to real tests and put in
// a separate file.
func tests() {
okDays := []string{"Sunday", "Wednesday"}
okStart := "04:00"
okDuration := 2 // hours
tfmt := "Mon Jan 2 15:04:05 2006"
t1 := "Sat Sep 5 04:30:00 2020" // time OK, day not
t2 := "Sun Sep 6 04:30:00 2020" // time OK, day OK
check := func(s string, expect bool) {
when, err := time.Parse(tfmt, s)
if err != nil {
panic(err)
}
result, err := startOKStr(when, okDays, okStart, okDuration)
if err != nil {
panic(err)
}
if result != expect {
fmt.Printf("fail: expected %v for %q\n", expect, s)
}
}
check(t1, false)
check(t2, true)
fmt.Println("2 tests run")
}
func main() {
tests()
}

Any easier ways to get the current datestamp

I have this code here but I don't think it's elegant. In fact I think it's kind of messy. Does anyone have a better/cleaner/concise code than this? I just need the timestamp of the day.
package main
import (
"os"
"fmt"
"io"
"time"
"strconv"
)
const (
layoutISO = "2006-01-02"
layoutUS = "January 2, 2006"
)
func main() {
year, month, day := time.Now().Date()
dayStr := strconv.Itoa(day)
if len(dayStr) == 1 {
dayStr = "0"+dayStr
}
mthStr := strconv.Itoa(int(month))
if len(mthStr) == 1 {
mthStr = "0"+mthStr
}
layout := strconv.Itoa(year)+"-"+mthStr+"-"+dayStr
fmt.Printf("%v\n",layout)
t, err := time.Parse(layoutISO, layout)
if err != nil {
fmt.Println(err)
}
fmt.Println(t.Unix())
}
This is the answer #Marc suggested. Thanks.
fmt.Printf("Value = %v\n",time.Date(year, month, day, 0,0,0,0, time.UTC).Unix())
I don't fully understand what you're asking, but here are some ways to get the current date and time information.
fmt.Println("current date and time:", time.Now().Format("2 January 2006 15:04:05"))
fmt.Println("current time:", time.Now().Format("15:04:05"))
fmt.Println("current date:", time.Now().Format("2 January 2006"))
https://play.golang.org/p/U2PKjivNzXa

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

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