check if timestamp between 2 dates - go

I have dates stored as timestamps in mongo, for example, 1564444800000000000. I want to check if a timestamp is between 2 dates - July 1, 2021 and July, 2021. I converted these 2 dates to timestamps using https://www.epochconverter.com/. I first fetched all records and while looping through the records, I did a check like so
cDate := 1564444800000000000
if cDate > 1625167488000 && cDate < 1627759488000 {
log.Fatal("found one!")
}
But this not seem to work as I get no matches. Is there a better way of doing this?

I mean just looking at the numbers:
cDate := 1564444800000000000
1625167488000
1627759488000
I don't see how one with six more digits than the one's it's supposed to be between would ever be between them. And even if we divided CDate by 1000000 it would be
cDate := 1564444800000
1625167488000
1627759488000
and it's still less than both of those, so it still wouldn't be between them. But that being said, you most likely do just need to divide cDate by 1000000 and your example is just not a good one (since 1564444800000 is July 29 2019)

I suggest to transform in a date then check with the before and after API, as example:
package main
import (
"fmt"
"time"
)
func main() {
cDate := int64(1564444800000000000)
firstJuly := time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)
thrirtyOneJuly := time.Date(2019, 7, 31, 0, 0, 0, 0, time.UTC)
date := time.Unix(0, cDate)
// fmt.Println(date) //will print 2019-07-30 00:00:00 +0000 UTC
fmt.Println("Is July?", date.After(firstJuly) && date.Before(thrirtyOneJuly))
}
will print
Is July? true
See on playground

Related

GoLang time zone conversion

I am looking to display a time in a specific format for a particular country. My current code:
now := time.Now()
ogTime := time.Date(2022, 8, 1, 0, 0, 0, 0, now.Location())
loc, _ := time.LoadLocation("Asia/Singapore")
convertedTime := ogTime.In(loc)
fmt.Println(convertedTime)
This prints out 2022-08-01 08:00:00 +0800 +08
Is there a way to display 2022-07-31T16:00:00Z? Is it possible to remove the time offset and instead just have a Z? I have tried ogTime.Format(RFC3339) as well as something like ogTime.Format("2006-01-02 T15:04:05Z"), but neither work.
fmt.Println is using the Stringer()-implementation of time.Time to print the value as a string, which determines the formatting for you.
To set the format yourself, use time.Time.Format();
now := time.Now()
fmt.Println(now.Format(`2006-01-02T15:04:05Z07:00`))
A "Z" in the output without an offset means the time is in UTC. If you do not want to print the timezone, omit it from the format;
fmt.Println(convertedTime.Format("2006-01-02T15:04:05"))
2022-08-01T08:00:00
If you want to print in UTC convert the timezone before printing; fmt.Println(convertedTime.UTC().Format("2006-01-02T15:04:05Z07:00"))
2022-08-01T00:00:00Z
Printing a "Z" while the time is not in UTC would require you to concatenate it yourself, but would be silly;
fmt.Println(convertedTime.Format("2006-01-02T15:04:05") + "Z")
2022-08-01T08:00:00Z
If you want to provide local time and print it in UTC, provide your timezone when parsing the date
loc, _ := time.LoadLocation("Asia/Singapore")
ogTime := time.Date(2022, 8, 1, 0, 0, 0, 0, loc)
fmt.Println(ogTime.UTC().Format("2006-01-02T15:04:05Z07:00"))
2022-07-31T16:00:00Z

Golang Time parsing providing the format is returning wrong results

I've got a t time.Time which I'm converting to an specific timezone and from which I need to extract both date and time (separately) as strings as follows:
Data should look like: 2006-09-23
Time should look like: 05:06:23
I'm doing the following:
Setting t to the needed timezone:
var err error
loc, err := time.LoadLocation("America/Los_Angeles")
if err != nil {
return err
} else {
t = t.In(loc)
}
Setting up the format and converting it to string so I can extract its values:
format := "2006-01-02 15:03:04"
timestamp := t.Format(format)
timestampSlice := strings.Fields(timestamp)
fmt.Println(timestampSlice[0])
fmt.Println(timestampSlice[1])
But I'm getting unexpected results for time (date works fine):
When passing
time.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC)
I'd expect
2021-02-20 and 17:10:30
but I'm getting:
17:05:10 for the time
When passing
time.Date(2022, time.Month(8), 26, 22, 7, 30, 0, time.FixedZone("Asia/Shanghai", 0)),
I'd expect
2022-08-26 and 06:07:30
but I'm getting:
15:03:07
what am I doing wrong? does the values passed in the format have any effect in the parsing? I thought the format was only to signal the way the result should look
From the docs:
// Jan 2 15:04:05 2006 MST
// 1 2 3 4 5 6 -7
So the format 2006-01-02 15:03:04 would be parsed as years-months-days hours-hours-minutes. Note that 15 refers to the hours (00-23), that 03 refers to the hours (1-12), and 04 refers to the minutes.
So the correct format would be
format := "2006-01-02 15:04:05"
You can learn more about formatting time here: https://pkg.go.dev/time#example-Time.Format

Given the IANA entry is known, how do I find a specific dates offset (daylight vs standard)?

I have a list of date strings that appear in this format without any time zone or offset information:
[
"2019-04-30T12:34:00.000", // In 2019, DST started in March 10, 2019, so this should have the appropriate DST offset
"2017-11-20T13:45:00.000" // In 2017, DST ended on November 5, 2017 so this should have the appropriate standard time offset
]
I know the IANA region (eg, America/New_York) that these dates and times were created in, but I cannot figure out how to dynamically generate the appropriate offset given this information using go and the time package.
I have thought about the following:
Appending a hardcoded value to the end of the date string (ie, "2019-04-30T12:34:00.000" + "-04:00)
Write custom logic to determine if a date falls within the boundary of standard or daylight savings time
However, these solutions only work for some dates or the logic becomes exceedingly complicated.
I was able to figure it out
package main
import (
"log"
"time"
)
func main() {
Chicago, _ := time.LoadLocation("America/Chicago")
t := time.Date(2019, time.March, 1, 12, 30, 0, 0, Chicago)
log.Print(t) // 2019-03-01 12:30:00 -0600 CST
log.Print(t.UTC()) // 2019-03-01 18:30:00 +0000 UTC
t = time.Date(2019, time.November, 2, 12, 30, 0, 0, Chicago)
log.Print(t) // 2019-11-02 12:30:00 -0500 CDT
log.Print(t.UTC()) // 2019-11-02 17:30:00 +0000 UTC
}
go playground # https://play.golang.org/p/nP28y9jSDAk
An even cleaner solution by leveraging a custom layout and time.LoadLocation
package main
import (
"fmt"
"time"
)
func main() {
Chicago, _ := time.LoadLocation("America/Chicago")
cdt, _ := time.ParseInLocation("2006-01-02T15:04:05.999999", "2019-04-30T12:34:00.000", Chicago)
fmt.Println(cdt)
fmt.Println(cdt.UTC())
cst, _ := time.ParseInLocation("2006-01-02T15:04:05.999999", "2017-11-20T13:45:00.000", Chicago)
fmt.Println(cst)
fmt.Println(cst.UTC())
}
go playground # https://play.golang.org/p/3Ai4qVz0af5

Golang equivalent of strtotime("this Sunday, 23:59:59")

I am writing a scraper that scrapes offers off websites and these offers have end dates. One such website has offers that expire every Sunday. I have gone through the golang time documentation but still dont get how that can be done the equivalence I found in PHP and is pretty simple.
$endDate = strtotime('this Sunday, 23:59:59');
Is there a golang way to do this?
Write a function in Go using the Go standard library time package. For example,
package main
import (
"fmt"
"time"
)
func endDate(t time.Time, wd time.Weekday) time.Time {
next := int((wd - t.Weekday() + 7) % 7)
y, m, d := t.Date()
return time.Date(y, m, d+next+1, 0, 0, 0, -1, t.Location())
}
func main() {
now := time.Now().Round(0)
fmt.Println(now, now.Weekday())
end := endDate(now, time.Sunday)
fmt.Println(end, end.Weekday())
}
Playground: https://play.golang.org/p/T0oZGRO9NV8
Output:
2018-11-08 05:25:01.104445722 -0500 EST Thursday
2018-11-11 23:59:59.999999999 -0500 EST Sunday

Go time.Format wrong month

I'd like to rename some files based on their modification date.
When I use the time.Format method to get the correct string, basically in this format YYYY-MM-DD_HH-MM-SS, the day has a trailing 0.
Am I doing something wrong here?
package main
import (
"time"
"fmt"
)
func main() {
loc, _ := time.LoadLocation("Europe/Berlin")
const layout = "2006-01-20_15-04-05"
t := time.Date(2013, 07, 23, 21, 32, 39, 0, loc)
fmt.Println(t)
fmt.Println(t.Format(layout))
}
Click to play
Output:
2013-07-23 21:32:39 +0200 CEST
2013-07-230_21-32-39
Your layout isn't using the reference date: change it to "2006-01-02_15-04-05"
When you use "2006-01-20_15-04-05", the formatter see the 2, and uses that for the day, then keeps the extra 0 since it doesn't match any part of the reference date.

Resources