Go: time.Parse() issue - parsing

I have the following code:
timeLocal := "01/July/2015:18:12:25 +0900"
inFormat := "02/January/2006:15:04:05 -0700"
parsed, err := time.Parse(inFormat, timeLocal)
if err != nil {
log.Fatal("Time format was not recognized!")
}
Now, parsing works fine. But when I run:
fmt.Println(timeLocal)
fmt.Println(inFormat)
fmt.Println(parsed)
The output is:
01/July/2015:18:12:25 +0900
02/January/2006:15:04:05 -0700
2015-07-01 18:12:25 +0900 +0900
Should the second +0900 be there? What is the stupid thing that I'm doing? Sorry, it was really a long day, I don't see what I'm missing.
Oh, and the whole file is here:
package main
import (
"fmt"
"time"
"log"
)
func main() {
timeLocal := "01/July/2015:18:12:25 +0900"
inFormat := "02/January/2006:15:04:05 -0700"
parsed, err := time.Parse(inFormat, timeLocal)
if err != nil {
log.Fatal("Time format was not recognized!")
}
fmt.Println(timeLocal)
fmt.Println(inFormat)
fmt.Println(parsed)
}

If you look at documentation of time.Time you will see what the default output format is:
String returns the time formatted using the format string:
"2006-01-02 15:04:05.999999999 -0700 MST"
Now you should see what the second +0900 is doing there – this is a location (time zone) name. Since your input format doesn't have a name it will simply repeat an offset.
You can provide name by altering your input format to parse location name. Alternatively you can provide an output format which doesn't print the name, if you don't need it.
Your modified example:
package main
import (
"fmt"
"time"
"log"
)
func main() {
timeLocal := "01/July/2015:18:12:25 +0900 XYZ"
inFormat := "02/January/2006:15:04:05 -0700 MST"
parsed, err := time.Parse(inFormat, timeLocal)
if err != nil {
log.Fatal("Time format was not recognized!")
}
fmt.Println(timeLocal)
fmt.Println(inFormat)
fmt.Println(parsed) // 2015-07-01 18:12:25 +0900 XYZ
fmt.Println(parsed.Format("02/January/2006:15:04:05 -0700"))
}
http://play.golang.org/p/xVGvlt-M5B

The default format used by Time.String is this:
2006-01-02 15:04:05.999999999 -0700 MST
Notice the "MST" part. Since you're not providing the name of the zone, the format just "names" it the same as offset, that is "+0900". If you change that to "+0000", you'll see that this is indeed a time zone name:
2015-07-01 18:12:25 +0000 UTC
If you don't want that, just use a separate format for printing:
myFmt := "2006-01-02 15:04:05.999999999 -0700"
fmt.Println(parsed.Format(myFmt))

Related

Date.gettime() is not a function, undefined

It is working on android and browser and WAS working on iOS (ionic view and device). I am saving a date inside my local Storage (import { Storage } from '#ionic/storage';) then compare it to a another date
Here's what I do And is working everywhere but suddenly, not ios under ionic view. Last test was maximum 2 weeks ago and was working as intended !
this.storage.get(filename).then((metadata_stored) => {
if (metadata_stored && metadata_stored.date && metadata_stored.date.getTime() === filedate.getTime())
//do something
and I get TypeError: metadata_stored.date.getTime() is not a function; metadata_stored.date.getTime is undefined.
filedate is create through something like this filedate: Date = new date("2017-10-14T15:44:48+02:00") (supposedly an ISO). Then it is saved in my local storage : this.storage.set(filename, { /* ... */ , date: filedate })
If I display metadata_stored.data, I get something like 2017-08-13T13:44:10.000Z
I don't get why it suddenly and silently stopped working. And how to correct it since metadate.date is an old value of filedate and filedate is a new Date(...) ! No code were changed in this section last 2 weeks.
Edit: I solved it by doing (new Date(metadata_stored.date)).getTime() instead. But I still have no idea why it stopped working for no reason...
In local storage, everything is stored as a string.
That means you should use (new Date(metadata_stored.date)).getTime() because metadata_stored.date is a string, not a Date.
let a = new Date();
let b = new Date();
// 2017-11-30T18:01:01457Z object
console.log(a, typeof a);
// 2017-11-30T18:01:01457Z object
console.log(b, typeof b);
localStorage.a = a;
localStorage.b = b;
a = localStorage.a;
b = localStorage.b;
// Thu Nov 30 18:01:01 GMT+0000 (GMT Standard Time) string
console.log(a, typeof a);
// Thu Nov 30 18:01:01 GMT+0000 (GMT Standard Time) string
console.log(b, typeof b);
a = new Date(localStorage.b);
b = new Date(localStorage.a);
// 2017-11-30T18:01:01457Z object
console.log(a, typeof a);
// 2017-11-30T18:01:01457Z object
console.log(b, typeof b);

RFC3339 time parsing in golang

I'm pulling a timestamp from a datebase, it is using RFC3339 format but the timezone is missing. So when I try to compare the timestamps it will be off. How do I change dbtime to be Eastern time?
// time format
const
(
RFC3339 = "2006-01-02T15:04:05Z07:00"
)
//now time
now := time.Now()
nowtime := now.Unix()
fmt.Println("Nowtime:", nowtime)
fmt.Println("Now:", now)
//time in db
fmt.Println("Dbtime string:", dbtime)
udbtime, err := time.Parse.EST(RFC3339,dbtime)
fmt.Println("RFC3339: " + RFC3339)
fmt.Println("dbtime parsed", udbtime)
fmt.Println("dbtime parsed unixtime", udbtime.Unix())
My output is
Nowtime: 1466443640
Now: 2016-06-20 13:27:20.963232824 -0400 EDT
Dbtime string: 2016-06-20T12:41:45.14Z
RFC3339: 2006-01-02T15:04:05Z07:00
dbtime parsed 2016-06-20 12:41:45.14 +0000 UTC
dbtime parsed unixtime 1466426505
You could parse the timestamps using the defined time.RFC3339 like you've shown, and adjust them after the fact by adding the UTC offset so that they are correct in UTC.
udbtime = udbtime.Add(4*time.Hour)
This however requires that you check whether each time falls in EST or EDT to add the correct offset, unless you can assume they are all EDT.
A better way would be to use your own time format without a specific TZ offset (the Z isn't part of the time specification for parsing), and parse it with time.ParseInLocation.
This way you can account for the correct offset depending on whether the time would have been in EST or EDT.
https://play.golang.org/p/IrUnTwvlkk
RFC3339local := "2006-01-02T15:04:05Z"
loc, err := time.LoadLocation("America/New_York")
if err != nil {
log.Fatal(err)
}
ts1 := "2016-06-20T12:41:45.14Z"
t1, _ := time.ParseInLocation(RFC3339local, ts1, loc)
fmt.Println(t1)
// prints: 2016-06-20 12:41:45.14 -0400 EDT
ts2 := "2016-01-20T12:41:45.14Z"
t2, _ = time.ParseInLocation(RFC3339local, ts2, loc)
fmt.Println(t2)
// prints: 2016-01-20 12:41:45.14 -0500 EST
you can try go-carbon,a simple,semantic and developer-fridendly golang package for datetime
carbon.Parse("2020-12-31").ToRfc3339String()
// output
2020-12-31T00:00:00+08:00
https://github.com/golang-module/carbon

How do I convert a string value in uint16 in Go lang?

I'm researching a solution in order to convert a string (in my case the string is "05f8") into a uint16.I made research but I don't find a solution.Does anyone know how to do this?
Thanks for your help!
Use strconv.ParseUint (doc).
var s = "05f8"
var base = 16
var size = 16
value, err := strconv.ParseUint(s, base, size)
value2 := uint16(value) // done!
Note that the output value is an uint64, you have to cast it to you type before using it.
Note (bis) that the size parameter control the maximum size of the uint to convert to, so the overflow check is done correctly.
If you are interested in turning a string into []uint16, you can do:
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
a, e := windows.UTF16FromString("05f8")
if e != nil {
panic(e)
}
fmt.Printf("%q\n", a) // ['0' '5' 'f' '8' '\x00']
}
or, if you are certain string contains no NUL bytes, you can do this:
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
a := windows.StringToUTF16("05f8")
fmt.Printf("%q\n", a) // ['0' '5' 'f' '8' '\x00']
}
https://pkg.go.dev/golang.org/x/sys/windows#StringToUTF16
https://pkg.go.dev/golang.org/x/sys/windows#UTF16FromString
By no means do I claim to be a go developer, and I welcome feedback on this, but I was trying to convert an env variable for a port from a string to uint16. I was able to get it working with:
File: main.go
package main
import (
"log"
"os"
"strconv"
)
var PORT = os.Getenv("PORT")
func main() {
portAsInt, err := strconv.ParseInt(PORT, 0, 16)
if (err != nil) {
log.Fatal(err)
}
// Use as needed with uint16()
log.Println("Listening on port:", uint16(portAsInt))
}
Running application:
PORT=3000 go run main.go;
# Expected Output:
# Listening on port: 3000

time.Parse with custom layout

I'm trying to parse this string pattern "4-JAN-12 9:30:14" into a time.Time.
Tried time.Parse("2-JAN-06 15:04:05", inputString) and many others but cannot get it working.
I've read http://golang.org/pkg/time/#Parse and https://gobyexample.com/time-formatting-parsing but it seems there aren't any examples like this.
Thanks!
Edit:
full code:
type CustomTime time.Time
func (t *CustomTime) UnmarshalJSON(b []byte) error {
auxTime, err := time.Parse("2-JAN-06 15:04:05", string(b))
*t = CustomTime(auxTime)
return err
}
parsing time ""10-JAN-12 11:20:41"" as "2-JAN-06 15:04:05": cannot
parse ""24-JAN-15 10:27:44"" as "2"
Don't know what you did wrong (should post your code), but it is really just a simple function call:
s := "4-JAN-12 9:30:14"
t, err := time.Parse("2-JAN-06 15:04:05", s)
fmt.Println(t, err)
Outputs:
2012-01-04 09:30:14 +0000 UTC <nil>
Try it on the Go Playground.
Note that time.Parse() returns 2 values: the parsed time.Time value (if parsing succeeds) and an optional error value (if parsing fails).
See the following example where I intentionally specify a wrong input string:
s := "34-JAN-12 9:30:14"
if t, err := time.Parse("2-JAN-06 15:04:05", s); err == nil {
fmt.Println("Success:", t)
} else {
fmt.Println("Failure:", err)
}
Output:
Failure: parsing time "34-JAN-12 9:30:14": day out of range
Try it on the Go Playground.
EDIT:
Now that you posted code and error message, your problem is that your input string contains a leading and trailing quotation mark!
Remove the leading and trailing quotation mark and it will work. This is your case:
s := `"4-JAN-12 9:30:14"`
s = s[1 : len(s)-1]
if t, err := time.Parse("2-JAN-06 15:04:05", s); err == nil {
fmt.Println("Success:", t)
} else {
fmt.Println("Failure:", err)
}
Output (try it on the Go Playground):
Success: 2012-01-04 09:30:14 +0000 UTC

Date parsing with sub method

I'm aware of the time package and how you can parse templates based on date/time representation. What I would like to know is how to parse time.Now() one month prior to stdLongMonth.
i.e.
time.Now() // == April, 2013
// Output: March, 2013
In other words, is it possible to parse time.now() with a sub.stdLongMonth() method? Can anyone be kind enough and show some examples?
For example,
package main
import (
"fmt"
"time"
)
func main() {
y, m, _ := time.Now().Date()
t := time.Date(y, m, 1, 0, 0, 0, 0, time.UTC)
fmt.Println(t.Format("January, 2006"))
t = time.Date(y, m-1, 1, 0, 0, 0, 0, time.UTC)
fmt.Println(t.Format("January, 2006"))
}
Output:
April, 2013
March, 2013
use time.AddDate() as this will also free you from timezone considerations:
package main
import (
"fmt"
"time"
)
func main() {
time := time.Now().AddDate(0,-1,0)
fmt.Println(time.Format("January, 2006"))
}

Resources