Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Calculate difference between 2 durations

Posted on 2016-08-18
11
47 Views
Last Modified: 2016-08-22
I have a web page where the user can enter times - such as "34.56" (34 seconds, 56 hundredths), "1:07.32" (1 minute, 7 seconds, 32 hundredths), up to 59:59.99.

For each input field there is a defined "Minimum" and "Maximum" allowed time, in the same format as above.

I want to validate that the entered time is within the Minimum / Maximum time range.

I am trying to use the "duration" feature in moment.js - but I can't get it to work, nor can I find enough information about "durations".

I have this:

        
$('.timeInput').blur(function () {
    var enteredVal = $(this).val();
    if (enteredVal == '') return;

    var mReq = moment.duration("40.99");
    var mEnteredVal = moment.duration(enteredVal);
    var timeDiff = mEnteredVal.asMilliseconds - mReq.asMilliseconds;

    if (timeDiff > 0) {
        alert("Greater than");
    } else {
        alert("Less Than");
    }
}

Open in new window


However, it doesn't work. The above is a test version that just checks if the entered time is greater than the mReq value. Once I've got that working, I will extend it to check the time is within the min / max values.

The min and max values will eventually come from hidden fields on the page.
0
Comment
Question by:ascendinternet
  • 5
  • 5
11 Comments
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 41762011
First, make sure your spelling is exact and also your closing brackets match.  I don't think yours did and that may be from copy/pasting.

  1. Convert input to a number
  2. Declare variable you want to test against
  3. Use duration of minutes
  4. Compare entered value against your test variable

http://jsbin.com/sozifuxavo/edit?html,output
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <input class="timeInput" placeholder="TimeInput">
  <input>
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>
<script>
  $(function(){ 
  $('.timeInput').blur(function () {
    var enteredVal = $(this).val();
    enteredVal = Number(enteredVal); // convert tonumber
    var testVal = moment.duration(49.99, 'minutes');
    newEnteredVal=moment.duration(enteredVal,'minutes');
    alert(newEnteredVal + ' : '+ testVal);
    if(newEnteredVal > testVal){
      alert('greater than');
    } else {
      alert( 'less than');
    }
    
    });
    
});
  </script>
</body>
</html>

Open in new window

0
 

Author Comment

by:ascendinternet
ID: 41762052
Sorry, the code in my post was only part of the code I had, so I may have missed a bracket or two!

I don't understand why I should use a duration of minutes - the times entered might be minutes, seconds and hundredths (e.g. 1:07.43) - or might just be seconds and hundredths (e.g. 34.59)

Your sample works for seconds and hundredths (34.59) but not if it goes to minutes (1:07.43).
0
 
LVL 52

Accepted Solution

by:
Scott Fell,  EE MVE earned 500 total points
ID: 41762103
Using duration, you need to make sure your comparison matches.

http://jsbin.com/beyakixuca/1/edit?html,output
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div></div>
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>
<script>
  $(function(){ 
    var x = moment.duration('23:59:30.2');
    var y = moment.duration('24:00:24.2');
    if (x > y){
      $('div').text('greater');
    } else {
       $('div').text('less');
    }

    
});
  </script>
</body>
</html>

Open in new window

0
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 

Author Comment

by:ascendinternet
ID: 41762113
By "you need to make sure your comparison matches" - do you mean the format of the time needs to match?

Sometimes, the min / max values might only be seconds & hundredths, sometimes it will be minutes, second and hundredths - so the formatting needs to be dynamic / flexible!?

Is there another / easier way to do it, without using moment.js?
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 41762123
One way or another, you will need to know if "23" is an hour, minute, second or fraction or just a great center.

If you are presented with "21.5" you may assume that is 21 seconds and 5 tenths.  So format that as "0:00:21.5"

What you can't do is see a 1 and 21 and let the black box figure out the user meant the 1 as an hour and 21 as minutes.  It is up to you to format the data no matter if you use moment or pure javascript date.
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 41762129
To clarify,

<input value ="1">  then compare against 40.99 where the user meant 1 as an hour and your comparison is against 40 seconds and 99 tenths.
0
 

Author Comment

by:ascendinternet
ID: 41762222
Sorry, I have already dealt with formatting the input, so if you type 4099 it gets formatted as "40.99", if you type 10765 it gets formatted as "1:07.65".

I will need to deal with "stupid" inputs like "1" or "999999" but for now, I want to get it working for valid inputs.
0
 

Author Comment

by:ascendinternet
ID: 41762933
OK, I now have this which appears to be working:

        $('.timeInput')
            .blur(function () {
                var enteredVal = $(this).val().toString();
                if (enteredVal == '') return;

                var inputId = this.id;
                var fromVal = $('#from_' + inputId).val().toString();
                var toVal = $('#to_' + inputId).val().toString();

                var mReqFrom = moment.duration(PadString(fromVal));
                var mReqTo = moment.duration(PadString(toVal));
                var mEnteredVal = moment.duration(PadString(enteredVal));
                var statusIcon = $('#status_' + inputId);
                if (mEnteredVal >= mReqFrom && mEnteredVal <= mReqTo) {
                    statusIcon.attr("class", "fa fa-check");
                } else {
                    statusIcon.attr("class", "fa fa-times");
                }
            });

        function PadString(strTime) {
            var pattern = "00:00:00.00";

            var timeLen = strTime.length;

            return pattern.substr(0, pattern.length - timeLen) + strTime;
        }

Open in new window


The HTML input tag has a maxlength="8". Also the input is formatted using this plugin - http://igorescobar.github.io/jQuery-Mask-Plugin/ (code not shown).

Can the code be improved, for safety and/or performance and/or code reduction purposes?
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 41763323
>Can the code be improved, for safety

This is all client side.  If you are eventually going to use this to post data to your db, you want to make sure you scrub and check data server side even if you validate on the client.

>Can the code be improved, for performance and/or code reduction purposes
If it is working, go with it.  In production you will want to compress all your javascript/jquery code.  I'm sure there are some things that can be done to make this more efficient like using pure js.  For the the likes of Google and Facebook, small changes can make a very big difference.   For your purposes, you may find the page will load almost the same expanded like this or minified.
0
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41763624
You can also just use a custom function to convert to milliseconds - a lot smaller than including the entire moment.js library
function timeToMS(value) 
{
  var current = min = sec = 0;
  for(var i = 0; i < value.length; i++) {
    c = value[i];
    if (c == ':') {
      min = current;
      current = 0;
    }
    else if (c == '.') {
      sec = current;
      current = 0;
    }
    else {
	  current = current * 10 + c * 1;
    }
  }
  
  return (min*60000 + sec * 1000 + current);
}

Open in new window

Working sample here
0
 

Author Closing Comment

by:ascendinternet
ID: 41764861
The key issue turned out to be that the format of the comparisons needed to match. I ensured both values were formatted to "00:00:00.000".
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to resize a div in html 3 38
IFrame in MVC 2 23
jquery check value of radiobutton and checkboxlist 3 29
JS Event Does not Trigger From File 2 28
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

837 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question