parse capital letter month in golang - date

I want to parse string like "25-APR-2019" to time.time
I know parsing date using
date, err := time.Parse(layout, stringVariableForDate)
But I didn't find layout option in https://golang.org/pkg/time/#pkg-constants
I can not use JAN, as using this, I am getting error :
panic: parsing time "25-APR-2019" as "02-JAN-2006": cannot parse "APR-2019" as "-JAN-"
How can I parse date string with month name in capital letter in go-lang?

Package time
import "time"
The recognized month formats are "Jan" and "January".
The parse layout abbreviated month format is "Jan". Use "02-Jan-2006" for the parse layout.
For example,
package main
import (
"fmt"
"time"
)
func main() {
date, err := time.Parse("02-Jan-2006", "25-APR-2019")
fmt.Println(date, err)
}
Playground: https://play.golang.org/p/5MRpUrUVJt4
Output:
2019-04-25 00:00:00 +0000 UTC <nil>

Related

Parse Date dynamically

I have a case in which I can have both Date alone or with Date + Time Zone . So when I parse it with TimeZone like this
dateString := "2021-03-11T00:00:00Z"
time1, _ := time.Parse(time.RFC3339,dateString);
fmt.Println(time1);
It gives accurate answer but when I dynamically It gets Date like
dateString := "2021-03-11"
time1, _ := time.Parse(time.RFC3339,dateString);
fmt.Println(time1); //gives this 0001-01-01 00:00:00 +0000 UTC
while In both cases I just want date like this "2021-03-11". what is best way to achieve this
To parse just the date, you can use "2006-01-02" as the layout to time.Parse.
See the official docs for how these layouts are handled and what time.Parse expects.
As #zerkms says in a comment, if you check the error from time.Parse you'll know whether it succeeded or not, so you can try something else. Rough code sketch:
dateString := "2021-03-11"
time1, err := time.Parse(time.RFC3339, dateString)
if err != nil {
time1, err = time.Parse("2006-01-02", dateString)
if err != nil {
log.Fatal("cannot parse using either layout:", err)
}
}
fmt.Println(time1)
In real life I'd probably wrap it in a function that tries parsing both ways before it gives up and returns an error.

Parse UTC date string and convert to different format

Go newcomer here.
I have a date string 2018-06-07T16:16:57Z and I want to convert it to something like this mm/dd/yyyy hh:mm.
This seems to be a frequently asked question, but I can't seem to find any previous questions that work for me.
I'm reading in a time field and trying to convert like this
time := row["Date & Time"]
fmt.Println(time)
t, _ := time.Parse("2006-01-02 15:04:05 -0700 UTC", time)
fmt.Println(t)
But I think the issue is that I don't have a correct format string. I've tried a few resources to no success.
When I print t as is, I get 0001-01-01 00:00:00 +0000 UTC as a result, which is obviously incorrect.
What I'd like to do is convert the time I'm reading in like this
newTime := currentDate.Format("01/02/2006 hh:mm")
You have two issues.
First, you should not name the variable time as that is the name of a built-in package. I suppose you knew that and this is just a copy paste error.
Next, the string you pass to time.Parse() is a format string that should describe the format of the time string from your database. You already know what the format is: 2018-06-07T16:16:57Z, so just use that replacing the value with Go's reference time.
Here is working variant:
package main
import (
"fmt"
"time"
)
func main() {
tm := "2018-06-07T16:16:57Z"
fmt.Println(tm)
t, err := time.Parse("2006-01-02T15:04:05Z", tm)
if err != nil {
panic(err)
}
fmt.Println(t)
}
Run in playground
What's more the time format database uses is often described as RFC3339, which is also available as the time.RFC3339 constant in Go.
So using that simplifies your code even further:
package main
import (
"fmt"
"time"
)
func main() {
tm := "2018-06-07T16:16:57Z"
fmt.Println(tm)
t, err := time.Parse(time.RFC3339, tm)
if err != nil {
panic(err)
}
fmt.Println(t)
}
Run in playground
And if you prefer, you could also let the database driver convert the time for you by scanning it to a time.Time variable.
For example:
var tm time.Time
if err = row.Scan(&tm); err != nil {
panic(err)
}
fmt.Print(tm)
As #mkopriva describes the layout should be matched. Understand the layout which is 2006-01-02T15:04:05Z, go through Golang spec for layout use to convert the string to date
Parse parses a formatted string and returns the time value it
represents. The layout defines the format by showing how the reference
time, defined to be
Mon Jan 2 15:04:05 -0700 MST 2006
and then use returned time value to Format the date according to your requirement.
package main
import (
"fmt"
"time"
)
func main() {
layout1 := "2006-01-02T15:04:05Z"
t, err := time.Parse(layout1, "2018-06-07T16:16:57Z")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(t.Format("01/02/2006 15:04"))
}
Check it on Go Playground

How to convert YYYY-MM-DD string format to timestamp in Golang?

I'm sorry if this is a trivial question. This is currently what I have.
snapshot = "2017-07-25"
snapshotFilter := " AND cdate = %s"
snapshot, err := time.Parse(time.RFC3339, snapshot)
if err != nil {
log.Fatal(err)
}
queryFilter = queryFilter + fmt.Sprintf(snapshotFilter, pq.FormatTimestamp(snapshot))
This is the output
2017/09/12 09:59:34 parsing time "2017-07-25" as "2006-01-02T15:04:05Z07:": cannot parse "" as "T".
I'm trying to get snapshot in the correct format to insert it into a postgres query.
I'm using the
"database/sql"
"time"
"github.com/gorilla/mux"
"github.com/lib/pq"
EDIT: is seemed that this was more of an issue with postgres and the 2017-07-25 just needed to be in quotes and put inside the postgres query string.
As already suggested, use this:
package main
import (
"fmt"
"log"
"time"
)
const layout = "2006-01-02"
func main() {
snapshot := "2017-07-25"
t, err := time.Parse(layout, snapshot)
if err != nil {
log.Fatal(err)
}
fmt.Println(t)
}
As you can see in the documentation of constants for the time package there is a reference date
Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
which is used to specify date/time strings layout. So you provide a string and every occurrence of 3 gets replaced by the hour in 12h am/pm notation of your point in time and every occurrence of 15 gets replaced by the hour in 24h representation for example.
All the wrinkles and problems of such an approach are explained in some sample code in the documentation.

How do you parse date in the format:

It's not clear to me from the documentation how I would parse a date in this somewhat strange format. It seems like it might not be possible.
2016-07-08T08:34:24+00:00
The following does not work (go play link)
package main
import (
"fmt"
"time"
)
func main() {
date := "2016-07-08T08:34:24+00:00"
d, err := time.Parse("2006-01-02T15:04:05+07:00", date)
if err == nil {
fmt.Println(d)
} else {
fmt.Println(err)
}
}
Obviously a regexp could first check for this format and transform the + to a -, but that implies the standard library cant parse this date.
Go's reference layout uses -7 hours as the timezone offset, but you used +7 hours:
package main
import (
"fmt"
"time"
)
func main() {
date := "2016-07-08T08:34:24+00:00"
d, err := time.Parse("2006-01-02T15:04:05-07:00", date)
if err == nil {
fmt.Println(d)
} else {
fmt.Println(err)
}
}
https://play.golang.org/p/FNzx57R2jy

Date parsing in Go

I'm trying to parse a timestamp as produced by tar such as '2011-01-19 22:15' but can't work out the funky API of time.Parse.
The following produces 'parsing time "2011-01-19 22:15": month out of range'
package main
import (
"fmt"
"time"
)
func main () {
var time , error = time.Parse("2011-01-19 22:15","2011-01-19 22:15")
if error != nil {
fmt.Println(error.String())
return
}
fmt.Println(time)
}
Follow the instructions in the Go time package documentation.
The standard time used
in the layouts is:
Mon Jan 2 15:04:05 MST 2006 (MST is
GMT-0700)
which is Unix time 1136243045. (Think
of it as 01/02 03:04:05PM '06 -0700.)
To define your own format, write down
what the standard time would look like
formatted your way.
For example,
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse("2006-01-02 15:04", "2011-01-19 22:15")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(time.SecondsToUTC(t.Seconds()))
}
Output: Wed Jan 19 22:15:00 UTC 2011