[英]How to use intl.formatRelativeTime() in the correct way
In my React app, I have to show info saying create 1 hour ago or 1 day ago and also plural as 10 minutes ago or 3 days ago.在我的 React 应用程序中,我必须显示创建 1 小时前或 1 天前的信息,以及 10 分钟前或 3 天前的复数形式。 To achieve that I'm trying to use this API FormatJS and in the specific
intl.formatRelativeTime()
为了实现这一点,我正在尝试使用这个 API FormatJS并在特定的
intl.formatRelativeTime()
What I tried so far is something like that到目前为止我尝试的是这样的
const CreatedConsetee = ({ date }) => {
// date = 2021-04-26T14:21:51.771Z
const intl = useIntl();
const parsedDate = new Date(date);
const dateFormat = intl.formatRelativeTime(parsedDate, 'hour', {
style: 'long',
});
return <>{dateFormat}</>;
};
The result is of the above is like this上面的结果是这样的
in 1,619,446,911,771 hours
Whatever is it always that big number and I have no idea how to make it right.不管是什么,它总是那么大,我不知道如何使它正确。
The expected behavior I want is that I got a message saying created 7 days ago
the same if we have 1 hour 1 minute 1 day and plural forms 2 hours 2 minutes 2 days.我想要的预期行为是,如果我们有 1 小时 1 分钟 1 天和复数 forms 2 小时 2 分钟 2 天,我收到一条消息说
created 7 days ago
的相同。
You would have to take the current time and diff the tiem you are formatting to get the milliseconds.您必须采用当前时间并区分您正在格式化的时间以获得毫秒数。
Now, you need to figure out the closest unit to round down to and format using that unit.现在,您需要找出最接近的单位以向下舍入并使用该单位进行格式化。
Just swap Intl.RelativeTimeFormat
for intl.formatRelativeTime
where applicable, but the algorithm should remain the same.只需在适用的情况下将
intl.formatRelativeTime
换成Intl.RelativeTimeFormat
,但算法应该保持不变。
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>
Here is a version of the code above written in React:这是上面用 React 编写的代码的一个版本:
View on CodeSandbox
在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")
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.