Выполнение форматированного времени в срезе с помощью html/template

Я делаю этот простой веб-сервер, который может разместить мой блог, но что бы я ни делал; Я не могу выполнить правильное форматированное время в моем html/template.

Вот что я делаю:

Я создал эту структуру:

type Blogpost struct {
    Title   string
    Content string
    Date    time.Time
}

Далее я создал эту небольшую функциональность, которая извлекает блогпосты с соответствующими заголовками/датами из хранилища Appengine Datastore и возвращает это как срез:

func GetBlogs(r *http.Request, max int) []Blogpost {
    c := appengine.NewContext(r)
    q := datastore.NewQuery("Blogpost").Order("-Date").Limit(max)
    bp := make([]Blogpost, 0, max)
    q.GetAll(c, &bp)
    return bp
}

Наконец, в blogHandler я создаю срез на основе извлеченных данных из хранилища данных Appengine, используя:

blogs := GetBlogs(r, 10)

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

blog.Execute(w, blogs) // gives dates like: 2013-09-03 16:06:48 +0000 UTC

Итак, я, будучи Golang n00b, который я есть, сказал бы, что такая функция, как следующая, даст мне результат, который я хочу

blogs[0].Date = blogs[0].Date.Format("02-01-2006 15:04:05") // Would return like 03-09-2013 16:06:48, at least when you print the formatted date that is.

Однако это приводит к конфликту типа, который я пытался решить, используя:

blogs[0].Date, _ = time.Parse("02-01-2006 15:04:05", blogs[0].Date.Format("02-01-2006 15:04:05")) // returns once again: 2013-09-03 16:06:48 +0000 UTC

Вероятно, что-то вроде n00b, которое я наблюдал еще раз, но я просто не могу понять, как я не могу переопределить время. Time Type в фрагменте или, по крайней мере, печатать его в том формате, который я хочу.

Ответ 1

В поле Date есть тип time.Time. Если вы отформатируете его как строку и проанализируете его, вы снова получите значение time.Time, которое по-прежнему будет печатать по умолчанию, когда выполнение шаблона вызывает его метод String, поэтому он не решает вашу проблему.

Способом его решения является предоставление шаблона самой форматированной временной строкой вместо значения времени, и вы можете сделать это несколькими способами. Например:

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

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

  • Если вы хотите форматировать значения времени несколькими способами в шаблоне, вы также можете выбрать функцию шаблона шаблона, чтобы вы могли сделать что-то вроде {{post.Date | fdate "02-01-2006 15:04:05"}}. Смотрите документацию Template.Funcs, тип FuncMap и этот пример для получения подробной информации о том, как это сделать.

Обновление: Пример кода для первого варианта: http://play.golang.org/p/3QYdrDQ1YO

Ответ 2

В то время как я ищу аналогичную функциональность, чтобы просто форматировать и отображать тип time.Time в html/template, я случайно обнаружил, что шаблонный анализатор шаблонов позволяет вызывать методы в определенных ограничения при рендеринге типа time.Time.

Например:

type Post struct {
    Id        int
    Title     string
    CreatedOn time.Time
}

// post is a &Post. in my case, I fetched that from a postgresql
// table which has a datetime column for that field and
// value in db is 2015-04-04 20:51:48

template.Execute(w, post)

и можно использовать это время в шаблоне, как показано ниже:

<span>{{ .CreatedOn }}</span>
<!-- Outputs: 2015-04-04 20:51:48 +0000 +0000 -->

<span>{{ .CreatedOn.Format "2006 Jan 02" }}</span>
<!-- Outputs: 2015 Apr 04 -->

<span>{{ .CreatedOn.Format "Jan 02, 2006" }}</span>
<!-- Outputs: Apr 04, 2015 -->

<span>{{.CreatedOn.Format "Jan 02, 2006 15:04:05 UTC" }}</span>
<!-- Outputs: Apr 04, 2015 20:51:48 UTC -->

В качестве примечания; моя версия go go1.4.2 darwin/amd64

Надеюсь, что это поможет другим.

Ответ 3

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

  • Добавить строковое поле FormatedDate в ваш Blogpost и заполнить его из Date с помощью Date.Format(независимо)
  • Запишите и зарегистрируйте фильтр форматирования `в вашем шаблоне (см. http://golang.org/pkg/html/template/#Template.Funcs) и используйте это.