从 Moment 迁移到 Luxon - (t) => moment(t).format('hh:mm') 等效
Migrating from Moment to Luxon - (t) => moment(t).format('hh:mm') equivalent
我正在将一段旧代码从 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 可以吗?可能是什么问题?
我觉得你的旧代码可能有一些问题,所以我想在回答你的问题之前至少解决这些问题:
moment
接受 number
参数的唯一函数签名是 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);
我不确定 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
类型实例化 DateTime
的 Luxon
等价物是 DateTime.fromMillis()
。 (您无需担心使用 local
方法,因为 luxon 默认使用您系统的本地时区。)
关于等效的格式选项,它们是:
用代码表示,大概是这样的:
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));
}
Code in the TypeScript Playground
来自 TS playground link 的已编译 JavaScript 的演示:
<script type="module">
import {DateTime} from 'https://unpkg.com/luxon@2.3.1/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>
我正在将一段旧代码从 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 可以吗?可能是什么问题?
我觉得你的旧代码可能有一些问题,所以我想在回答你的问题之前至少解决这些问题:
moment
接受 number
参数的唯一函数签名是 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);
我不确定 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
类型实例化 DateTime
的 Luxon
等价物是 DateTime.fromMillis()
。 (您无需担心使用 local
方法,因为 luxon 默认使用您系统的本地时区。)
关于等效的格式选项,它们是:
用代码表示,大概是这样的:
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));
}
Code in the TypeScript Playground
来自 TS playground link 的已编译 JavaScript 的演示:
<script type="module">
import {DateTime} from 'https://unpkg.com/luxon@2.3.1/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>