diff --git a/modules/timeutil/datetime.go b/modules/timeutil/datetime.go
index 02275bca0..80b96fa65 100644
--- a/modules/timeutil/datetime.go
+++ b/modules/timeutil/datetime.go
@@ -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(`%s`, datetimeEscaped, fallbackEscaped))
+ return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped))
case "long":
- return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, fallbackEscaped))
+ return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped))
case "full":
- return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, fallbackEscaped))
+ return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped))
}
- return template.HTML("error in DateTime")
+ panic(fmt.Sprintf("Unsupported format %s", format))
}
diff --git a/modules/timeutil/datetime_test.go b/modules/timeutil/datetime_test.go
new file mode 100644
index 000000000..a5639b34f
--- /dev/null
+++ b/modules/timeutil/datetime_test.go
@@ -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, `invalid`, actual)
+
+ actual = DateTime("short", refTimeStr)
+ assert.EqualValues(t, `2018-01-01T00:00:00Z`, actual)
+
+ actual = DateTime("short", refTime)
+ assert.EqualValues(t, `2018-01-01`, actual)
+
+ actual = DateTime("short", refTimeStamp)
+ assert.EqualValues(t, `2017-12-31`, actual)
+
+ actual = DateTime("full", refTimeStamp)
+ assert.EqualValues(t, `2017-12-31 19:00:00 -05:00`, actual)
+}
diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go
index 4aee814ec..04fcff54a 100644
--- a/modules/timeutil/since.go
+++ b/modules/timeutil/since.go
@@ -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"`
diff --git a/templates/admin/auth/list.tmpl b/templates/admin/auth/list.tmpl
index f8e15edde..c9f7c0d51 100644
--- a/templates/admin/auth/list.tmpl
+++ b/templates/admin/auth/list.tmpl
@@ -26,8 +26,8 @@
{{.Name}} |
{{.TypeName}} |
{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}} |
- {{DateTime "short" .UpdatedUnix.FormatLong .UpdatedUnix.FormatShort}} |
- {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} |
+ {{DateTime "short" .UpdatedUnix}} |
+ {{DateTime "short" .CreatedUnix}} |
{{svg "octicon-pencil"}} |
{{end}}
diff --git a/templates/admin/cron.tmpl b/templates/admin/cron.tmpl
index 5dd631494..267da0075 100644
--- a/templates/admin/cron.tmpl
+++ b/templates/admin/cron.tmpl
@@ -21,8 +21,8 @@
|
{{$.locale.Tr (printf "admin.dashboard.%s" .Name)}} |
{{.Spec}} |
- {{DateTime "full" (DateFmtLong .Next) (DateFmtLong .Next)}} |
- {{if gt .Prev.Year 1}}{{DateTime "full" (DateFmtLong .Prev) (DateFmtLong .Prev)}}{{else}}N/A{{end}} |
+ {{DateTime "full" (DateFmtLong .Next)}} |
+ {{if gt .Prev.Year 1}}{{DateTime "full" .Prev}}{{else}}N/A{{end}} |
{{.ExecTimes}} |
{{if eq .Status ""}}—{{else if eq .Status "finished"}}{{svg "octicon-check" 16}}{{else}}{{svg "octicon-x" 16}}{{end}} |
diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl
index 51b0c6850..bd6b74dd2 100644
--- a/templates/admin/notice.tmpl
+++ b/templates/admin/notice.tmpl
@@ -26,7 +26,7 @@
{{.ID}} |
{{$.locale.Tr .TrStr}} |
{{.Description}} |
- {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} |
+ {{DateTime "short" .CreatedUnix}} |
{{svg "octicon-note" 16 "view-detail"}} |
{{end}}
diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl
index 73435fdd3..a400dcbc8 100644
--- a/templates/admin/org/list.tmpl
+++ b/templates/admin/org/list.tmpl
@@ -41,7 +41,7 @@
{{.NumTeams}} |
{{.NumMembers}} |
{{.NumRepos}} |
- {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} |
+ {{DateTime "short" .CreatedUnix}} |
{{svg "octicon-pencil"}} |
{{end}}
diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl
index 2edcad4b7..f320878b8 100644
--- a/templates/admin/packages/list.tmpl
+++ b/templates/admin/packages/list.tmpl
@@ -65,7 +65,7 @@
{{end}}
{{FileSize .CalculateBlobSize}} |
- {{DateTime "short" .Version.CreatedUnix.FormatLong .Version.CreatedUnix.FormatShort}} |
+ {{DateTime "short" .Version.CreatedUnix}} |
{{svg "octicon-trash"}} |
{{end}}
diff --git a/templates/admin/queue.tmpl b/templates/admin/queue.tmpl
index d3052c91a..3de01a32a 100644
--- a/templates/admin/queue.tmpl
+++ b/templates/admin/queue.tmpl
@@ -155,8 +155,8 @@
{{range .Queue.Workers}}
{{.Workers}}{{if .IsFlusher}}{{svg "octicon-sync"}}{{end}} |
- {{DateTime "full" (DateFmtLong .Start) (DateFmtLong .Start)}} |
- {{if .HasTimeout}}{{DateTime "full" (DateFmtLong .Timeout) (DateFmtLong .Timeout)}}{{else}}-{{end}} |
+ {{DateTime "full" .Start}} |
+ {{if .HasTimeout}}{{DateTime "full" .Timeout}}{{else}}-{{end}} |
{{svg "octicon-trash"}}
|
diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl
index f9a0a6ef9..3d09f2de2 100644
--- a/templates/admin/repo/list.tmpl
+++ b/templates/admin/repo/list.tmpl
@@ -80,7 +80,7 @@
{{.NumForks}} |
{{.NumIssues}} |
{{FileSize .Size}} |
- {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} |
+ {{DateTime "short" .CreatedUnix}} |
{{svg "octicon-trash"}} |
{{end}}
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl
index fef7c7b27..2f76f2d3b 100644
--- a/templates/admin/user/list.tmpl
+++ b/templates/admin/user/list.tmpl
@@ -91,9 +91,9 @@
{{if .IsRestricted}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}} |
{{if index $.UsersTwoFaStatus .ID}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}} |
{{.NumRepos}} |
- {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} |
+ {{DateTime "short" .CreatedUnix}} |
{{if .LastLoginUnix}}
- {{DateTime "short" .LastLoginUnix.FormatLong .LastLoginUnix.FormatShort}} |
+ {{DateTime "short" .LastLoginUnix}} |
{{else}}
{{$.locale.Tr "admin.users.never_login"}} |
{{end}}
diff --git a/templates/explore/organizations.tmpl b/templates/explore/organizations.tmpl
index e61a72b6e..295818f94 100644
--- a/templates/explore/organizations.tmpl
+++ b/templates/explore/organizations.tmpl
@@ -23,7 +23,7 @@
{{svg "octicon-link"}}
{{.Website}}
{{end}}
- {{svg "octicon-clock"}} {{$.locale.Tr "user.join_on"}} {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}}
+ {{svg "octicon-clock"}} {{$.locale.Tr "user.join_on"}} {{DateTime "short" .CreatedUnix}}
diff --git a/templates/explore/users.tmpl b/templates/explore/users.tmpl
index 4cab94ee8..0c1ba2744 100644
--- a/templates/explore/users.tmpl
+++ b/templates/explore/users.tmpl
@@ -18,7 +18,7 @@
{{svg "octicon-mail"}}
{{.Email}}
{{end}}
- {{svg "octicon-clock"}} {{$.locale.Tr "user.join_on"}} {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}}
+ {{svg "octicon-clock"}} {{$.locale.Tr "user.join_on"}} {{DateTime "short" .CreatedUnix}}
diff --git a/templates/package/shared/cleanup_rules/preview.tmpl b/templates/package/shared/cleanup_rules/preview.tmpl
index ae1ce1b1d..5992ea60b 100644
--- a/templates/package/shared/cleanup_rules/preview.tmpl
+++ b/templates/package/shared/cleanup_rules/preview.tmpl
@@ -22,7 +22,7 @@
{{.Version.Version}} |
{{.Creator.Name}} |
{{FileSize .CalculateBlobSize}} |
- {{DateTime "short" .Version.CreatedUnix.FormatLong .Version.CreatedUnix.FormatShort}} |
+ {{DateTime "short" .Version.CreatedUnix}} |
{{else}}
diff --git a/templates/package/view.tmpl b/templates/package/view.tmpl
index 36b0e8a8b..3cb130851 100644
--- a/templates/package/view.tmpl
+++ b/templates/package/view.tmpl
@@ -86,7 +86,7 @@
{{range .LatestVersions}}
{{.Version}}
-
{{DateTime "short" (.CreatedUnix.FormatDate) (.CreatedUnix.FormatDate)}}
+
{{DateTime "short" .CreatedUnix}}
{{end}}
diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl
index 26734e304..9d15cec05 100644
--- a/templates/repo/activity.tmpl
+++ b/templates/repo/activity.tmpl
@@ -2,7 +2,7 @@
{{template "repo/header" .}}
-
{{else if eq .Type 19}}
diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl
index 248fc71b0..fad0aadaf 100644
--- a/templates/repo/issue/view_content/sidebar.tmpl
+++ b/templates/repo/issue/view_content/sidebar.tmpl
@@ -385,7 +385,7 @@
{{svg "octicon-calendar" 16 "gt-mr-3"}}
- {{DateTime "long" .Issue.DeadlineUnix.FormatDate .Issue.DeadlineUnix.FormatDate}}
+ {{DateTime "long" .Issue.DeadlineUnix}}
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
diff --git a/templates/repo/settings/deploy_keys.tmpl b/templates/repo/settings/deploy_keys.tmpl
index caf049acd..1a0f8f826 100644
--- a/templates/repo/settings/deploy_keys.tmpl
+++ b/templates/repo/settings/deploy_keys.tmpl
@@ -60,7 +60,7 @@
{{.Fingerprint}}
- {{$.locale.Tr "settings.add_on"}} {{DateTime "short" .CreatedUnix.FormatLong .CreatedUnix.FormatShort}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix.FormatLong .UpdatedUnix.FormatShort}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} - {{$.locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{$.locale.Tr "settings.can_write_info"}} {{end}}
+ {{$.locale.Tr "settings.add_on"}} {{DateTime "short" .CreatedUnix}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix.FormatLong .UpdatedUnix.FormatShort}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} - {{$.locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{$.locale.Tr "settings.can_write_info"}} {{end}}
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index a974401e8..515854609 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -89,7 +89,7 @@
{{(MirrorRemoteAddress $.Context .Repository .Mirror.GetRemoteName false).Address}} |
{{$.locale.Tr "repo.settings.mirror_settings.direction.pull"}} |
- {{DateTime "full" .Mirror.UpdatedUnix.FormatLong .Mirror.UpdatedUnix.AsTime}} |
+ {{DateTime "full" .Mirror.UpdatedUnix}} |
|