Fix template function DateTime (#24317)

Before, 500 error


![image](https://user-images.githubusercontent.com/2114189/234170176-403ffd1b-ec27-42be-bff9-86184dc8d74d.png)
This commit is contained in:
wxiaoguang 2023-04-26 03:48:30 +08:00 committed by GitHub
parent 9219534447
commit 0e8045d8ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 140 additions and 60 deletions

View file

@ -7,19 +7,54 @@ import (
"fmt"
"html"
"html/template"
"time"
)
// DateTime renders an absolute time HTML given a time as a string
func DateTime(format, datetime, fallback string) template.HTML {
datetimeEscaped := html.EscapeString(datetime)
fallbackEscaped := html.EscapeString(fallback)
// DateTime renders an absolute time HTML element by datetime.
func DateTime(format string, datetime any) template.HTML {
if p, ok := datetime.(*time.Time); ok {
datetime = *p
}
if p, ok := datetime.(*TimeStamp); ok {
datetime = *p
}
switch v := datetime.(type) {
case TimeStamp:
datetime = v.AsTime()
case int:
datetime = TimeStamp(v).AsTime()
case int64:
datetime = TimeStamp(v).AsTime()
}
var datetimeEscaped, textEscaped string
switch v := datetime.(type) {
case nil:
return "N/A"
case string:
datetimeEscaped = html.EscapeString(v)
textEscaped = datetimeEscaped
case time.Time:
if v.IsZero() || v.Unix() == 0 {
return "N/A"
}
datetimeEscaped = html.EscapeString(v.Format(time.RFC3339))
if format == "full" {
textEscaped = html.EscapeString(v.Format("2006-01-02 15:04:05 -07:00"))
} else {
textEscaped = html.EscapeString(v.Format("2006-01-02"))
}
default:
panic(fmt.Sprintf("Unsupported time type %T", datetime))
}
switch format {
case "short":
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, fallbackEscaped))
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
case "long":
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="long" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, fallbackEscaped))
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="long" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
case "full":
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="%s">%s</relative-time>`, datetimeEscaped, fallbackEscaped))
return template.HTML(fmt.Sprintf(`<relative-time format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
}
return template.HTML("error in DateTime")
panic(fmt.Sprintf("Unsupported format %s", format))
}

View file

@ -0,0 +1,45 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package timeutil
import (
"testing"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
func TestDateTime(t *testing.T) {
oldTz := setting.DefaultUILocation
setting.DefaultUILocation, _ = time.LoadLocation("America/New_York")
defer func() {
setting.DefaultUILocation = oldTz
}()
refTimeStr := "2018-01-01T00:00:00Z"
refTime, _ := time.Parse(time.RFC3339, refTimeStr)
refTimeStamp := TimeStamp(refTime.Unix())
assert.EqualValues(t, "N/A", DateTime("short", nil))
assert.EqualValues(t, "N/A", DateTime("short", 0))
assert.EqualValues(t, "N/A", DateTime("short", time.Time{}))
assert.EqualValues(t, "N/A", DateTime("short", TimeStamp(0)))
actual := DateTime("short", "invalid")
assert.EqualValues(t, `<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="invalid">invalid</relative-time>`, actual)
actual = DateTime("short", refTimeStr)
assert.EqualValues(t, `<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</relative-time>`, actual)
actual = DateTime("short", refTime)
assert.EqualValues(t, `<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="2018-01-01T00:00:00Z">2018-01-01</relative-time>`, actual)
actual = DateTime("short", refTimeStamp)
assert.EqualValues(t, `<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="2017-12-31T19:00:00-05:00">2017-12-31</relative-time>`, actual)
actual = DateTime("full", refTimeStamp)
assert.EqualValues(t, `<relative-time format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual)
}

View file

@ -115,7 +115,7 @@ func timeSincePro(then, now time.Time, lang translation.Locale) string {
}
func timeSinceUnix(then, now time.Time, lang translation.Locale) template.HTML {
friendlyText := then.Format("2006-01-02 15:04:05 +07:00")
friendlyText := then.Format("2006-01-02 15:04:05 -07:00")
// document: https://github.com/github/relative-time-element
attrs := `tense="past"`