Tom Butcher 0bf16d844e Refactor TimeDisplay component to improve time difference calculation
- Updated the time difference logic to handle both past and future dates more accurately.
- Simplified the calculation process by introducing base and compare dates.
- Enhanced the output format to include "in" for future dates and improved readability of time strings.
2025-12-28 01:09:11 +00:00

126 lines
3.1 KiB
JavaScript

// PrinterSelect.js
import { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { Flex, Typography, Tag } from 'antd'
import dayjs from 'dayjs'
const { Text } = Typography
const formatTimeDifference = (dateTime) => {
const now = dayjs()
const target = dayjs(dateTime)
const isFuture = target.isAfter(now)
// If future, calculate from target to now; if past, from now to target
const baseDate = isFuture ? target : now
const compareDate = isFuture ? now : target
const years = baseDate.diff(compareDate, 'year')
const months = baseDate.diff(compareDate.add(years, 'year'), 'month')
const weeks = baseDate.diff(
compareDate.add(years, 'year').add(months, 'month'),
'week'
)
const days = baseDate.diff(
compareDate.add(years, 'year').add(months, 'month').add(weeks, 'week'),
'day'
)
const hours = baseDate.diff(
compareDate
.add(years, 'year')
.add(months, 'month')
.add(weeks, 'week')
.add(days, 'day'),
'hour'
)
const minutes = baseDate.diff(
compareDate
.add(years, 'year')
.add(months, 'month')
.add(weeks, 'week')
.add(days, 'day')
.add(hours, 'hour'),
'minute'
)
const seconds = baseDate.diff(
compareDate
.add(years, 'year')
.add(months, 'month')
.add(weeks, 'week')
.add(days, 'day')
.add(hours, 'hour')
.add(minutes, 'minute'),
'second'
)
let timeStr = ''
if (years > 0) {
timeStr = `${years} ${years === 1 ? 'year' : 'years'}`
} else if (months > 0) {
timeStr = `${months} ${months === 1 ? 'month' : 'months'}`
} else if (weeks > 0) {
timeStr = `${weeks} ${weeks === 1 ? 'week' : 'weeks'}`
} else if (days > 0) {
timeStr = `${days} ${days === 1 ? 'day' : 'days'}`
} else if (hours > 0) {
timeStr = `${hours} ${hours === 1 ? 'hour' : 'hours'}`
} else if (minutes > 0) {
timeStr = `${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`
} else {
timeStr = `${seconds} ${seconds === 1 ? 'second' : 'seconds'}`
}
return isFuture ? `in ${timeStr} time` : `${timeStr} ago`
}
const TimeDisplay = ({
dateTime,
showDate = true,
showTime = true,
showSince = false,
type = 'primary'
}) => {
const [timeAgo, setTimeAgo] = useState(formatTimeDifference(dateTime))
useEffect(() => {
if (showSince) {
const timer = setInterval(() => {
setTimeAgo(formatTimeDifference(dateTime))
}, 1000)
return () => clearInterval(timer)
}
}, [dateTime, showSince])
if (!dateTime) {
return <Text type='secondary'>n/a</Text>
}
var dateFormat = ''
if (showDate == true) {
dateFormat += 'YYYY-MM-DD '
}
if (showTime == true) {
dateFormat += 'HH:mm:ss '
}
const formattedDate = dayjs(dateTime).format(dateFormat)
return (
<Flex align={'center'} gap={'small'}>
<Text type={type}>{formattedDate}</Text>
{showSince ? <Tag style={{ margin: 0 }}>{timeAgo}</Tag> : null}
</Flex>
)
}
TimeDisplay.propTypes = {
dateTime: PropTypes.string,
showDate: PropTypes.bool,
showTime: PropTypes.bool,
showSince: PropTypes.bool,
type: PropTypes.string
}
export default TimeDisplay