Skip to content

Commit

Permalink
fix: dates inconsistent across site
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgoff committed Dec 10, 2024
1 parent 1d7f28e commit b20f6b7
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 83 deletions.
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 = (
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

0 comments on commit b20f6b7

Please sign in to comment.