2014-09-15 2 views
52

Я пробовал синтаксический анализ строки даты «2014-09-12T11: 45: 26.371Z» в go lang.Синхронизация строки даты в golang

Код

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

время разбора "2014-11-12T11: 47: 39.489Z": месяц из диапазона

Я получил эту ошибку.

Как разобрать эту строку даты?

+0

Для будущих читателей, я написал несколько упражнений для занятий разбор дат https://github.com/soniah/date_practice –

ответ

68

Используйте точные номера макетов, описанные here, и хороший блог-блог here.

так:

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) 

дает:

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

Я знаю. Умение ошеломляет. Также поймал меня в первый раз. Go просто не использует абстрактный синтаксис для компонентов datetime (YYYY-MM-DD), но эти точные числа ( Я думаю, что время первого совершения go Нет, согласно this. Кто-нибудь знает?).

+34

макета номера? Какие? Зачем? Argh! – Fuser97381

+9

@ Fuser97381 Поделитесь своими агониями ... – RickyA

+0

такой же здесь ... и null! строка с нулем неприемлема. –

47

Схема, которую следует использовать, действительно «2006-01-02T15:04:05.000Z», описанная в RickyA's answer.
Это не «время первого совершения перехода», а скорее мнемонический способ запомнить упомянутый макет.
См pkg/time:

опорного времени, используемый в макетах является:

Mon Jan 2 15:04:05 MST 2006 

который является Unix-время 1136239445.
С MST является GMT-0700, начало отсчета времени можно рассматривать как

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

(1,2,3,4,5,6,7, если вы помните, что 1 находится за месяц , и 2 за день, что не так просто для такого европейца, как я, используется для формата даты в день)

Как показано на «time.parse : why does golang parses the time incorrectly?», этот макет (с использованием 1,2,3,4,5 , 6,7) должно быть соблюдено точно.

+0

Ницца, спасибо за это объяснение. – RickyA

+0

Да, это тоже захватывает австралийцев! MM/DD просто не вычисляет для меня, и я должен продолжать смотреть на него. –

+2

@SimonWhitehead Согласен. По крайней мере, как только я посмотрю, я знаю, что означают YY, MM, DD, hh, mm, ss, и я могу легко их переупорядочить. С Go, даже после поиска, мне нужно помнить, что стоят 1, 2, 3, 4 .... – VonC

10

Как указано, но чтобы сохранить ввод "2006-01-02T15:04:05.000Z" для макета, вы можете использовать постоянную упаковку 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

+1

Кроме того, если вы посмотрите на константы пакета (связанные в ответе выше), существует множество других распространенных форматов, которые могут быть использованы. Если вам нужно что-то немного другое, используйте их в качестве отправной точки. – Hugh

+0

Этот и несколько ответов рекомендуют '2006-01-02T15: 04: 05.000Z' и упомянуть, что Go' time.RFC3339' также будет работать. Но 'time.RFC3339 =" 2006-01-02T15: 04: 05Z07: 00 ". Являются ли эти два формата в точности эквивалентными, поскольку будут выполняться 'time.Parse' и' time.ParseInLocation'? – Miles

+1

Правильно @Miles, этот тест подтверждает это https://play.golang.org/p/T3dW1kTeAHl – robstarbuck

1

Это может быть очень поздно, но это для людей, которые могли бы наткнуться на этой проблеме и, возможно, захотите использовать внешний пакет для разбора строки даты.

Я пытался ищу библиотеки, и я это нашел:

https://github.com/araddon/dateparse

Пример из 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()) 
} 
+1

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки , Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/18671993) – talves

+0

Привет @talves, я обновил ответ, чтобы включить пример кода из readme пакета. благодаря! – srf

0

Я предлагаю использовать time.RFC3339 постоянная от времени пакета , Вы можете проверить другие константы из временного пакета. 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); 
} 
Смежные вопросы