date formatter in a single file

This commit is contained in:
m5r 2021-08-30 23:19:33 +08:00
parent 5e0c2ae643
commit 4bc24f5395
7 changed files with 67 additions and 60 deletions

View File

@ -1,10 +1,6 @@
const formatter = Intl.DateTimeFormat("en-US", { import { formatDate } from "../../core/helpers/date-formatter";
day: "2-digit",
month: "short",
year: "numeric",
});
export default function DateComponent({ dateString }: any) { export default function DateComponent({ dateString }: any) {
const date = new Date(dateString); const date = new Date(dateString);
return <time dateTime={dateString}>{formatter.format(date)}</time>; return <time dateTime={dateString}>{formatDate(date)}</time>;
} }

View File

@ -1,17 +1,14 @@
import { Link, Routes } from "blitz"; import { Link, Routes } from "blitz";
import PostPreview from "./post-preview";
import type { Post } from "../../../integrations/datocms"; import type { Post } from "../../../integrations/datocms";
import { formatDate } from "../../core/helpers/date-formatter";
import PostPreview from "./post-preview";
type Props = { type Props = {
posts: Post[]; posts: Post[];
}; };
const formatter = Intl.DateTimeFormat("en-US", {
day: "2-digit",
month: "short",
year: "numeric",
});
export default function MoreStories({ posts }: Props) { export default function MoreStories({ posts }: Props) {
return ( return (
<aside> <aside>
@ -46,9 +43,7 @@ export default function MoreStories({ posts }: Props) {
</h3> </h3>
</a> </a>
</Link> </Link>
<div className="text-sm opacity-80"> <div className="text-sm opacity-80">{formatDate(new Date(post.date))}</div>
{formatter.format(new Date(post.date))}
</div>
</header> </header>
<footer> <footer>
{/* Author meta */} {/* Author meta */}

View File

@ -1,9 +1,11 @@
import type { BlitzPage, GetStaticPaths, GetStaticProps } from "blitz"; import type { BlitzPage, GetStaticPaths, GetStaticProps } from "blitz";
import { Head, useRouter } from "blitz"; import { useRouter } from "blitz";
import ErrorPage from "next/error"; import ErrorPage from "next/error";
import type { Post } from "integrations/datocms"; import type { Post } from "integrations/datocms";
import { getAllPostsWithSlug, getPostAndMorePosts, markdownToHtml } from "integrations/datocms"; import { getAllPostsWithSlug, getPostAndMorePosts, markdownToHtml } from "integrations/datocms";
import { formatDate } from "../../../core/helpers/date-formatter";
import Header from "../../../public-area/components/header"; import Header from "../../../public-area/components/header";
import PostBody from "../../components/post-body"; import PostBody from "../../components/post-body";
import SectionSeparator from "../../components/section-separator"; import SectionSeparator from "../../components/section-separator";
@ -15,12 +17,6 @@ type Props = {
preview: boolean; preview: boolean;
}; };
const formatter = Intl.DateTimeFormat("en-US", {
day: "2-digit",
month: "short",
year: "numeric",
});
const PostPage: BlitzPage<Props> = ({ post, morePosts, preview }) => { const PostPage: BlitzPage<Props> = ({ post, morePosts, preview }) => {
const router = useRouter(); const router = useRouter();
if (!router.isFallback && !post?.slug) { if (!router.isFallback && !post?.slug) {
@ -81,7 +77,7 @@ const PostPage: BlitzPage<Props> = ({ post, morePosts, preview }) => {
</a> </a>
<span className="text-gray-600 dark:text-gray-400"> <span className="text-gray-600 dark:text-gray-400">
{" "} {" "}
· {formatter.format(new Date(post.date))} · {formatDate(new Date(post.date))}
</span> </span>
</div> </div>
</div> </div>

View File

@ -0,0 +1,48 @@
import { DateTime } from "luxon";
export function formatDate(date: Date, config?: Intl.DateTimeFormatOptions): string {
const dateFormatter = Intl.DateTimeFormat(
"en-US",
config ?? {
day: "2-digit",
month: "short",
year: "numeric",
},
);
return dateFormatter.format(date);
}
export function formatTime(date: Date, config?: Intl.DateTimeFormatOptions): string {
const timeFormatter = Intl.DateTimeFormat(
"en-US",
config ?? {
hour: "2-digit",
minute: "2-digit",
},
);
return timeFormatter.format(date);
}
export function formatRelativeDate(date: Date): string {
const dateTime = DateTime.fromJSDate(date);
const diff = dateTime.diffNow("days");
const isToday = diff.days >= -1;
if (isToday) {
return dateTime.toFormat("HH:mm", { locale: "en-US" });
}
const isYesterday = diff.days >= -2;
if (isYesterday) {
return "Yesterday";
}
const isDuringLastWeek = diff.days >= -7;
if (isDuringLastWeek) {
return dateTime.weekdayLong;
}
return dateTime.toFormat("dd/MM/yyyy", { locale: "en-US" });
}

View File

@ -5,6 +5,7 @@ import clsx from "clsx";
import { Direction } from "../../../db"; import { Direction } from "../../../db";
import useConversation from "../hooks/use-conversation"; import useConversation from "../hooks/use-conversation";
import NewMessageArea from "./new-message-area"; import NewMessageArea from "./new-message-area";
import { formatDate, formatTime } from "../../core/helpers/date-formatter";
export default function Conversation() { export default function Conversation() {
const router = useRouter(); const router = useRouter();
@ -42,18 +43,13 @@ export default function Conversation() {
{(!isPreviousMessageFromSameSender || !shouldGroupMessages) && ( {(!isPreviousMessageFromSameSender || !shouldGroupMessages) && (
<div className="flex py-2 space-x-1 text-xs justify-center"> <div className="flex py-2 space-x-1 text-xs justify-center">
<strong> <strong>
{new Date(message.sentAt).toLocaleDateString("en-US", { {formatDate(new Date(message.sentAt), {
weekday: "long", weekday: "long",
day: "2-digit", day: "2-digit",
month: "short", month: "short",
})} })}
</strong> </strong>
<span> <span>{formatTime(new Date(message.sentAt))}</span>
{new Date(message.sentAt).toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
})}
</span>
</div> </div>
)} )}

View File

@ -1,9 +1,9 @@
import { Link, useQuery, Routes } from "blitz"; import { Link, useQuery, Routes } from "blitz";
import { DateTime } from "luxon";
import { faChevronRight } from "@fortawesome/pro-regular-svg-icons"; import { faChevronRight } from "@fortawesome/pro-regular-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import getConversationsQuery from "../queries/get-conversations"; import getConversationsQuery from "../queries/get-conversations";
import { formatRelativeDate } from "../../core/helpers/date-formatter";
export default function ConversationsList() { export default function ConversationsList() {
const conversations = useQuery(getConversationsQuery, {})[0]; const conversations = useQuery(getConversationsQuery, {})[0];
@ -23,7 +23,7 @@ export default function ConversationsList() {
<div className="flex flex-row justify-between"> <div className="flex flex-row justify-between">
<strong>{formattedPhoneNumber}</strong> <strong>{formattedPhoneNumber}</strong>
<div className="text-gray-700 flex flex-row gap-x-1"> <div className="text-gray-700 flex flex-row gap-x-1">
{formatMessageDate(lastMessage.sentAt)} {formatRelativeDate(lastMessage.sentAt)}
<FontAwesomeIcon className="w-4 h-4 my-auto" icon={faChevronRight} /> <FontAwesomeIcon className="w-4 h-4 my-auto" icon={faChevronRight} />
</div> </div>
</div> </div>
@ -36,20 +36,3 @@ export default function ConversationsList() {
</ul> </ul>
); );
} }
function formatMessageDate(date: Date): string {
const messageDate = DateTime.fromJSDate(date);
const diff = messageDate.diffNow("days");
const isToday = diff.days > -1;
if (isToday) {
return messageDate.toFormat("HH:mm", { locale: "en-US" });
}
const isDuringLastWeek = diff.days > -8;
if (isDuringLastWeek) {
return messageDate.weekdayLong;
}
return messageDate.toFormat("dd/MM/yyyy", { locale: "en-US" });
}

View File

@ -1,10 +1,9 @@
import type { BlitzPage } from "blitz"; import type { BlitzPage } from "blitz";
import { Head } from "blitz";
import clsx from "clsx"; import clsx from "clsx";
import { CheckIcon, XIcon, TerminalIcon } from "@heroicons/react/solid"; import { CheckIcon, XIcon, TerminalIcon } from "@heroicons/react/solid";
import Header from "../components/header"; import { formatDate } from "../../core/helpers/date-formatter";
import Footer from "../components/footer";
import Layout from "../components/layout"; import Layout from "../components/layout";
const Roadmap: BlitzPage = () => { const Roadmap: BlitzPage = () => {
@ -45,7 +44,7 @@ const Roadmap: BlitzPage = () => {
</div> </div>
{isDone ? ( {isDone ? (
<div className="text-right self-start text-md xl:text-lg whitespace-nowrap text-gray-500"> <div className="text-right self-start text-md xl:text-lg whitespace-nowrap text-gray-500">
<time>{formatter.format(feature.doneDate)}</time> <time>{formatDate(feature.doneDate)}</time>
</div> </div>
) : null} ) : null}
</div> </div>
@ -131,12 +130,6 @@ const roadmap: RoadmapItem[] = [
}, },
]; ];
const formatter = Intl.DateTimeFormat("en-US", {
day: "2-digit",
month: "short",
year: "numeric",
});
Roadmap.getLayout = (page) => <Layout title="(Rough) Roadmap">{page}</Layout>; Roadmap.getLayout = (page) => <Layout title="(Rough) Roadmap">{page}</Layout>;
Roadmap.suppressFirstRenderFlicker = true; Roadmap.suppressFirstRenderFlicker = true;