How to display duration time with moment-duration-format in an app developed by Typescript like Next.js and Angular?
When you handle time in Front-end, sometime you need to process duration time. I give you an example as below:
🤔Example :
You want to display store opening hours in your application. The value for opening and closing hours as seconds.
Value: number, as seconds past midnight, e.g. 28800 = 8 am, 45000 = 12:30 pm and max value is 86399 = 11:59:59 pm .
💡One solution is using moment.js and durations format with moment-duration-format plugin
What is moment.js duration?
Moment.js also has duration objects. Where a moment is defined as single points in time, durations are defined as a length of time. Durations do not have a defined beginning and end date. They are contextless. https://momentjs.com/docs/#/durations/
You can use it like below. It looks pretty easy!
moment.duration(123, "minutes").format("h:mm"); // "2:03"
🤔But with Typescript, you will see the following error:
Property 'format' does not exist on type 'Duration'.ts(2339)
How to use moment.js durations rightly?
Check this article for better codes view experience.
Install dependencies:
yarn add moment-duration-format
yarn add @types/moment-duration-format
Config type in tsconfig.js
Add “@types/moment-duration-format” type to compilerOptions.
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"types": [
"@types/moment-duration-format",
"@types/jest"
],
"allowJs": true,
"skipLibCheck": true,
...
}
...
}
Use moment.duration() in codes
Let us use React Hooks as an example.
You need to import moment and moment-duration-format, firstly.
import moment from 'moment';
import 'moment-duration-format';
Then, use duration function. Let us apply above example: 28800 = 8 am.
moment.duration(28800, "seconds").format("h:mm a");
🎉Well, you do not have above type error. 🤔Do you get a right value 8:00 am ? No…, the value you get is 8:00 a. Moment.js format is not working as it is supposed.
💡The solution is that transform seconds to milliseconds and use UTC time.
moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')
All right we get 8:00 am now. If you want 8 am instead of 8:00 am for integral time, we need to do RegExp.
const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
import React from 'react';
import moment from 'moment';
import 'moment-duration-format';
interface DurationHours {
durations: number;
}
const DurationHours: React.FunctionComponent<DurationHours> = ({ durations }) => {
const displayDurations = (durations: number): string => {
return moment.utc(moment.duration(durations, 'seconds').asMilliseconds()).format('h:mm a');
};
return (
<div>
{displayDurations(durations)}
</div>
);
};
export default DurationHours;