从 Moment 迁移到 Luxon - (t) => moment(t).format('hh:mm') 等效

发布于 2025-01-15 19:12:56 字数 1322 浏览 1 评论 0 原文

我正在将一段旧代码从 Moment 迁移到 Luxon,并遇到下面的函数:

export const TIME_FORMATTER = {
  HOUR: (t) => moment(t).format('hh:mm'),
  DAY: (t) => moment(t).format('M/DD'),
  HOUR_PERIOD: (t) => moment(t).format('hh:mm A'),
  DAY_HOUR_PERIOD: (t) => moment(t).format('hh:mm A M/DD'),
  SEC: (t) => moment(t).format('HH:mm:ss')
};

其调用方式如下:

export const getFormatterByTimeInterval = (timeInterval: number) => {
  if (timeInterval <= 240) {
    return TIME_FORMATTER.DAY_HOUR_PERIOD;
  }
  else if (timeInterval > 480) {
    return TIME_FORMATTER.HOUR_PERIOD;
  }
  else {
    return TIME_FORMATTER.DAY;
  }
}

我最初的想法是与 Luxon 使用相同的调用格式:


const TIME_FORMATTER_LUXON = {
  HOUR: (t) => DateTime.local(t).toFormat("hh:mm"),
  DAY: (t) => DateTime.local(t).toFormat("M/d"),
  HOUR_PERIOD: (t) => DateTime.local(t).toFormat("t"),
  DAY_HOUR_PERIOD: (t) => DateTime.local(t).toFormat("t M/d"),
  SEC: (t) => DateTime.local(t).toFormat("HH:mm:ss")
};

这在另一个文件 const formatter 上调用= getFormatterByTimeInterval(timeInterval); 但它返回 Invalid DateTime

这对于 Luxon 来说可能吗?可能是什么问题?

I'm migrating an old piece of code from Moment to Luxon and bumped into the function below:

export const TIME_FORMATTER = {
  HOUR: (t) => moment(t).format('hh:mm'),
  DAY: (t) => moment(t).format('M/DD'),
  HOUR_PERIOD: (t) => moment(t).format('hh:mm A'),
  DAY_HOUR_PERIOD: (t) => moment(t).format('hh:mm A M/DD'),
  SEC: (t) => moment(t).format('HH:mm:ss')
};

which gets called as follows:

export const getFormatterByTimeInterval = (timeInterval: number) => {
  if (timeInterval <= 240) {
    return TIME_FORMATTER.DAY_HOUR_PERIOD;
  }
  else if (timeInterval > 480) {
    return TIME_FORMATTER.HOUR_PERIOD;
  }
  else {
    return TIME_FORMATTER.DAY;
  }
}

My initial thought was to use the same call format with Luxon:


const TIME_FORMATTER_LUXON = {
  HOUR: (t) => DateTime.local(t).toFormat("hh:mm"),
  DAY: (t) => DateTime.local(t).toFormat("M/d"),
  HOUR_PERIOD: (t) => DateTime.local(t).toFormat("t"),
  DAY_HOUR_PERIOD: (t) => DateTime.local(t).toFormat("t M/d"),
  SEC: (t) => DateTime.local(t).toFormat("HH:mm:ss")
};

This gets called on another file const formatter = getFormatterByTimeInterval(timeInterval); but it's returning Invalid DateTime

Is this possible with Luxon? What can be the issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤痕我心 2025-01-22 19:12:56

在我看来,您的旧代码可能有一些问题,所以我想至少在回答您的问题之前解决这些问题:

接受 numbermoment 的唯一函数签名code> 参数是 Unix 时间戳(毫秒)

new Date(Number)类似,您可以通过传递一个整数值来创建一个时刻,该整数值表示自 Unix 纪元(UTC 时间 1970 年 1 月 1 日凌晨 12 点)以来的毫秒数)。

const day = moment(1318781876406);

注意:ECMAScript 调用这是“时间价值”

我不确定格式化程序解析器函数中的 timeInterval 参数代表什么:

function getFormatterByTimeInterval (timeInterval: number) {/* ... */}

但我现在会忽略它。排除这一点,让我们看看条件:

export const getFormatterByTimeInterval = (timeInterval: number) => {
  // This formats as time and date information
  if (timeInterval > 240) {
    return TIME_FORMATTER.DAY_HOUR_PERIOD;
  }
  // This formats as time-only information
  // Also, this will never match because any `timeInterval` value which is
  // greater than 480 is also greater than 240, so the first conditional above
  // will match and return before reaching this one
  else if (timeInterval > 480) {
    return TIME_FORMATTER.HOUR_PERIOD;
  }
  // Shorter than either of the above
  // This formats as date-only information
  else {
    return TIME_FORMATTER.DAY;
  }
}

我不确定你的程序应该如何工作,但这对我来说似乎不是预期的行为。


关于您的转换问题:

从毫秒 number 类型实例化 DateTimeLuxon 等效项是 DateTime.fromMillis()。 (您无需担心使用 local 方法,因为 luxon 默认情况下使用系统的本地时区。)

关于等效的格式选项,它们将是:

时刻 luxon
hh:mm hh:mm
M/DD L/dd
hh:mm A hh:mm a
hh:mm AM/DD hh:mm a L/dd >
时:分:秒 HH:mm:ss

表示为代码,它看起来像这样:

import {DateTime} from 'luxon';

export const TIME_FORMATTER = {
  HOUR: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm'),
  DAY: (millis: number) => DateTime.fromMillis(millis).toFormat('L/dd'),
  HOUR_PERIOD: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm a'),
  DAY_HOUR_PERIOD: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm a L/dd'),
  SEC: (millis: number) => DateTime.fromMillis(millis).toFormat('HH:mm:ss'),
};

然后,对解析器进行一个小的重构:

type FormatterFn = (millis: number) => string;

export const getFormatterByTimeInterval = (timeInterval: number): FormatterFn => {
  let key: keyof typeof TIME_FORMATTER;
  // I'm still not sure about these conditionals,
  // but this order matches longest duration first
  if (timeInterval > 480) key = 'HOUR_PERIOD';
  else if (timeInterval > 240) key = 'DAY_HOUR_PERIOD';
  else key = 'DAY';
  return TIME_FORMATTER[key];
};

您可以像这样检查它:

// The time you asked this question
const millis = DateTime.fromISO('2022-03-21T21:02:03Z').toMillis();

// Check each conditional range:
for (const timeInterval of [500, 300, 100]) {
  const formatter = getFormatterByTimeInterval(timeInterval);
  console.log(formatter(millis));
}

TypeScript Playground 中的代码

来自 TS Playground 的已编译 JavaScript 演示链接:

<script type="module">

import {DateTime} from 'https://unpkg.com/[email protected]/src/luxon.js';

export const TIME_FORMATTER = {
    HOUR: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm'),
    DAY: (millis) => DateTime.fromMillis(millis).toFormat('L/dd'),
    HOUR_PERIOD: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm a'),
    DAY_HOUR_PERIOD: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm a L/dd'),
    SEC: (millis) => DateTime.fromMillis(millis).toFormat('HH:mm:ss'),
};
export const getFormatterByTimeInterval = (timeInterval) => {
    let key;
    // I'm still not sure about these conditionals,
    // but this order matches longest duration first
    if (timeInterval > 480)
        key = 'HOUR_PERIOD';
    else if (timeInterval > 240)
        key = 'DAY_HOUR_PERIOD';
    else
        key = 'DAY';
    return TIME_FORMATTER[key];
};
// The time you asked this question
const millis = DateTime.fromISO('2022-03-21T21:02:03Z').toMillis();
// Check each conditional range:
for (const timeInterval of [500, 300, 100]) {
    const formatter = getFormatterByTimeInterval(timeInterval);
    console.log(timeInterval, formatter(millis));
}

</script>

It seems to me like your old code might have a few issues, so I want to at least address them before responding to your question:

The only function signature for moment which accepts a number argument is Unix Timestamp (milliseconds):

Similar to new Date(Number), you can create a moment by passing an integer value representing the number of milliseconds since the Unix Epoch (Jan 1 1970 12AM UTC).

const day = moment(1318781876406);

Note: ECMAScript calls this a "Time Value"

I'm not sure what the timeInterval parameter represents in your formatter resolver function:

function getFormatterByTimeInterval (timeInterval: number) {/* ... */}

but I'll ignore that for now. With that out of the way, let's look at the conditionals:

export const getFormatterByTimeInterval = (timeInterval: number) => {
  // This formats as time and date information
  if (timeInterval > 240) {
    return TIME_FORMATTER.DAY_HOUR_PERIOD;
  }
  // This formats as time-only information
  // Also, this will never match because any `timeInterval` value which is
  // greater than 480 is also greater than 240, so the first conditional above
  // will match and return before reaching this one
  else if (timeInterval > 480) {
    return TIME_FORMATTER.HOUR_PERIOD;
  }
  // Shorter than either of the above
  // This formats as date-only information
  else {
    return TIME_FORMATTER.DAY;
  }
}

I'm not sure how your program is supposed to work, but that doesn't seem like the intended behavior to me.


In regard to your question of conversion:

The Luxon equivalent for instantiation of a DateTime from a milliseconds number type is DateTime.fromMillis(). (You don't need to worry about using the local method because luxon uses your system's local timezone by default.)

In regard to the equivalent formatting options, they would be:

moment luxon
hh:mm hh:mm
M/DD L/dd
hh:mm A hh:mm a
hh:mm A M/DD hh:mm a L/dd
HH:mm:ss HH:mm:ss

Expressed as code, it looks like this:

import {DateTime} from 'luxon';

export const TIME_FORMATTER = {
  HOUR: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm'),
  DAY: (millis: number) => DateTime.fromMillis(millis).toFormat('L/dd'),
  HOUR_PERIOD: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm a'),
  DAY_HOUR_PERIOD: (millis: number) => DateTime.fromMillis(millis).toFormat('hh:mm a L/dd'),
  SEC: (millis: number) => DateTime.fromMillis(millis).toFormat('HH:mm:ss'),
};

Then, a small refactor of your resolver:

type FormatterFn = (millis: number) => string;

export const getFormatterByTimeInterval = (timeInterval: number): FormatterFn => {
  let key: keyof typeof TIME_FORMATTER;
  // I'm still not sure about these conditionals,
  // but this order matches longest duration first
  if (timeInterval > 480) key = 'HOUR_PERIOD';
  else if (timeInterval > 240) key = 'DAY_HOUR_PERIOD';
  else key = 'DAY';
  return TIME_FORMATTER[key];
};

And you can check it like this:

// The time you asked this question
const millis = DateTime.fromISO('2022-03-21T21:02:03Z').toMillis();

// Check each conditional range:
for (const timeInterval of [500, 300, 100]) {
  const formatter = getFormatterByTimeInterval(timeInterval);
  console.log(formatter(millis));
}

Code in the TypeScript Playground

Demo of compiled JavaScript from the TS playground link:

<script type="module">

import {DateTime} from 'https://unpkg.com/[email protected]/src/luxon.js';

export const TIME_FORMATTER = {
    HOUR: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm'),
    DAY: (millis) => DateTime.fromMillis(millis).toFormat('L/dd'),
    HOUR_PERIOD: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm a'),
    DAY_HOUR_PERIOD: (millis) => DateTime.fromMillis(millis).toFormat('hh:mm a L/dd'),
    SEC: (millis) => DateTime.fromMillis(millis).toFormat('HH:mm:ss'),
};
export const getFormatterByTimeInterval = (timeInterval) => {
    let key;
    // I'm still not sure about these conditionals,
    // but this order matches longest duration first
    if (timeInterval > 480)
        key = 'HOUR_PERIOD';
    else if (timeInterval > 240)
        key = 'DAY_HOUR_PERIOD';
    else
        key = 'DAY';
    return TIME_FORMATTER[key];
};
// The time you asked this question
const millis = DateTime.fromISO('2022-03-21T21:02:03Z').toMillis();
// Check each conditional range:
for (const timeInterval of [500, 300, 100]) {
    const formatter = getFormatterByTimeInterval(timeInterval);
    console.log(timeInterval, formatter(millis));
}

</script>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文