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
Related
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>
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
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.
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
If I store ISODate in mongodb,the ISODate is always GMT+0
type StoreTime struct {
storeTime time.Time `bson:"testTime" json:"testTime,omitempty"`
}
...
t := StoreTime {
storeTime : time.Now(),
}
....
c.Insert(t)
The result is :
{
"_id" : ObjectId("578b43e5feaa0deb6a94b1d0"),
"storeTime" : ISODate("2016-07-17T08:38:25.316+0000")
}
How can I change the time zone?
You came across an intricacy of mgo.v2/bson, which converts Since the BSON specification states that all times shall be stored as
UTC milliseconds since the Unix epoch
mgo.v2/bson converts all time.Time values to UTC. So even when you explicitly set the location info of a time returned by time.Now() or companions, this local time is converted to UTC.
So in order to display time correctly for any given time zone, you should do the following:
When saving a time.Time value, you should use the time as returned by time.Time.In(*time.Location) if the time zone differs from your (the servers) local time.
When displaying the returned value in UTC, make sure you use time.Time.UTC()
When displaying the returned value in a given local time, make sure you use time.Time.In(*time.Location) again.
To be a more clear on that, please have a look at the example below:
package main
import (
"fmt"
"time"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
const (
myLoc = "Europe/Berlin"
ny = "America/New_York"
)
// We define those vars here, as you might want to make them
// package-global
var (
berlin *time.Location
nyc *time.Location
)
// StoreTime is just a dummy struct
type StoreTime struct {
// Unexported fields are not (un-)marshalled by encoding/json
// and mgo.v2/bson, so the field name has to be uppercase
StoreTime time.Time `bson:"testTime"`
}
func main() {
var (
sess *mgo.Session
err error
)
// Connect to MongoDB
if sess, err = mgo.Dial("localhost:27017"); err != nil {
panic("Could not connect to MongoDB: " + err.Error())
}
// Make sure the session is closed when main exits for whatever reason
defer sess.Close()
// Clear the collection for demo purposes
if err = sess.DB("test").C("timezones").Remove(bson.M{}); err != nil && err != mgo.ErrNotFound {
panic("Could not clean test collection: " + err.Error())
}
// Load the desired TZ by location
if berlin, err = time.LoadLocation(myLoc); err != nil {
panic("Error loading '" + myLoc + "' as timezone location: " + err.Error())
}
// Create a new StoreTime with the local time of the desired timezone.
// Note that mgo.v2/bson still converts it to Zulu time, but with the
// appropriate offset.
st := &StoreTime{StoreTime: time.Now().In(berlin)}
// Save the document for further reference
if err = sess.DB("test").C("timezones").Insert(st); err != nil {
panic("Error inserting sample document into MongoDB: " + err.Error())
}
// Load the saved document,...
res := &StoreTime{}
if err = sess.DB("test").C("timezones").Find(nil).One(&res); err != nil {
panic("Unable to load just recently stored document: " + err.Error())
}
// ... and another TZ for displaying,...
if nyc, err = time.LoadLocation(ny); err != nil {
panic("Error loading '" + ny + "' as timezone location: " + err.Error())
}
// ...and display the time from the document in UTC and the local time
// of both Berlin and NYC.
fmt.Println(res.StoreTime.UTC())
// The next two are identical for _me_, as I happen to live in the according TZ.
// Unless you do, too, you should have different values
fmt.Println(res.StoreTime.In(Berlin))
fmt.Println(res.StoreTime)
fmt.Println(res.StoreTime.In(nyc))
}
time.Now should return local time. Is your system time setup properly? What do you get on running the date command (on linux based system)?
You can try using In method on you time object with a time.Location value:
l, _ := time.LoadLocation("Local") // or the name of your time zone
t : time.Now()
t := StoreTime {
storeTime : t.In(l),
}