javascript - Is there a built in way to normalize a duration within Luxon? - Stack Overflow

I am migrating from Momentjs to Luxon. I allow users to pick a number of hours that a task will take. W

I am migrating from Momentjs to Luxon. I allow users to pick a number of hours that a task will take. When we save this value, I'd like it to normalize. So if a task takes 90 hours, I would prefer if we stored 3 days and 18 hours. I store the ISO Duration String so I'd like to convert PT90H to P3DT18H... of course with any given value.

I have tried Luxon's normalize function, I tried to call it like so:

const duration = Duration.fromObject({ hours: 90 });
duration.normalize().toISO();

However, normalize does not seem to do anything to the result. I still get PT90H. Is there a built in way to do this with Luxon?

I am migrating from Momentjs to Luxon. I allow users to pick a number of hours that a task will take. When we save this value, I'd like it to normalize. So if a task takes 90 hours, I would prefer if we stored 3 days and 18 hours. I store the ISO Duration String so I'd like to convert PT90H to P3DT18H... of course with any given value.

I have tried Luxon's normalize function, I tried to call it like so:

const duration = Duration.fromObject({ hours: 90 });
duration.normalize().toISO();

However, normalize does not seem to do anything to the result. I still get PT90H. Is there a built in way to do this with Luxon?

Share Improve this question asked Dec 14, 2021 at 13:28 nephiwnephiw 2,04620 silver badges42 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Durtation.normalize() won't add properties to the Duration object so you need to supply the units you want it to normalize to. (This is odd to me, but provides implicit control over oute).

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./ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>

Alternatively you can use Duration.shiftTo() to explicitly force the duration into specific units.

const duration = Duration
  .fromObject({hours: 90 })
  .shiftTo('days', 'hours')
  .toISO();

console.log(duration);
<script src="https://cdnjs.cloudflare./ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>


If you know you will always want to normalize into all units you could declare a utility to return a Duration object initialized with all units.

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./ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>

Per @pilchard's answer, I ended up using this function to normalize my duration.

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./ajax/libs/luxon/2.2.0/luxon.min.js"></script>
<script>const { Duration } = luxon;</script>

[EDIT] The step that filters out 0'ed units is unneeded for my stated goals, the toISO method does this for us. My needs related to making spec's pass, and it seems like it will be better change the specs than waste the CPU cycles normalizing during calculations. Using the above method will make the resulting ISO duration strings normalized units - PT1H30M instead of PT90M.

In the end I chose not to use the 0-unit filtering and just allow that to happen when I convert it to an ISO string.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745667884a4639225.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信