Transform seconds into an ISO 8601 duration using JavaScript

Dealing with ISO 8601 durations can be quite tricky.

Efficiently converting seconds to durations is my current challenge, especially in JavaScript.

Stay tuned for my solution and the Jest test script coming up next.

Answer №1

Converting Seconds to Duration

export const SECONDS_PER_SECOND = 1;
export const SECONDS_PER_MINUTE = 60;
export const SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
export const SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;

const timeUnits = [
  ['D', SECONDS_PER_DAY],
  ['H', SECONDS_PER_HOUR],
  ['M', SECONDS_PER_MINUTE],
  ['S', SECONDS_PER_SECOND],
];

export default function secondsToDuration(seconds) {
  let duration = 'P';
  let remainder = seconds;

  timeUnits.forEach(([unit, value]) => {
    const timeValue = Math.floor(remainder / value);

    remainder = remainder % value;

    if (timeValue) {
      duration += `${timeValue}${unit}`;
    }
  });

  if (duration == 'P') {
    duration = 'P0S';
  }

  return duration;
}

Testing the Conversion with Jest

import secondsToDuration, {
  SECONDS_PER_SECOND,
  SECONDS_PER_MINUTE,
  SECONDS_PER_HOUR,
  SECONDS_PER_DAY,
} from './seconds-to-duration';

describe('secondsToDuration', () => {
  describe('handling even units', () => {
    it('should handle days', () => {
      let i = 10;

      while (--i) {
        expect(secondsToDuration(SECONDS_PER_DAY * i)).toEqual(`P${i}D`);
      }
    });

    it('should handle hours', () => {
      let i = 10;

      while (--i) {
        expect(secondsToDuration(SECONDS_PER_HOUR * i)).toEqual(`P${i}H`);
      }
    });

    it('should handle minutes', () => {
      let i = 10;

      while (--i) {
        expect(secondsToDuration(SECONDS_PER_MINUTE * i)).toEqual(`P${i}M`);
      }
    });

    it('should handle seconds', () => {
      let i = 10;

      while (--i) {
        expect(secondsToDuration(SECONDS_PER_SECOND * i)).toEqual(`P${i}S`);
      }
    });

    it('should handle zero seconds', () => {
      expect(secondsToDuration(0)).toEqual('P0S');
    });
  });

  describe('handling uneven time units', () => {
    it('should break across periods', () => {
      let days = 2;

      while (days--) {
        let hours = 24;

        while (hours--) {
          let minutes = 60;

          while (minutes--) {
            testDuration({ days, hours, minutes, seconds: 59 });
            testDuration({ days, hours, minutes, seconds: 1 });
          }
        }
      }
    });
  });
});

function testDuration({ days, hours, minutes, seconds }) {
  const totalSeconds =
    days * SECONDS_PER_DAY +
    hours * SECONDS_PER_HOUR +
    minutes * SECONDS_PER_MINUTE +
    seconds * SECONDS_PER_SECOND;
  const expected = `P${days}D${hours}H${minutes}M${seconds}S`.replace(/(?<=\D)0\w/g, '');
  const result = secondsToDuration(totalSeconds);

  if (result != expected) {
    console.info({ totalSeconds, expected, result });
  }

  expect(result).toEqual(expected);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Javascript to load and parse data retrieved from an HTTP request

Within my application, a server with a rest interface is utilized to manage all database entries. Upon user login, the objective is to load and map all user data from database models to usable models. A key distinction between the two is that database mode ...

Check if the provided arguments in JavaScript are arrays and, if they are, combine them into a single large array

My array variables are as follows: const gumBrands = ['orbit', 'trident', 'chiclet', 'strident']; const mintBrands = ['altoids', 'certs', 'breath savers', 'tic tac']; Presen ...

A step-by-step guide on bringing in objects in JavaScript and Node.js

Let's say we have a file called main2.js exports.obj = { x: 10, setX: function(y) { this.x = y; }, getX: function() { return this.x; } }; Now, we also have two other files: abc.js const obj = require("./main2").o ...

Design your very own personalized Show Layout component

Currently, I'm in the process of creating a unique layout component to enhance the design of my Show page. I've encountered some inconsistencies with functionality, and my solution involves utilizing the Material-UI <Grid> component. While ...

The Angular Material md-input-container consumes a significant amount of space

Currently, I am exploring a sample in Angular Material. It appears that the md-input-container tag is taking up a substantial amount of space by default. The output is shown below: However, I have come across the md-input-content tag, which occupies less ...

How to access nested JSON elements in Javascript without relying on the eval function

Below is a JSON that I am trying to access. { "orders": { "errorData": { "errors": { "error": [ { "code": "ERROR_01", "description": "API service is down" } ] } }, "status": " ...

Streamline a javascript code with numerous elements

Seeking assistance in simplifying this code Currently, I find myself constantly updating this code each time a new entry is uploaded. I am looking for a solution where there is a single script that can identify the element IDs ("#rolly" or "#lagrimas") a ...

Is it possible to manage how many times a functional react component re-renders based on changes in its state?

For my practice e-commerce app, I have a functional component called "Shop" with two states: [products, setProducts] = useState([10ProductObjects]) and [cart, setCart] = useState([]) Upon the initial render, 10 products are loaded and each Product compone ...

Locate all inputs containing a special attribute name, wherein a portion of the name corresponds to a JavaScript variable

$("td[id^='td' + myvar + '_']") Can someone help me with a solution to substitute the static value of 0 in this code snippet with the dynamic variable myvar? Thanks! ...

Automate your functions using Javascript!

Hello, I have written a code snippet that triggers an action on mouse click. Initially, I created a function that scrolls the screen to a specific element upon clicking another element: (function($) { $.fn.goTo = function() { $('html, bo ...

Ways to expose a components prop to its slotted elements

I've set up my structure as follows: <childs> <child> <ul> <li v-for="item in currentData">@{{ item.name }}</li> </ul> </child> </childs> Within the child component, t ...

What is the best way to showcase a unique quote right when the webpage is opened?

I'm currently developing a random quote application. I want the quote to be displayed when the page loads instead of waiting for the user to click a button. I've tried invoking a function, but it's not working as expected. Any advice would b ...

Is jQuery Autocomplete functioning properly on outdated browsers, but not on newer ones?

Here is the JSON data I have for my auto complete feature { "list" : [ { "genericIndicatorId" : 100, "isActive" : false, "maxValue" : null, "minValue" : null, "modificationDate" : 1283904000000, "monotone" : 1, "name":"Abbau", ...

Adjusting element position while scrolling

Objective The goal is to have the page navigation display lower on the page by default. This will provide a cleaner layout as shown in the image below. Context An interactive element for navigation was implemented utilizing Headroom.js. This library d ...

Struggles encountered while developing a JavaScript calendar

Hey guys, I'm encountering an issue with Uncaught TypeError: document.getElementById(...) is null. I believe the problem lies in the way types are being parsed for document.getElementById(dayOfWeek).appendChild(dayPTag);. This code is meant to display ...

Animate the leftward disappearance of a div to make it vanish

My goal is to create a user interface where users can navigate through different divs. Here is the HTML code: <article id="realize" class="realizeBox"> <div class="shown"> <div class="heading"> <h2>Realisati ...

Module fails to load in the proper sequence

As a .NET developer who is relatively new to modern client-side web applications, I am currently working on developing an Angular2 charting application using Chart.js. The modules are being loaded with SystemJS. Below is the content of my systemjs.config. ...

Assign a value to a HubSpot hidden form field by utilizing Javascript

I have a snippet of JavaScript code placed in the head section of my website: <!-- Form ID Setter --> <script> document.querySelector('input[name=form_submission_id]').value = new Date(); </script> My objective is to automat ...

Execute a function with parameters when a button is clicked dynamically using PHP

I am trying to execute a parameterised function in PHP using AJAX. Below is the code snippet of my dynamic button where I need to pass $sub_id to the delet(sub_id) function for executing some SQL: echo "<td><input type='submit' name=&a ...

Change a reactive variable based on an event

I am currently working on a file upload feature in my application. Template.uploadFile.events({ 'change .set-file': function ( event, template ) { var file = event.currentTarget.files[0]; [...] } }); My goal is to read each row fro ...