web-dev-qa-db-fra.com

Chaîne de date d'analyse dans Go

J'ai essayé d'analyser la chaîne de date "2014-09-12T11:45:26.371Z" dans Go.

Code

layout := "2014-09-12T11:45:26.371Z"
str := "2014-11-12T11:45:26.371Z"
t, err := time.Parse(layout , str)

J'ai eu cette erreur:

temps d'analyse "2014-11-12T11: 47: 39.489Z": mois hors limites

Comment puis-je analyser cette chaîne de date?

109
kannanrbk

Utilisez les numéros de mise en page exacts décrits ici et un article de blog gentil ici .

alors:

layout := "2006-01-02T15:04:05.000Z"
str := "2014-11-12T11:45:26.371Z"
t, err := time.Parse(layout, str)

if err != nil {
    fmt.Println(err)
}
fmt.Println(t)

donne:

>> 2014-11-12 11:45:26.371 +0000 UTC

Je connais. Ahurissant. Aussi m'a attrapé la première fois. Go n’utilise simplement pas de syntaxe abstraite pour les composants datetime (YYYY-MM-DD), mais ces nombres exacts (Je pense que le temps du premier commit Non, selon this . Est-ce que quelqu'un sait?).

135
RickyA

La mise en page à utiliser est bien "2006-01-02T15:04:05.000Z" décrite dans RickyA 's réponse .
Ce n’est pas "le moment du premier commit", mais plutôt une façon mnémonique de se souvenir de ladite mise en page.
Voir pkg/heure :

Le temps de référence utilisé dans les présentations est:

Mon Jan 2 15:04:05 MST 2006

qui est le temps Unix 1136239445.
Puisque MST est GMT-0700, l’heure de référence peut être considérée comme

 01/02 03:04:05PM '06 -0700

(1,2,3,4,5,6,7, à condition de vous rappeler que 1 correspond au mois et 2 au jour, ce qui n'est pas facile pour un Européen comme moi, habitué au format de date jour-mois)

Comme illustré dans " time.parse: pourquoi golang analyse-t-il le temps incorrectement? ", cette mise en page (utilisant 1,2,3,4,5,6,7) doit être respectée exactement .

76
VonC

En guise de réponse, mais pour enregistrer en tapant "2006-01-02T15:04:05.000Z" pour la mise en page, vous pouvez utiliser la constante du paquet RFC3339 .

str := "2014-11-12T11:45:26.371Z"
t, err := time.Parse(time.RFC3339, str)

if err != nil {
    fmt.Println(err)
}
fmt.Println(t)

https://play.golang.org/p/Dgu2ZvHwTh

45
robstarbuck

C'est assez tard pour le parti, et je ne dis pas vraiment quoi que ce soit qui n'a pas déjà été dit sous une forme ou une autre, principalement par les liens ci-dessus, mais je voulais donner un récapitulatif TL; DR à ceux qui ont moins d'attention:

La date et l'heure de la chaîne de formatage sont très importantes. C'est comment Go sait quel domaine est lequel. Ils sont généralement 1-9 gauche à droite comme suit:

  • Janvier/janvier/janvier/janvier/01/_1 (etc) sont pour le mois
  • 02/_2 sont pour le jour du mois
  • 15/03/_3/PM/P/pm/p sont pour heure et méridien (15h)
  • 04/_4 sont pour minutes
  • 05/_5 sont pour secondes
  • 2006/06 sont pour l'année
  • -0700/07:00/MST sont pour le fuseau horaire
  • .999999999/.000000000, etc. sont des secondes partielles (je pense que la distinction est si les zéros de fin sont supprimés)
  • Lundi/lundi sont les jours de la semaine (ce qui était en réalité le 01-02-2006),

Donc, n'écrivez pas "01-05-15" comme format de date, à moins que vous ne vouliez "Mois-seconde-heure"

(... encore une fois, il s’agit essentiellement d’un résumé de ce qui précède.)

13
Loren Osborn

Je vais suggérer d'utiliser time.RFC3339 constante du paquet de temps. Vous pouvez vérifier les autres constantes du paquet de temps. https://golang.org/pkg/time/#pkg-constants

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("Time parsing");
    dateString := "2014-11-12T11:45:26.371Z"
    time1, err := time.Parse(time.RFC3339,dateString);
    if err!=nil {
    fmt.Println("Error while parsing date :", err);
    }
    fmt.Println(time1); 
}
11
Nishant Rawat

Cela peut être très tardif, mais il s’agit des personnes qui pourraient trébucher sur ce problème et souhaiteraient peut-être utiliser un package externe pour analyser la chaîne de date.

J'ai essayé de chercher une bibliothèque et j'ai trouvé celle-ci:

https://github.com/araddon/dateparse

Exemple tiré du fichier README:

package main

import (
    "flag"
    "fmt"
    "time"

    "github.com/apcera/termtables"
    "github.com/araddon/dateparse"
)

var examples = []string{
    "May 8, 2009 5:57:51 PM",
    "Mon Jan  2 15:04:05 2006",
    "Mon Jan  2 15:04:05 MST 2006",
    "Mon Jan 02 15:04:05 -0700 2006",
    "Monday, 02-Jan-06 15:04:05 MST",
    "Mon, 02 Jan 2006 15:04:05 MST",
    "Tue, 11 Jul 2017 16:28:13 +0200 (CEST)",
    "Mon, 02 Jan 2006 15:04:05 -0700",
    "Thu, 4 Jan 2018 17:53:36 +0000",
    "Mon Aug 10 15:44:11 UTC+0100 2015",
    "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)",
    "12 Feb 2006, 19:17",
    "12 Feb 2006 19:17",
    "03 February 2013",
    "2013-Feb-03",
    //   mm/dd/yy
    "3/31/2014",
    "03/31/2014",
    "08/21/71",
    "8/1/71",
    "4/8/2014 22:05",
    "04/08/2014 22:05",
    "4/8/14 22:05",
    "04/2/2014 03:00:51",
    "8/8/1965 12:00:00 AM",
    "8/8/1965 01:00:01 PM",
    "8/8/1965 01:00 PM",
    "8/8/1965 1:00 PM",
    "8/8/1965 12:00 AM",
    "4/02/2014 03:00:51",
    "03/19/2012 10:11:59",
    "03/19/2012 10:11:59.3186369",
    // yyyy/mm/dd
    "2014/3/31",
    "2014/03/31",
    "2014/4/8 22:05",
    "2014/04/08 22:05",
    "2014/04/2 03:00:51",
    "2014/4/02 03:00:51",
    "2012/03/19 10:11:59",
    "2012/03/19 10:11:59.3186369",
    // Chinese
    "2014年04月08日",
    //   yyyy-mm-ddThh
    "2006-01-02T15:04:05+0000",
    "2009-08-12T22:15:09-07:00",
    "2009-08-12T22:15:09",
    "2009-08-12T22:15:09Z",
    //   yyyy-mm-dd hh:mm:ss
    "2014-04-26 17:24:37.3186369",
    "2012-08-03 18:31:59.257000000",
    "2014-04-26 17:24:37.123",
    "2013-04-01 22:43",
    "2013-04-01 22:43:22",
    "2014-12-16 06:20:00 UTC",
    "2014-12-16 06:20:00 GMT",
    "2014-04-26 05:24:37 PM",
    "2014-04-26 13:13:43 +0800",
    "2014-04-26 13:13:44 +09:00",
    "2012-08-03 18:31:59.257000000 +0000 UTC",
    "2015-09-30 18:48:56.35272715 +0000 UTC",
    "2015-02-18 00:12:00 +0000 GMT",
    "2015-02-18 00:12:00 +0000 UTC",
    "2017-07-19 03:21:51+00:00",
    "2014-04-26",
    "2014-04",
    "2014",
    "2014-05-11 08:20:13,787",
    // mm.dd.yy
    "3.31.2014",
    "03.31.2014",
    "08.21.71",
    //  yyyymmdd and similar
    "20140601",
    // unix seconds, ms
    "1332151919",
    "1384216367189",
}

var (
    timezone = ""
)

func main() {
    flag.StringVar(&timezone, "timezone", "UTC", "Timezone aka `America/Los_Angeles` formatted time-zone")
    flag.Parse()

    if timezone != "" {
        // NOTE:  This is very, very important to understand
        // time-parsing in go
        loc, err := time.LoadLocation(timezone)
        if err != nil {
            panic(err.Error())
        }
        time.Local = loc
    }

    table := termtables.CreateTable()

    table.AddHeaders("Input", "Parsed, and Output as %v")
    for _, dateExample := range examples {
        t, err := dateparse.ParseLocal(dateExample)
        if err != nil {
            panic(err.Error())
        }
        table.AddRow(dateExample, fmt.Sprintf("%v", t))
    }
    fmt.Println(table.Render())
}
5
Steven Ferrer