From 11a1e492922a0b4e89c6b0c5c76df8c66052da00 Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:13:01 +1100 Subject: [PATCH] Remove timezone from package date format (#4313) * Use UTC date for manifest * Use intl to format package dates --- pkg/pkg/pkg.go | 25 ++++++++++++++--- .../Shared/PackageManager/PackageManager.tsx | 27 ++++++++++++++----- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/pkg/pkg/pkg.go b/pkg/pkg/pkg.go index 5bd27b404..570f42f5b 100644 --- a/pkg/pkg/pkg.go +++ b/pkg/pkg/pkg.go @@ -8,8 +8,16 @@ import ( "github.com/stashapp/stash/pkg/sliceutil" ) -const timeFormat = "2006-01-02 15:04:05 -0700" +const ( + // TimeFormat is the format used for marshalling/unmarshalling time.Time. + // Times are stored in UTC. + TimeFormat = "2006-01-02 15:04:05" + // timeFormatLegacy is the old format that may exist in some manifests. + timeFormatLegacy = "2006-01-02 15:04:05 -0700" +) + +// Time is a wrapper around time.Time that allows for custom YAML marshalling/unmarshalling using TimeFormat. type Time struct { time.Time } @@ -19,16 +27,25 @@ func (t *Time) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal(&s); err != nil { return err } - parsed, err := time.Parse(timeFormat, s) + + // times are stored in UTC + parsed, err := time.Parse(TimeFormat, s) if err != nil { - return err + // try to parse using the legacy format + var legacyErr error + parsed, legacyErr = time.Parse(timeFormatLegacy, s) + + if legacyErr != nil { + // if we can't parse using the legacy format, return the original error + return err + } } t.Time = parsed return nil } func (t Time) MarshalYAML() (interface{}, error) { - return t.Format(timeFormat), nil + return t.Format(TimeFormat), nil } type PackageMetadata map[string]interface{} diff --git a/ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx b/ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx index 9a41b6747..5bd6d4a67 100644 --- a/ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx +++ b/ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx @@ -1,6 +1,6 @@ import { Button, Form, Table } from "react-bootstrap"; import React, { useState, useMemo, useEffect } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; +import { FormattedMessage, IntlShape, useIntl } from "react-intl"; import * as GQL from "src/core/generated-graphql"; import { Icon } from "../Icon"; import { @@ -17,10 +17,19 @@ import { LoadingIndicator } from "../LoadingIndicator"; import { ApolloError } from "@apollo/client"; import { ClearableInput } from "../ClearableInput"; -function formatDate(date: string | undefined | null) { +function formatDate(intl: IntlShape, date: string | undefined | null) { if (!date) return; - return new Date(date).toISOString(); + const d = new Date(date); + + return `${intl.formatDate(d, { + timeZone: "utc", + })} ${intl.formatTime(d, { + timeZone: "utc", + hour: "numeric", + minute: "numeric", + second: "numeric", + })}`; } interface IPackage { @@ -48,6 +57,8 @@ const InstalledPackageRow: React.FC<{ togglePackage: () => void; updatesLoaded: boolean; }> = ({ loading, pkg, selected, togglePackage, updatesLoaded }) => { + const intl = useIntl(); + function rowClassname() { if (pkg.upgrade?.version) { return "package-update-available"; @@ -69,12 +80,14 @@ const InstalledPackageRow: React.FC<{ {pkg.version} - {formatDate(pkg.date)} + {formatDate(intl, pkg.date)} {updatesLoaded ? ( {pkg.upgrade?.version} - {formatDate(pkg.upgrade?.date)} + + {formatDate(intl, pkg.upgrade?.date)} + ) : undefined} @@ -523,6 +536,8 @@ const AvailablePackageRow: React.FC<{ togglePackage, renderDescription = () => undefined, }) => { + const intl = useIntl(); + function renderRequiredBy() { if (!requiredBy.length) return; @@ -551,7 +566,7 @@ const AvailablePackageRow: React.FC<{ {pkg.version} - {formatDate(pkg.date)} + {formatDate(intl, pkg.date)} {renderRequiredBy()}