您必须采用当前时间并区分您正在格式化的时间以获得毫秒数。
现在,您需要找出最接近的单位以向下舍入并使用该单位进行格式化。
只需在适用的地方交换Intl.RelativeTimeFormat
,intl.formatRelativeTime
但算法应该保持不变。
if (Date.prototype.getUTCTime === undefined) {
Date.prototype.getUTCTime = function() {
return this.getTime() - (this.getTimezoneOffset() * 60000);
};
}
const
WEEK_IN_MILLIS = 6.048e8,
DAY_IN_MILLIS = 8.64e7,
HOUR_IN_MILLIS = 3.6e6,
MIN_IN_MILLIS = 6e4,
SEC_IN_MILLIS = 1e3;
// For testing only, remove the constructor argument in production.
const getCurrentUTCTime = () => new Date('2021-04-26T14:21:51.771Z').getUTCTime();
const timeFromNow = (date, formatter) => {
const
millis = typeof date === 'string' ? new Date(date).getUTCTime() : date.getUTCTime(),
diff = millis - getCurrentUTCTime();
if (Math.abs(diff) > WEEK_IN_MILLIS)
return formatter.format(Math.trunc(diff / WEEK_IN_MILLIS), 'week');
else if (Math.abs(diff) > DAY_IN_MILLIS)
return formatter.format(Math.trunc(diff / DAY_IN_MILLIS), 'day');
else if (Math.abs(diff) > HOUR_IN_MILLIS)
return formatter.format(Math.trunc((diff % DAY_IN_MILLIS) / HOUR_IN_MILLIS), 'hour');
else if (Math.abs(diff) > MIN_IN_MILLIS)
return formatter.format(Math.trunc((diff % HOUR_IN_MILLIS) / MIN_IN_MILLIS), 'minute');
else
return formatter.format(Math.trunc((diff % MIN_IN_MILLIS) / SEC_IN_MILLIS), 'second');
};
const dateFormat = new Intl.RelativeTimeFormat('en', { style: 'long' });
console.log(timeFromNow('2021-04-24T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-25T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-26T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-27T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-28T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-29T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-04-30T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-05-01T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-05-02T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-05-03T14:21:51.771Z', dateFormat));
console.log(timeFromNow('2021-05-04T14:21:51.771Z', dateFormat));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-messageformat/9.0.2/intl-messageformat.min.js"></script>
这是上面用 React 编写的代码的一个版本:
在CodeSandbox上查看
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { IntlProvider, useIntl } from "react-intl";
const WEEK_IN_MILLIS = 6.048e8,
DAY_IN_MILLIS = 8.64e7,
HOUR_IN_MILLIS = 3.6e6,
MIN_IN_MILLIS = 6e4,
SEC_IN_MILLIS = 1e3;
const getUTCTime = (date) => date.getTime() - date.getTimezoneOffset() * 60000;
// For testing only, remove the constructor argument in production.
const getCurrentUTCTime = () => getUTCTime(new Date());
const defaultFormatOptions = {
style: "long"
};
const timeFromNow = (date, intl, options = defaultFormatOptions) => {
const millis =
typeof date === "string" ? getUTCTime(new Date(date)) : getUTCTime(date),
diff = millis - getCurrentUTCTime();
if (Math.abs(diff) > WEEK_IN_MILLIS)
return intl.formatRelativeTime(
Math.trunc(diff / WEEK_IN_MILLIS),
"week",
options
);
else if (Math.abs(diff) > DAY_IN_MILLIS)
return intl.formatRelativeTime(
Math.trunc(diff / DAY_IN_MILLIS),
"day",
options
);
else if (Math.abs(diff) > HOUR_IN_MILLIS)
return intl.formatRelativeTime(
Math.trunc((diff % DAY_IN_MILLIS) / HOUR_IN_MILLIS),
"hour",
options
);
else if (Math.abs(diff) > MIN_IN_MILLIS)
return intl.formatRelativeTime(
Math.trunc((diff % HOUR_IN_MILLIS) / MIN_IN_MILLIS),
"minute",
options
);
else
return intl.formatRelativeTime(
Math.trunc((diff % MIN_IN_MILLIS) / SEC_IN_MILLIS),
"second",
options
);
};
const CreatedConsetee = ({ date }) => {
return <>{timeFromNow(date, useIntl())}</>;
};
ReactDOM.render(
<StrictMode>
<IntlProvider locale={navigator.language}>
<div className="App">
<h1>
<CreatedConsetee date={new Date("2021-04-26T14:21:51.771Z")} />
</h1>
</div>
</IntlProvider>
</StrictMode>,
document.getElementById("root")
);