使用html/template在切片中执行格式化的时间

Dan*_*ani 12 google-app-engine go

我正在制作这个简单的网络服务器,可以托管我的博客,但无论我做什么; 我无法在我的html /模板中执行正确的格式化时间.

这是我做的:

我创建了这个结构:

type Blogpost struct {
    Title   string
    Content string
    Date    time.Time
}
Run Code Online (Sandbox Code Playgroud)

接下来我创建了这个小函数,它从Appengine数据存储区中检索具有相应标题/日期的博客帖子并将其作为切片返回:

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
}
Run Code Online (Sandbox Code Playgroud)

最后,在blogHandler中,我使用以下方法根据从Appengine数据存储中检索到的数据创建一个切片:

blogs := GetBlogs(r, 10)
Run Code Online (Sandbox Code Playgroud)

现在当我执行这样名为博客的模板时,博客的日期将被解析为默认日期:

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

所以,我,作为我的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.
Run Code Online (Sandbox Code Playgroud)

然而,这会导致类型冲突,我尝试使用以下方法解决:

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
Run Code Online (Sandbox Code Playgroud)

这可能是我再次监督的一些n00b的事情,但我只是看不出我怎么不能覆盖时间.时间类型切片或至少以我想要的格式打印它.

edi*_*igu 46

当我寻找类似的功能来简单地格式化并渲染a中的time.Time类型时html/template,我偶然发现go的模板解析器允许在渲染类型时在某些限制下调用方法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)
Run Code Online (Sandbox Code Playgroud)

并且可以在下面的模板中使用该时间:

<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 -->
Run Code Online (Sandbox Code Playgroud)

作为一个笔记; 我去的版本是go1.4.2 darwin/amd64

希望它能帮助别人.

  • 作为一个 Go 新手,这对我来说并不明显。注意 `Mon Jan 2 15:04:05 MST 2006` 是 Go 时间格式的特殊字符串值。通过重新排列确切的日期值作为格式参数,您可以获得各种日期格式。然后,您的日期将以这种方式格式化,例如,如果今天是 2019 年 12 月 15 日,并且您使用格式字符串“01/02/2006”,则结果字符串将为“12/15/2019”。同样,如果您使用格式字符串“Jan 2, 2006”,则结果字符串将为“Dec 15, 2019” https://golang.org/pkg/time/#pkg-constants (3认同)

Gus*_*yer 29

你的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认同)
  • 在这三个选项的最后一个中,您无需定义自定义函数`fdate`。模板管道可以包含方法调用,因此您可以编写“ {{post.Date.Format“ 02-01-2006”}}` (2认同)