繁体   English   中英

如何正确使用 intl.formatRelativeTime()

[英]How to use intl.formatRelativeTime() in the correct way

在我的 React 应用程序中,我必须显示创建 1 小时前或 1 天前的信息,以及 10 分钟前或 3 天前的复数形式。 为了实现这一点,我正在尝试使用这个 API FormatJS并在特定的intl.formatRelativeTime()

到目前为止我尝试的是这样的

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}</>;
};

上面的结果是这样的

in 1,619,446,911,771 hours

不管是什么,它总是那么大,我不知道如何使它正确。

我想要的预期行为是,如果我们有 1 小时 1 分钟 1 天和复数 forms 2 小时 2 分钟 2 天,我收到一条消息说created 7 days ago的相同。

您必须采用当前时间并区分您正在格式化的时间以获得毫秒数。

现在,您需要找出最接近的单位以向下舍入并使用该单位进行格式化。

只需在适用的情况下将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>

这是上面用 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")
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM