araddon / dateparse

GoLang Parse many date strings without knowing format in advance.
MIT License
2.04k stars 166 forks source link

Can't parse golang default format #64

Closed mgtest42 closed 6 years ago

mgtest42 commented 6 years ago

What am I doing wrong?

package main

import (
    "fmt"
    "github.com/araddon/dateparse"
)

func main() {
    a := "2018-06-29 19:09:57.77297118 +0300 +03" // result of time.Now().String()

    fmt.Println(a)
    t, err := dateparse.ParseLocal(a)
    fmt.Println(t, err)
    t, err = dateparse.ParseAny(a)
    fmt.Println(t, err)
    t, err = dateparse.ParseStrict(a)
    fmt.Println(t, err)

}

Result:

2018-06-29 19:09:57.77297118 +0300 +03
2018-06-29 03:09:57.77297118 +0300 +03 <nil>
2018-06-29 03:09:57.77297118 +0300 +03 <nil>
2018-06-29 03:09:57.77297118 +0300 +03 <nil>

Why only the hour is mangled?

go version go1.10.2 darwin/amd64
araddon commented 6 years ago

Can you try running the cli tool for testing formats? It parses for me, so wonder if its related to your local timezone?

araddon/dateparse/dateparse$ dateparse "2018-06-29 19:09:57.77297118 +0300 +03"

Your Current time.Local zone is PDT

Layout String: dateparse.ParseFormat() => 2006-01-02 15:04:05.00000000 -0700 +03

+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| method      | Zone Source           | Parsed                                   | Parsed: t.In(time.UTC)                       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| ParseAny    | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC day=5 |
| ParseAny    | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC day=5 |
| ParseIn     | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseIn     | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseLocal  | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseLocal  | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+
mgtest42 commented 6 years ago
go run dateparse/main.go "2018-06-29 19:09:57.77297118 +0300 +03"

Your Current time.Local zone is +03

Layout String: dateparse.ParseFormat() => 2006-01-02 15:04:05.00000000 -0700 +03

+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| method      | Zone Source           | Parsed                                   | Parsed: t.In(time.UTC)                       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| ParseAny    | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC day=5 |
| ParseAny    | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC day=5 |
| ParseIn     | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseIn     | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseLocal  | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseLocal  | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = nil      | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = time.UTC | 2018-06-29 03:09:57.77297118 +0300 +0300 | 2018-06-29 00:09:57.77297118 +0000 UTC       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+

It parses. But times aren't equal. Why "03" instead of "19"?

araddon commented 6 years ago

investigating. notes: https://play.golang.org/p/bWU0OklWnhi

Last line of go-playground shows the go lib parsing with that 03. Not sure how to handle if its a go lib issue, or way i can address it.

Where did that 2nd "+03" come from? That doesn't look like go time.Now().String() ?

mgtest42 commented 6 years ago
loc, err := time.LoadLocation("Asia/Istanbul")
fmt.Println(time.Now().In(loc))

On play.golang.org - 2009-11-11 01:00:00 +0200 EET On my mac: 2018-06-29 23:01:08.283113202 +0300 +03

For example, python returns the same timezone:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
datetime.timezone(datetime.timedelta(0, 10800), '+03')

It seems that on different systems time has a different format. And yes, it's golang bug (or os x?), not dateparse. I think we can close the issue. Sorry for bothering, I had to check it myself.

araddon commented 6 years ago

Thanks for submitting this ticket. after fix:

$ dateparse "2018-06-29 19:09:57.77297118 +0300 +03"

Your Current time.Local zone is PDT

Layout String: dateparse.ParseFormat() => 2006-01-02 15:04:05.00000000 -0700

+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| method      | Zone Source           | Parsed                                   | Parsed: t.In(time.UTC)                       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+
| ParseLocal  | time.Local = nil      | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
| ParseLocal  | time.Local = time.UTC | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = nil      | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
| ParseStrict | time.Local = time.UTC | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
| ParseAny    | time.Local = nil      | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC day=5 |
| ParseAny    | time.Local = time.UTC | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC day=5 |
| ParseIn     | time.Local = nil      | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
| ParseIn     | time.Local = time.UTC | 2018-06-29 19:09:57.77297118 +0300 +0300 | 2018-06-29 16:09:57.77297118 +0000 UTC       |
+-------------+-----------------------+------------------------------------------+----------------------------------------------+