Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dates inconsistent across site #632

Merged
merged 1 commit into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions components/EventTime/patterns/EventTimeLong.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from "prop-types";
import { useDateString, useTimeString, useTimeZone } from "@/lib/utils";
import { useTimeString, useTimeZone } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";

export default function EventTimeLong({
startDate,
Expand All @@ -9,9 +10,9 @@ export default function EventTimeLong({
timezone,
isSameDay,
}) {
const localizedStartDate = useDateString(startDate);
const localizedStartDate = makeDateString(startDate);
const localizedStartTime = useTimeString(startTime);
const localizedEndDate = useDateString(endDate);
const localizedEndDate = makeDateString(endDate);
const localizedEndTime = useTimeString(endTime);
const localizedTimezone = useTimeZone(timezone);

Expand Down
9 changes: 5 additions & 4 deletions components/EventTime/patterns/EventTimeShort/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from "prop-types";
import { makeDateObject, useGlobalData } from "@/lib/utils";
import { useGlobalData } from "@/lib/utils";
import { makeDateObject } from "@/helpers/dates";
import * as Styled from "./styles";
import { fallbackLng } from "@/lib/i18n/settings";

Expand All @@ -15,10 +16,10 @@ function renderShortDate({ month, day, year }) {

export default function EventTimeShort({ startDate, endDate, isSameDay }) {
const localeInfo = useGlobalData("localeInfo");
const lang = localeInfo?.language || fallbackLng;
const endDateObject = makeDateObject(endDate, lang, true);
const locale = localeInfo?.language || fallbackLng;
const endDateObject = makeDateObject(endDate, { locale, isShort: true });
const startDateObject = !isSameDay
? makeDateObject(startDate, lang, true)
? makeDateObject(startDate, { locale, isShort: true })
: null;

return (
Expand Down
13 changes: 7 additions & 6 deletions components/content-blocks/Callout/CalloutEntry/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@

import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { makeDateString, getSiteString, makeReleaseFeature } from "@/lib/utils";
import { getSiteString, makeReleaseFeature } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";
import * as Styled from "./styles";
import { Image } from "@rubin-epo/epo-react-lib";
import { useRelease } from "@/lib/api/noirlabReleases";
import { fallbackLng } from "@/lib/i18n/settings";

const getDateString = (newsDate, eventStart, eventEnd, lang) => {
const getDateString = (newsDate, eventStart, eventEnd, locale) => {
if (newsDate) {
return makeDateString(newsDate, lang);
return makeDateString(newsDate, { locale });
}

if (eventStart && eventEnd) {
return `${makeDateString(eventStart, lang)} - ${makeDateString(
return `${makeDateString(eventStart, { locale })} - ${makeDateString(
eventEnd,
lang
{ locale }
)}`;
}

if (eventEnd) {
return makeDateString(eventEnd, lang);
return makeDateString(eventEnd, { locale });
}
};

Expand Down
7 changes: 4 additions & 3 deletions components/content-blocks/GridBlock/NewsGrid.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import {
makeDateString,
makeTruncatedString,
makeReleaseFeature,
normalizeItemData,
useGlobalData,
useList,
} from "@/lib/utils";

import { makeDateString } from "@/helpers/dates";
import { Grid } from "@rubin-epo/epo-react-lib";
import Tile from "@/atomic/Tile";
import Loader from "@/atomic/Loader";
Expand All @@ -16,7 +17,7 @@ import { fallbackLng } from "@/lib/i18n/settings";
const NewsGrid = ({ items = [], limit, listTypeId, sectionHandle, pageId }) => {
const { t } = useTranslation();
const localeInfo = useGlobalData("localeInfo");
const lang = localeInfo?.language || fallbackLng;
const locale = localeInfo?.language || fallbackLng;
// get manually-curated data first
let allItems = normalizeItemData(items);

Expand Down Expand Up @@ -70,7 +71,7 @@ const NewsGrid = ({ items = [], limit, listTypeId, sectionHandle, pageId }) => {
isFeature={i === 0}
link={uri}
pretitle={postType?.[0]?.title ? postType[0].title : " "}
subtitle={makeDateString(date || releaseDate, lang)}
subtitle={makeDateString(date || releaseDate, { locale })}
text={makeTruncatedString(subtitle || description, 30)}
title={title}
type="news"
Expand Down
2 changes: 1 addition & 1 deletion components/content-blocks/PublicationsList/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import PropTypes from "prop-types";
import { Container } from "@rubin-epo/epo-react-lib";
import { mixedLinkShape } from "@/shapes/link";
import { makeDateString } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";
import * as Styled from "./styles";

export default function PublicationsListBlock({
Expand Down
4 changes: 2 additions & 2 deletions components/content-blocks/Schedule/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import PropTypes from "prop-types";
import styled from "styled-components";
import { Container } from "@rubin-epo/epo-react-lib";
import { useDateString } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";

export default function ScheduleBlock({ date, description, scheduleRows }) {
const localizedDate = useDateString(date);
const localizedDate = makeDateString(date);
return (
<Container>
<Date>{localizedDate}</Date>
Expand Down
6 changes: 3 additions & 3 deletions components/dynamic/NewsList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Grid } from "@rubin-epo/epo-react-lib";
import DataList from "@/dynamic/DataList";
import Tile from "@/atomic/Tile";
import {
makeDateString,
makeTruncatedString,
makeReleaseFeature,
useGlobalData,
} from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";
import { fallbackLng } from "@/lib/i18n/settings";

const NewsList = ({
Expand All @@ -23,7 +23,7 @@ const NewsList = ({
}) => {
const { t } = useTranslation();
const localeInfo = useGlobalData("localeInfo");
const lang = localeInfo?.language || fallbackLng;
const locale = localeInfo?.language || fallbackLng;
const cols = initialLimit === 4 ? 4 : initialLimit === 3 ? 3 : 2;
const canShowFeatured = initialLimit > 4;

Expand Down Expand Up @@ -84,7 +84,7 @@ const NewsList = ({
? postType[0].title
: null
}
subtitle={makeDateString(date || releaseDate, lang)}
subtitle={makeDateString(date || releaseDate, { locale })}
text={makeTruncatedString(description || subtitle, 30)}
title={title}
titleTag={"h2"}
Expand Down
7 changes: 4 additions & 3 deletions components/dynamic/SearchList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { useTranslation } from "react-i18next";
import {
makeBreadcrumbs,
makeCustomBreadcrumbs,
makeDateString,
makeTruncatedString,
useGlobalData,
} from "@/lib/utils";

import { makeDateString } from "@/helpers/dates";
import Breadcrumbs from "@/components/page/Breadcrumbs";
import { Grid } from "@rubin-epo/epo-react-lib";
import DataList from "@/dynamic/DataList";
Expand All @@ -25,7 +26,7 @@ const SearchList = ({
const { t } = useTranslation();
const localeInfo = useGlobalData("localeInfo");
const rootPages = useGlobalData("rootPages");
const lang = localeInfo?.language || fallbackLng;
const locale = localeInfo?.language || fallbackLng;

const makePretitle = (entry) => {
if (entry.eventType) {
Expand Down Expand Up @@ -79,7 +80,7 @@ const SearchList = ({
<div>{type ? `${type} ` : ``}</div>
<div>
{entry.date
? `${t("published")} ${makeDateString(entry.date, lang)}`
? `${t("published")} ${makeDateString(entry.date, { locale })}`
: ``}
</div>
</Styled.PretitleContainer>
Expand Down
3 changes: 2 additions & 1 deletion components/templates/HomePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { useTranslation } from "react-i18next";
import ContentBlockFactory from "@/factories/ContentBlockFactory";
import Hero from "@/components/molecules/Hero";
import { Buttonish, MixedLink } from "@rubin-epo/epo-react-lib";
import { makeDateString, makeTruncatedString } from "@/lib/utils";
import { makeTruncatedString } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";
import { SlideBlock } from "@/components/content-blocks";
import Tabs from "@/components/layout/Tabs";
import TempList from "@/components/dynamic/TempList";
Expand Down
10 changes: 7 additions & 3 deletions components/templates/NewsPage/NewsArticle.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"use client";
import PropTypes from "prop-types";
import Link from "next/link";
import { useTranslation } from "react-i18next";
import useResizeObserver from "use-resize-observer";
import { useDateString } from "@/lib/utils";
import { makeDateString } from "@/helpers/dates";
import ContentBlockFactory from "@/factories/ContentBlockFactory";
import { Container } from "@rubin-epo/epo-react-lib";
import { Share } from "@/content-blocks";
Expand All @@ -27,8 +28,11 @@ export default function NewsArticle({ data }) {
releaseUrl,
} = data;

const { t } = useTranslation();
const localizedDate = useDateString(date);
const {
t,
i18n: { resolvedLanguage },
} = useTranslation();
const localizedDate = makeDateString(date, { locale: resolvedLanguage });
const { ref } = useResizeObserver({
box: "border-box",
onResize: ({ height }) => {
Expand Down
72 changes: 72 additions & 0 deletions helpers/dates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { fallbackLng } from "@/lib/i18n/settings";

const normalizeCraftDate = (date: Date) => {
date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
};

interface DateStringOptions {
locale?: string;
isShort?: boolean;
isCraftDate?: boolean;
}

export const makeDateString = (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combination of existing makeDateString and useDateString

date: string,
options: DateStringOptions = {}
) => {
const { isShort = false, isCraftDate = true, locale = fallbackLng } = options;
const newDate = new Date(date);

/**
* Craft dates are stored in UTC with the timezone applied as an hours offset
* The user's timezone offset needs to be removed to restore the original date
*
* https://craftcms.com/docs/4.x/time-fields.html#converting-from-a-date-field
*/
if (isCraftDate) {
normalizeCraftDate(newDate);
}
const localeOptions: Intl.DateTimeFormatOptions = {
year: "numeric",
month: isShort ? "short" : "long",
day: "numeric",
};
let dateString = newDate.toLocaleString(locale, localeOptions);
isShort && (dateString = dateString.replace(",", ""));

return dateString;
};

export const makeDateObject = (
date: string,
options: DateStringOptions = {}
): Record<string, string> | undefined => {
if (!date) return;
const { isShort = false, isCraftDate = true, locale = fallbackLng } = options;
const newDate = new Date(date);

/**
* Craft dates are stored in UTC with the timezone applied as an hours offset
* The user's timezone offset needs to be removed to restore the original date
*
* https://craftcms.com/docs/4.x/time-fields.html#converting-from-a-date-field
*/
if (isCraftDate) {
normalizeCraftDate(newDate);
}

const localeOptions: Intl.DateTimeFormatOptions = {
year: "numeric",
month: isShort ? "short" : "long",
day: "numeric",
};

return new Intl.DateTimeFormat(locale, localeOptions)
.formatToParts(newDate)
.filter(({ type }) => type !== "literal")
.reduce((prev, { type, value }) => {
prev[type] = value;

return prev;
}, {});
};
54 changes: 0 additions & 54 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,34 +179,6 @@ function dateWoTimezone(iso) {
return new Date(iso.slice(0, -6));
}

export const useDateString = (date, options = {}) => {
const { isShort = false, isCraftDate = true } = options;
const localeInfo = useGlobalData("localeInfo");
const locale = localeInfo.language || fallbackLng;
const newDate = new Date(date);

/**
* Craft dates are stored in UTC with the timezone applied as an hours offset
* The user's timezone offset needs to be removed to restore the original date
*
* https://craftcms.com/docs/4.x/time-fields.html#converting-from-a-date-field
*/
if (isCraftDate) {
newDate.setTime(
newDate.getTime() + newDate.getTimezoneOffset() * 60 * 1000
);
}
const localeOptions = {
year: "numeric",
month: isShort ? "short" : "long",
day: "numeric",
};
let dateString = newDate.toLocaleString(locale, localeOptions);
isShort && (dateString = dateString.replace(",", ""));

return dateString;
};

export const useTimeString = (iso) => {
const localeInfo = useGlobalData("localeInfo");
const locale = localeInfo.language || fallbackLng;
Expand Down Expand Up @@ -283,32 +255,6 @@ export const makeCustomBreadcrumbs = (rootPages, rootPageString) => {
return customBreadcrumbs.flat(1);
};

export const makeDateString = (date, locale = fallbackLng, isShort = false) => {
const newDate = new Date(date);
const options = {
year: "numeric",
month: `${isShort ? "short" : "long"}`,
day: "numeric",
};
let dateString = newDate.toLocaleString(locale, options);
isShort && (dateString = dateString.replace(",", ""));
return dateString;
};

export const makeDateObject = (date, locale = fallbackLng, isShort = false) => {
if (!date) return;
const newDate = new Date(date);
const options = {
month: `${isShort ? "short" : "long"}`,
};
const dateObject = {
year: newDate.getFullYear(),
month: new Intl.DateTimeFormat(locale, options).format(newDate),
day: newDate.getDate(),
};
return dateObject;
};

export const checkIfBetweenDates = (startDate, endDate) => {
if (!startDate || !endDate) {
return true;
Expand Down