是否有内置的方法来规范 Luxon 内的持续时间?
Is there a built in way to normalize a duration within Luxon?
我正在从 Momentjs 迁移到 Luxon。我允许用户选择任务将花费的小时数。当我们保存这个值时,我希望它正常化。因此,如果一项任务需要 90 个小时,我更愿意存储 3 天 18 个小时。我存储了 ISO 持续时间字符串,所以我想将 PT90H 转换为 P3DT18H...当然可以使用任何给定值。
我试过Luxon的normalize
函数,我试过这样调用它:
const duration = Duration.fromObject({ hours: 90 });
duration.normalize().toISO();
然而,normalize
似乎对结果没有任何作用。我仍然得到 PT90H。 Luxon 有内置的方法吗?
Durtation.normalize()
不会向 Duration 对象添加属性,因此您需要提供您希望其标准化的单位。 (这对我来说很奇怪,但提供了对结果的隐式控制)。
normalize() – Reduce this Duration to its canonical representation in its current units.
const duration = Duration
.fromObject({ days: 0, hours: 90 })
.normalize()
.toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
或者,您可以使用 Duration.shiftTo()
明确地将持续时间强制为特定单位。
const duration = Duration
.fromObject({hours: 90 })
.shiftTo('days', 'hours')
.toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
如果您知道您总是想要标准化为所有单位,您可以声明一个实用程序 return 用所有单位初始化的 Duration 对象。
function createDuration(duration) {
return Duration.fromObject(
Object.assign(
{ years: 0, months: 0, weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 },
duration
)
);
}
const duration = createDuration({ hours: 90, minutes: 3004 }).normalize().toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
根据@pilchard 的回答,我最终使用这个函数来标准化我的持续时间。
function normalize(duration) {
const durationObject = duration.shiftTo(
'years',
'months',
'days',
'hours',
'minutes',
'seconds'
).toObject();
// filter out units with 0 values.
const resultObject = Object.keys(durationObject).reduce((result, key) => {
const value = durationObject[key];
return value ? { ...result, [key]: value } : result;
}, {});
return Duration.fromObject(resultObject);
}
console.log(normalize(Duration.fromObject({ hours: 90 })));
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
[编辑]
过滤掉 0'ed 单元的步骤对于我的既定目标来说是不需要的,toISO
方法为我们做了这个。我的需求与规范的通过有关,看起来改变规范比在计算期间浪费 CPU 周期归一化更好。使用上述方法将使生成的 ISO 持续时间字符串标准化单位 - PT1H30M
而不是 PT90M
.
最后我选择不使用 0 单位过滤,只是在将其转换为 ISO 字符串时允许它发生。
我正在从 Momentjs 迁移到 Luxon。我允许用户选择任务将花费的小时数。当我们保存这个值时,我希望它正常化。因此,如果一项任务需要 90 个小时,我更愿意存储 3 天 18 个小时。我存储了 ISO 持续时间字符串,所以我想将 PT90H 转换为 P3DT18H...当然可以使用任何给定值。
我试过Luxon的normalize
函数,我试过这样调用它:
const duration = Duration.fromObject({ hours: 90 });
duration.normalize().toISO();
然而,normalize
似乎对结果没有任何作用。我仍然得到 PT90H。 Luxon 有内置的方法吗?
Durtation.normalize()
不会向 Duration 对象添加属性,因此您需要提供您希望其标准化的单位。 (这对我来说很奇怪,但提供了对结果的隐式控制)。
normalize() – Reduce this Duration to its canonical representation in its current units.
const duration = Duration
.fromObject({ days: 0, hours: 90 })
.normalize()
.toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
或者,您可以使用 Duration.shiftTo()
明确地将持续时间强制为特定单位。
const duration = Duration
.fromObject({hours: 90 })
.shiftTo('days', 'hours')
.toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
如果您知道您总是想要标准化为所有单位,您可以声明一个实用程序 return 用所有单位初始化的 Duration 对象。
function createDuration(duration) {
return Duration.fromObject(
Object.assign(
{ years: 0, months: 0, weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 },
duration
)
);
}
const duration = createDuration({ hours: 90, minutes: 3004 }).normalize().toISO();
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
根据@pilchard 的回答,我最终使用这个函数来标准化我的持续时间。
function normalize(duration) {
const durationObject = duration.shiftTo(
'years',
'months',
'days',
'hours',
'minutes',
'seconds'
).toObject();
// filter out units with 0 values.
const resultObject = Object.keys(durationObject).reduce((result, key) => {
const value = durationObject[key];
return value ? { ...result, [key]: value } : result;
}, {});
return Duration.fromObject(resultObject);
}
console.log(normalize(Duration.fromObject({ hours: 90 })));
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>
[编辑]
过滤掉 0'ed 单元的步骤对于我的既定目标来说是不需要的,toISO
方法为我们做了这个。我的需求与规范的通过有关,看起来改变规范比在计算期间浪费 CPU 周期归一化更好。使用上述方法将使生成的 ISO 持续时间字符串标准化单位 - PT1H30M
而不是 PT90M
.
最后我选择不使用 0 单位过滤,只是在将其转换为 ISO 字符串时允许它发生。