Move redundant datetime formatting code into a unified station-timezone-aware composable.

This commit is contained in:
Buster Neece 2024-01-22 12:34:53 -06:00
parent 87e7802d01
commit f6b998a17b
No known key found for this signature in database
14 changed files with 169 additions and 179 deletions

View File

@ -151,7 +151,7 @@
<script setup lang="ts">
import Icon from "~/components/Common/Icon.vue";
import DataTable, { DataTableField } from "~/components/Common/DataTable.vue";
import DataTable, {DataTableField} from "~/components/Common/DataTable.vue";
import AdminBackupsLastOutputModal from "./Backups/LastOutputModal.vue";
import formatFileSize from "~/functions/formatFileSize";
import AdminBackupsConfigureModal from "~/components/Admin/Backups/ConfigureModal.vue";
@ -196,7 +196,7 @@ const settings = ref({...blankSettings});
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const {DateTime} = useLuxon();
const {DateTime, timestampToRelative} = useLuxon();
const fields: DataTableField[] = [
{
@ -250,8 +250,6 @@ const relist = () => {
onMounted(relist);
const {timestampToRelative} = useLuxon();
const $lastOutputModal = ref<InstanceType<typeof AdminBackupsLastOutputModal> | null>(null);
const showLastOutput = () => {
$lastOutputModal.value?.show();

View File

@ -96,13 +96,13 @@
v-if="item.publish_at"
class="badge text-bg-secondary"
>
{{ formatTime(item.publish_at) }}
{{ formatTimestampAsDateTime(item.publish_at) }}
</span>
<span
v-else
class="badge text-bg-secondary"
>
{{ formatTime(item.created_at) }}
{{ formatTimestampAsDateTime(item.created_at) }}
</span>
<span
v-if="item.explicit"
@ -141,8 +141,7 @@ import {useTranslate} from "~/vendor/gettext.ts";
import {IconRss} from "~/components/Common/icons.ts";
import Icon from "~/components/Common/Icon.vue";
import PlayButton from "~/components/Common/PlayButton.vue";
import {useLuxon} from "~/vendor/luxon.ts";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const {params} = useRoute();
@ -164,17 +163,5 @@ const fields: DataTableField[] = [
{key: 'actions', label: $gettext('Actions'), sortable: false, class: 'shrink'}
];
const {DateTime} = useLuxon();
const {timezone} = useAzuraCastStation();
const {timeConfig} = useAzuraCast();
const formatTime = (value) => {
if (!value) {
return '';
}
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
};
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
</script>

View File

@ -84,13 +84,13 @@
v-if="episode.publish_at"
class="badge text-bg-secondary"
>
{{ formatTime(episode.publish_at) }}
{{ formatTimestampAsDateTime(episode.publish_at) }}
</span>
<span
v-else
class="badge text-bg-secondary"
>
{{ formatTime(episode.created_at) }}
{{ formatTimestampAsDateTime(episode.created_at) }}
</span>
<span
v-if="episode.explicit"
@ -123,8 +123,7 @@ import {useAxios} from "~/vendor/axios.ts";
import useRefreshableAsyncState from "~/functions/useRefreshableAsyncState.ts";
import AlbumArt from "~/components/Common/AlbumArt.vue";
import PlayButton from "~/components/Common/PlayButton.vue";
import {useLuxon} from "~/vendor/luxon.ts";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const {params} = useRoute();
@ -143,17 +142,5 @@ const {state: episode, isLoading: episodeLoading} = useRefreshableAsyncState(
{},
);
const {DateTime} = useLuxon();
const {timezone} = useAzuraCastStation();
const {timeConfig} = useAzuraCast();
const formatTime = (value) => {
if (!value) {
return '';
}
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
};
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
</script>

View File

@ -241,7 +241,7 @@
</template>
<script setup lang="ts">
import DataTable, { DataTableField } from '~/components/Common/DataTable.vue';
import DataTable, {DataTableField} from '~/components/Common/DataTable.vue';
import MediaToolbar from './Media/MediaToolbar.vue';
import Breadcrumb from './Media/Breadcrumb.vue';
import FileUpload from './Media/FileUpload.vue';
@ -256,14 +256,13 @@ import PlayButton from "~/components/Common/PlayButton.vue";
import {useTranslate} from "~/vendor/gettext";
import {computed, ref, watch} from "vue";
import {forEach, map, partition} from "lodash";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import formatFileSize from "../../functions/formatFileSize";
import InfoCard from "~/components/Common/InfoCard.vue";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import {useRoute, useRouter} from "vue-router";
import {IconFile, IconFolder, IconImage} from "~/components/Common/icons";
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const props = defineProps({
initialPlaylists: {
@ -300,9 +299,8 @@ const renameUrl = getStationApiUrl('/files/rename');
const quotaUrl = getStationApiUrl('/quota/station_media');
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
const fields = computed<DataTableField[]>(() => {
const fields: DataTableField[] = [
@ -337,15 +335,7 @@ const fields = computed<DataTableField[]>(() => {
key: 'timestamp',
label: $gettext('Modified'),
sortable: true,
formatter: (value) => {
if (!value) {
return '';
}
return DateTime.fromSeconds(value).setZone(timezone).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
},
formatter: (value) => formatTimestampAsDateTime(value),
selectable: true,
visible: true
},

View File

@ -45,9 +45,8 @@
<script setup lang="ts">
import {map} from "lodash";
import {computed} from "vue";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import CardPage from "~/components/Common/CardPage.vue";
import {useLuxon} from "~/vendor/luxon";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const props = defineProps({
scheduleItems: {
@ -56,39 +55,35 @@ const props = defineProps({
}
});
const {timeConfig} = useAzuraCast();
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const {
DateTime,
now,
timestampToDateTime,
formatDateTime
} = useStationDateTimeFormatter();
const processedScheduleItems = computed(() => {
const now = DateTime.now().setZone(timezone);
const nowTz = now();
return map(props.scheduleItems, (row) => {
const start_moment = DateTime.fromSeconds(row.start_timestamp).setZone(timezone);
const end_moment = DateTime.fromSeconds(row.end_timestamp).setZone(timezone);
const startMoment = timestampToDateTime(row.start_timestamp);
const endMoment = timestampToDateTime(row.end_timestamp);
row.time_until = start_moment.toRelative();
row.time_until = startMoment.toRelative();
if (start_moment.hasSame(now, 'day')) {
row.start_formatted = start_moment.toLocaleString(
{...DateTime.TIME_SIMPLE, ...timeConfig}
);
} else {
row.start_formatted = start_moment.toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
}
row.start_formatted = formatDateTime(
startMoment,
startMoment.hasSame(nowTz, 'day')
? DateTime.TIME_SIMPLE
: DateTime.DATETIME_MED
);
if (end_moment.hasSame(start_moment, 'day')) {
row.end_formatted = end_moment.toLocaleString(
{...DateTime.TIME_SIMPLE, ...timeConfig}
);
} else {
row.end_formatted = end_moment.toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
}
row.end_formatted = formatDateTime(
endMoment,
endMoment.hasSame(startMoment, 'day')
? DateTime.TIME_SIMPLE
: DateTime.DATETIME_MED
);
return row;
});

View File

@ -53,8 +53,8 @@
</div>
</template>
<template #cell(played_at)="row">
{{ formatTime(row.item.played_at) }}<br>
<small>{{ formatRelativeTime(row.item.played_at) }}</small>
{{ formatTimestampAsTime(row.item.played_at) }}<br>
<small>{{ formatTimestampAsRelative(row.item.played_at) }}</small>
</template>
<template #cell(source)="row">
<div v-if="row.item.is_request">
@ -74,7 +74,6 @@
import DataTable, {DataTableField} from '../Common/DataTable.vue';
import QueueLogsModal from './Queue/LogsModal.vue';
import Icon from "~/components/Common/Icon.vue";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import {useTranslate} from "~/vendor/gettext";
import {computed, ref} from "vue";
import useConfirmAndDelete from "~/functions/useConfirmAndDelete";
@ -83,10 +82,10 @@ import {useNotify} from "~/functions/useNotify";
import {useAxios} from "~/vendor/axios";
import {useSweetAlert} from "~/vendor/sweetalert";
import CardPage from "~/components/Common/CardPage.vue";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import {IconRemove} from "~/components/Common/icons";
import {useIntervalFn} from "@vueuse/core";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const listUrl = getStationApiUrl('/queue');
const clearUrl = getStationApiUrl('/queue/clear');
@ -100,20 +99,10 @@ const fields: DataTableField[] = [
{key: 'source', label: $gettext('Source'), sortable: false}
];
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const getDateTime = (timestamp) =>
DateTime.fromSeconds(timestamp).setZone(timezone);
const {timeConfig} = useAzuraCast();
const formatTime = (time) => getDateTime(time).toLocaleString(
{...DateTime.TIME_WITH_SECONDS, ...timeConfig}
);
const formatRelativeTime = (time) => getDateTime(time).toRelative();
const {
formatTimestampAsTime,
formatTimestampAsRelative
} = useStationDateTimeFormatter();
const $datatable = ref<DataTableTemplateRef>(null);
const {relist} = useHasDatatable($datatable);

View File

@ -191,8 +191,6 @@ import DateRangeDropdown from "~/components/Common/DateRangeDropdown.vue";
import {computed, ComputedRef, nextTick, onMounted, Ref, ref, ShallowRef, shallowRef, watch} from "vue";
import {useTranslate} from "~/vendor/gettext";
import {useAxios} from "~/vendor/axios";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import {IconDesktopWindows, IconDownload, IconRouter, IconSmartphone} from "~/components/Common/icons";
import useHasDatatable, {DataTableTemplateRef} from "~/functions/useHasDatatable";
@ -201,6 +199,7 @@ import {filter} from "lodash";
import formatTime from "~/functions/formatTime.ts";
import ListenerFiltersBar from "./Listeners/FiltersBar.vue";
import {ApiListener} from "~/entities/ApiInterfaces.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const props = defineProps({
attribution: {
@ -214,11 +213,13 @@ const apiUrl = getStationApiUrl('/listeners');
const isLive = ref<boolean>(true);
const listeners: ShallowRef<ApiListener[]> = shallowRef([]);
const {timezone} = useAzuraCastStation();
const {timeConfig} = useAzuraCast();
const {
DateTime,
now,
formatTimestampAsDateTime
} = useStationDateTimeFormatter();
const {DateTime} = useLuxon();
const nowTz = DateTime.now().setZone(timezone);
const nowTz = now();
const minDate = nowTz.minus({years: 5}).toJSDate();
const maxDate = nowTz.plus({days: 5}).toJSDate();
@ -266,14 +267,10 @@ const fields: DataTableField[] = [
key: 'connected_on',
label: $gettext('Start Time'),
sortable: true,
formatter: (_col, _key, item) => {
return DateTime.fromSeconds(
item.connected_on,
{zone: timezone}
).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
},
formatter: (_col, _key, item) => formatTimestampAsDateTime(
item.connected_on,
DateTime.DATETIME_SHORT
),
selectable: true,
visible: false
},
@ -281,14 +278,10 @@ const fields: DataTableField[] = [
key: 'connected_until',
label: $gettext('End Time'),
sortable: true,
formatter: (_col, _key, item) => {
return DateTime.fromSeconds(
item.connected_until,
{zone: timezone}
).toLocaleString(
{...DateTime.DATETIME_SHORT, ...timeConfig}
);
},
formatter: (_col, _key, item) => formatTimestampAsDateTime(
item.connected_until,
DateTime.DATETIME_SHORT
),
selectable: true,
visible: false
},

View File

@ -92,11 +92,10 @@ import StreamsTab from "./Overview/StreamsTab.vue";
import ClientsTab from "./Overview/ClientsTab.vue";
import ListeningTimeTab from "~/components/Stations/Reports/Overview/ListeningTimeTab.vue";
import {ref} from "vue";
import {useAzuraCastStation} from "~/vendor/azuracast";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import Tabs from "~/components/Common/Tabs.vue";
import Tab from "~/components/Common/Tab.vue";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const props = defineProps({
showFullAnalytics: {
@ -113,11 +112,9 @@ const byCountryUrl = getStationApiUrl('/reports/overview/by-country');
const byClientUrl = getStationApiUrl('/reports/overview/by-client');
const listeningTimeUrl = getStationApiUrl('/reports/overview/by-listening-time');
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const nowTz = DateTime.now().setZone(timezone);
const {now} = useStationDateTimeFormatter();
const nowTz = now();
const dateRange = ref({
startDate: nowTz.minus({days: 13}).toJSDate(),
endDate: nowTz.toJSDate(),

View File

@ -56,14 +56,14 @@
:api-url="listUrlForType"
>
<template #cell(timestamp)="row">
{{ formatTime(row.item.timestamp) }}
{{ formatTimestampAsDateTime(row.item.timestamp) }}
</template>
<template #cell(played_at)="row">
<span v-if="row.item.played_at === 0">
{{ $gettext('Not Played') }}
</span>
<span v-else>
{{ formatTime(row.item.played_at) }}
{{ formatTimestampAsDateTime(row.item.played_at) }}
</span>
</template>
<template #cell(song_title)="row">
@ -93,18 +93,17 @@
</template>
<script setup lang="ts">
import DataTable, { DataTableField } from '~/components/Common/DataTable.vue';
import DataTable, {DataTableField} from '~/components/Common/DataTable.vue';
import Icon from "~/components/Common/Icon.vue";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import {computed, nextTick, ref} from "vue";
import {useTranslate} from "~/vendor/gettext";
import {useSweetAlert} from "~/vendor/sweetalert";
import {useNotify} from "~/functions/useNotify";
import {useAxios} from "~/vendor/axios";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import {IconRemove} from "~/components/Common/icons";
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const listUrl = getStationApiUrl('/reports/requests');
const clearUrl = getStationApiUrl('/reports/requests/clear');
@ -147,16 +146,7 @@ const setType = (type) => {
nextTick(relist);
};
const {timeConfig} = useAzuraCast();
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const formatTime = (time) => {
return DateTime.fromSeconds(time).setZone(timezone).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
};
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
const {confirmDelete} = useSweetAlert();
const {notifySuccess} = useNotify();

View File

@ -114,16 +114,14 @@ import FormFieldset from "~/components/Form/FormFieldset.vue";
import FormGroupCheckbox from "~/components/Form/FormGroupCheckbox.vue";
import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm";
import {getStationApiUrl} from "~/router";
import {useLuxon} from "~/vendor/luxon";
import {useAzuraCastStation} from "~/vendor/azuracast";
import CardPage from "~/components/Common/CardPage.vue";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const apiUrl = getStationApiUrl('/reports/soundexchange');
const {DateTime} = useLuxon();
const {timezone} = useAzuraCastStation();
const {now} = useStationDateTimeFormatter();
const lastMonth = DateTime.now().setZone(timezone).minus({months: 1});
const lastMonth = now().minus({months: 1});
const {v$} = useVuelidateOnForm(
{

View File

@ -86,22 +86,20 @@
<script setup lang="ts">
import Icon from "~/components/Common/Icon.vue";
import DataTable, { DataTableField } from "~/components/Common/DataTable.vue";
import DataTable, {DataTableField} from "~/components/Common/DataTable.vue";
import DateRangeDropdown from "~/components/Common/DateRangeDropdown.vue";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import {useAzuraCast} from "~/vendor/azuracast";
import {computed, ref, watch} from "vue";
import {useTranslate} from "~/vendor/gettext";
import {useLuxon} from "~/vendor/luxon";
import {getStationApiUrl} from "~/router";
import {IconDownload, IconTrendingDown, IconTrendingUp} from "~/components/Common/icons";
import useHasDatatable, {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const baseApiUrl = getStationApiUrl('/history');
const {timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const nowTz = DateTime.now().setZone(timezone);
const {now} = useStationDateTimeFormatter();
const nowTz = now();
const dateRange = ref(
{

View File

@ -64,14 +64,14 @@
import {ref} from "vue";
import Icon from "~/components/Common/Icon.vue";
import SidebarMenu from "~/components/Common/SidebarMenu.vue";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast";
import {useAzuraCastStation} from "~/vendor/azuracast";
import {useEventBus, useIntervalFn} from "@vueuse/core";
import {useStationsMenu} from "~/components/Stations/menu";
import {StationPermission, userAllowedForStation} from "~/acl";
import {useAxios} from "~/vendor/axios.ts";
import {getStationApiUrl} from "~/router.ts";
import {useLuxon} from "~/vendor/luxon.ts";
import {IconEdit} from "~/components/Common/icons.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const props = defineProps({
station: {
@ -82,17 +82,13 @@ const props = defineProps({
const menuItems = useStationsMenu();
const {timeConfig} = useAzuraCast();
const {name, timezone} = useAzuraCastStation();
const {DateTime} = useLuxon();
const {name} = useAzuraCastStation();
const {DateTime, formatNowAsTime} = useStationDateTimeFormatter();
const clock = ref('');
useIntervalFn(() => {
clock.value = DateTime.now().setZone(timezone).toLocaleString({
...DateTime.TIME_WITH_SHORT_OFFSET,
...timeConfig
})
clock.value = formatNowAsTime(DateTime.TIME_WITH_SHORT_OFFSET);
}, 1000, {
immediate: true,
immediateCallback: true

View File

@ -63,24 +63,23 @@ import InlinePlayer from '~/components/InlinePlayer.vue';
import Icon from '~/components/Common/Icon.vue';
import PlayButton from "~/components/Common/PlayButton.vue";
import '~/vendor/sweetalert';
import {useAzuraCast} from "~/vendor/azuracast";
import {ref} from "vue";
import {useTranslate} from "~/vendor/gettext";
import {useSweetAlert} from "~/vendor/sweetalert";
import {useNotify} from "~/functions/useNotify";
import {useAxios} from "~/vendor/axios";
import Modal from "~/components/Common/Modal.vue";
import {useLuxon} from "~/vendor/luxon";
import {IconDownload} from "~/components/Common/icons";
import {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
import {ModalTemplateRef, useHasModal} from "~/functions/useHasModal.ts";
import {usePlayerStore, useProvidePlayerStore} from "~/functions/usePlayerStore.ts";
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
const listUrl = ref(null);
const {$gettext} = useTranslate();
const {timeConfig} = useAzuraCast();
const {DateTime} = useLuxon();
const {formatTimestampAsDateTime} = useStationDateTimeFormatter();
const fields: DataTableField[] = [
{
@ -93,11 +92,7 @@ const fields: DataTableField[] = [
key: 'timestampStart',
label: $gettext('Start Time'),
sortable: false,
formatter: (value) => {
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
},
formatter: (value) => formatTimestampAsDateTime(value),
class: 'ps-3'
},
{
@ -105,13 +100,9 @@ const fields: DataTableField[] = [
label: $gettext('End Time'),
sortable: false,
formatter: (value) => {
if (value === 0) {
return $gettext('Live');
}
return DateTime.fromSeconds(value).toLocaleString(
{...DateTime.DATETIME_MED, ...timeConfig}
);
return value === 0
? $gettext('Live')
: formatTimestampAsDateTime(value);
}
},
{

View File

@ -0,0 +1,81 @@
import {useLuxon} from "~/vendor/luxon.ts";
import {useAzuraCast, useAzuraCastStation} from "~/vendor/azuracast.ts";
import {DateTimeMaybeValid} from "luxon";
export default function useStationDateTimeFormatter() {
const {DateTime, Duration} = useLuxon();
const {timeConfig} = useAzuraCast();
const {timezone} = useAzuraCastStation();
const timestampToDateTime = (value): DateTimeMaybeValid =>
DateTime.fromSeconds(value).setZone(timezone);
const now = (): DateTimeMaybeValid =>
DateTime.now().setZone(timezone);
const formatDateTime = (
value: DateTimeMaybeValid,
format: Intl.DateTimeFormatOptions
) => value.toLocaleString(
{...format, ...timeConfig}
);
const formatDateTimeAsDateTime = (
value: DateTimeMaybeValid,
format: Intl.DateTimeFormatOptions | null = null
) => formatDateTime(value, format ?? DateTime.DATETIME_MED);
const formatDateTimeAsTime = (
value: DateTimeMaybeValid,
format: Intl.DateTimeFormatOptions | null = null
) => formatDateTime(value, format ?? DateTime.TIME_WITH_SECONDS);
const formatDateTimeAsRelative = (
value: DateTimeMaybeValid
) => value.toRelative();
const formatTimestampAsDateTime = (
value: any,
format: Intl.DateTimeFormatOptions | null = null
) =>
(value)
? formatDateTimeAsDateTime(timestampToDateTime(value), format)
: ''
const formatTimestampAsTime = (
value: any,
format: Intl.DateTimeFormatOptions | null = null
) =>
(value)
? formatDateTimeAsTime(timestampToDateTime(value), format)
: ''
const formatTimestampAsRelative = (value) =>
(value)
? formatDateTimeAsRelative(timestampToDateTime(value))
: '';
const formatNowAsDateTime = (
format: Intl.DateTimeFormatOptions | null = null
) => formatDateTimeAsDateTime(now(), format);
const formatNowAsTime = (
format: Intl.DateTimeFormatOptions | null = null
) => formatDateTimeAsTime(now(), format);
return {
DateTime,
Duration,
timestampToDateTime,
now,
formatDateTime,
formatDateTimeAsDateTime,
formatDateTimeAsTime,
formatDateTimeAsRelative,
formatTimestampAsDateTime,
formatTimestampAsTime,
formatTimestampAsRelative,
formatNowAsDateTime,
formatNowAsTime
};
}