Skip to content

Instantly share code, notes, and snippets.

@hypeJunction
Last active April 23, 2021 12:37
Show Gist options
  • Select an option

  • Save hypeJunction/2d8d8680f0ca52ff16d735a92eb3daf8 to your computer and use it in GitHub Desktop.

Select an option

Save hypeJunction/2d8d8680f0ca52ff16d735a92eb3daf8 to your computer and use it in GitHub Desktop.
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
export enum DateTimeFormat {
TIME,
ISO,
RELATIVE
}
export interface DateTimeFormatterProps {
format: DateTimeFormat;
date: Date;
}
export type DateTimeService = (props: DateTimeFormatterProps) => string;
const DateTimeServiceContext = createContext<{ service: any }>({ service: null });
type DateTimeProviderProps = {
service: DateTimeService,
children: ReactNode,
}
export const DateTimeProvider = ({ service, children }: DateTimeProviderProps) => {
return (
<DateTimeServiceContext.Provider value={{ service }}>
{children}
</DateTimeServiceContext.Provider>
);
};
export const useDateService = (): { service: DateTimeService } => {
return useContext(DateTimeServiceContext);
};
export const useTimer = (): { time: Date } => {
const [time, setTime] = useState(new Date());
useEffect(() => {
const interval = setInterval(() => {
setTime(new Date());
}, 1000);
return () => clearInterval(interval);
});
return { time };
};
import moment from "moment";
import { DateTimeFormat, DateTimeFormatterProps, DateTimeService } from "./DateTimeProvider";
const momentFormats = {
[DateTimeFormat.TIME]: (date: Date): string => {
return moment(date).format("HH:mm:ss");
},
[DateTimeFormat.ISO]: (date: Date): string => {
return date.toISOString();
},
[DateTimeFormat.RELATIVE]: (date: Date): string => {
return moment(date).fromNow();
}
};
const momentFormatter: DateTimeService = (
props: DateTimeFormatterProps
): string => {
const { format, date } = props;
return momentFormats[format](date);
};
export { momentFormatter as dateTimeService };
import { DateTimeFormat, DateTimeFormatterProps, useDateService } from "./DateTimeProvider";
import React from "react";
export function FormattedDateTime({ format, date }: DateTimeFormatterProps) {
const { service: formatDateTime } = useDateService();
return (
<time
dateTime={formatDateTime({
format: DateTimeFormat.ISO,
date
})}
>
{formatDateTime({ format, date })}
</time>
);
}
import React from "react";
import "./App.css";
import { DateTimeFormat, DateTimeProvider, useTimer } from "./DateTimeProvider";
import { dateTimeService } from "./DateTimeService";
import { FormattedDateTime } from "./FormattedDateTime";
export function TimerApp() {
const { time } = useTimer();
return (
<DateTimeProvider service={dateTimeService}>
<FormattedDateTime
format={DateTimeFormat.TIME}
date={time}
/>
</DateTimeProvider>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment