I'm working on a pdf form and trying to calculate hours from 2 fields. As long as the time does not go past midnight (in 24-hour format), I get the correct response. Once it goes past midnight, I get a negative number. Is there a way to add 24 hours to the returned value if it gives a negative number?
Here's what the field is being calculated as
var startTime = this.getField("SHIFT STARTRow1").value;
var endTime = this.getField("SHIFT ENDRow1").value;
this.getField("TOTAL HOURSRow1").value = timeDiff(startTime, endTime);
if ((event.value == "") || (event.value == Infinity) || isNaN(event.value)) {event.value = "";}
And here is the form javascript - timeDiff
function timeDiff(startTime, endTime) {
var startArr = startTime.split(":");
var endArr = endTime.split(":");
var startDate = new Date(0, 0, 0, startArr[0], startArr[1], 0);
var endDate = new Date(0, 0, 0, endArr[0], endArr[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = diff / 1000 / 60 / 60;
return hours.toFixed(2)
}
console.log(timeDiff('6:24', '8:13')) // 1.82
So using this script, if I type in 12:30 as the start time and 01:45 as the end time, I get a return of -10.75. However, I need a return of 13.25.
I attempted to find another thread that helped me with this, but maybe I overlooked it. Any help?
Example
If end hour is less than start, add 24
function timeDiff(startTime, endTime) {
var startArr = startTime.split(":").map(Number);
var endArr = endTime.split(":").map(Number);
if (startArr[0] > endArr[0]) {
endArr[0] += 24;
}
var hours = endArr[0] + endArr[1]/60 - startArr[0] - startArr[1]/60;
return hours.toFixed(2)
}
console.log(timeDiff('23:10', '1:00'))
Is there a way to add 24 hours to the returned value if it gives a negative number?
Well, yes –
if(hours < 0) hours += 24;
Related
It amazes me that JavaScript's Date object does not implement an add function of any kind.
I simply want a function that can do this:
var now = Date.now();
var fourHoursLater = now.addHours(4);
function Date.prototype.addHours(h) {
// How do I implement this?
}
I would simply like some pointers in a direction.
Do I need to do string parsing?
Can I use setTime?
How about milliseconds?
Like this:
new Date(milliseconds + 4*3600*1000 /* 4 hours in ms */)?
This seems really hackish though - and does it even work?
JavaScript itself has terrible Date/Time API's. Nonetheless, you can do this in pure JavaScript:
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
Date.prototype.addHours= function(h){
this.setHours(this.getHours()+h);
return this;
}
Test:
alert(new Date().addHours(4));
The below code will add 4 hours to a date (example, today's date):
var today = new Date();
today.setHours(today.getHours() + 4);
It will not cause an error if you try to add 4 to 23 (see the documentation):
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly
It is probably better to make the addHours method immutable by returning a copy of the Date object rather than mutating its parameter.
Date.prototype.addHours= function(h){
var copiedDate = new Date(this.getTime());
copiedDate.setHours(copiedDate.getHours()+h);
return copiedDate;
}
This way you can chain a bunch of method calls without worrying about state.
The version suggested by kennebec will fail when changing to or from DST, since it is the hour number that is set.
this.setUTCHours(this.getUTCHours()+h);
will add h hours to this independent of time system peculiarities.
Jason Harwig's method works as well.
Get a date exactly two hours from now, in one line.
You need to pass milliseconds to new Date.
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
or
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
let nowDate = new Date();
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
console.log('now', nowDate);
console.log('expiry', expiryDate);
console.log('expiry 2', expiryDate2);
You can use the Moment.js library.
var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
I also think the original object should not be modified. So to save future manpower here's a combined solution based on Jason Harwig's and Tahir Hasan answers:
Date.prototype.addHours= function(h){
var copiedDate = new Date();
copiedDate.setTime(this.getTime() + (h*60*60*1000));
return copiedDate;
}
If you would like to do it in a more functional way (immutability) I would return a new date object instead of modifying the existing and I wouldn't alter the prototype but create a standalone function. Here is the example:
//JS
function addHoursToDate(date, hours) {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
//TS
function addHoursToDate(date: Date, hours: number): Date {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
let myDate = new Date();
console.log(myDate)
console.log(addHoursToDate(myDate,2))
There is an add in the Datejs library.
And here are the JavaScript date methods. kennebec wisely mentioned getHours() and setHours();
Check if it’s not already defined. Otherwise, define it in the Date prototype:
if (!Date.prototype.addHours) {
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
}
This is an easy way to get an incremented or decremented data value.
const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour
const _date = new Date(date)
return new Date(_date.getTime() + inc)
return new Date(_date.getTime() + dec)
Another way to handle this is to convert the date to unixtime (epoch), then add the equivalent in (milli)seconds, then convert it back. This way you can handle day and month transitions, like adding 4 hours to 21, which should result in the next day, 01:00.
SPRBRN is correct. In order to account for the beginning/end of the month and year, you need to convert to Epoch and back.
Here's how you do that:
var milliseconds = 0; //amount of time from current date/time
var sec = 0; //(+): future
var min = 0; //(-): past
var hours = 2;
var days = 0;
var startDate = new Date(); //start date in local time (we'll use current time as an example)
var time = startDate.getTime(); //convert to milliseconds since epoch
//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24*days);
var newDate = new Date(newTime); //convert back to date; in this example: 2 hours from right now
Or do it in one line (where variable names are the same as above:
var newDate =
new Date(startDate.getTime() + millisecond +
1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
For a simple add/subtract hour/minute function in JavaScript, try this:
function getTime (addHour, addMin){
addHour = (addHour ? addHour : 0);
addMin = (addMin ? addMin : 0);
var time = new Date(new Date().getTime());
var AM = true;
var ndble = 0;
var hours, newHour, overHour, newMin, overMin;
// Change form 24 to 12 hour clock
if(time.getHours() >= 13){
hours = time.getHours() - 12;
AM = (hours>=12 ? true : false);
}else{
hours = time.getHours();
AM = (hours>=12 ? false : true);
}
// Get the current minutes
var minutes = time.getMinutes();
// Set minute
if((minutes + addMin) >= 60 || (minutes + addMin) < 0){
overMin = (minutes + addMin) % 60;
overHour = Math.floor((minutes + addMin - Math.abs(overMin))/60);
if(overMin < 0){
overMin = overMin + 60;
overHour = overHour-Math.floor(overMin/60);
}
newMin = String((overMin<10 ? '0' : '') + overMin);
addHour = addHour + overHour;
}else{
newMin = minutes + addMin;
newMin = String((newMin<10 ? '0' : '') + newMin);
}
// Set hour
if((hours + addHour >= 13) || (hours + addHour <= 0)){
overHour = (hours + addHour) % 12;
ndble = Math.floor(Math.abs((hours + addHour)/12));
if(overHour <= 0){
newHour = overHour + 12;
if(overHour == 0){
ndble++;
}
}else{
if(overHour == 0){
newHour = 12;
ndble++;
}else{
ndble++;
newHour = overHour;
}
}
newHour = (newHour<10 ? '0' : '') + String(newHour);
AM = ((ndble + 1) % 2 === 0) ? AM : !AM;
}else{
AM = (hours + addHour == 12 ? !AM : AM);
newHour = String((Number(hours) + addHour < 10 ? '0': '') + (hours + addHour));
}
var am = (AM) ? 'AM' : 'PM';
return new Array(newHour, newMin, am);
};
This can be used without parameters to get the current time:
getTime();
Or with parameters to get the time with the added minutes/hours:
getTime(1, 30); // Adds 1.5 hours to current time
getTime(2); // Adds 2 hours to current time
getTime(0, 120); // Same as above
Even negative time works:
getTime(-1, -30); // Subtracts 1.5 hours from current time
This function returns an array of:
array([Hour], [Minute], [Meridian])
If you need it as a string, for example:
var defaultTime: new Date().getHours() + 1 + ":" + new Date().getMinutes();
I think this should do the trick
var nextHour = Date.now() + 1000 * 60 * 60;
console.log(nextHour)
You can even format the date in desired format using the moment function after adding 2 hours.
var time = moment(new Date(new Date().setHours(new Date().getHours() + 2))).format("YYYY-MM-DD");
console.log(time);
A little messy, but it works!
Given a date format like this: 2019-04-03T15:58
//Get the start date.
var start = $("#start_date").val();
//Split the date and time.
var startarray = start.split("T");
var date = startarray[0];
var time = startarray[1];
//Split the hours and minutes.
var timearray = time.split(":");
var hour = timearray[0];
var minute = timearray[1];
//Add an hour to the hour.
hour++;
//$("#end_date").val = start;
$("#end_date").val(""+date+"T"+hour+":"+minute+"");
Your output would be: 2019-04-03T16:58
The easiest way to do it is:
var d = new Date();
d = new Date(d.setHours(d.getHours() + 2));
It will add 2 hours to the current time.
The value of d = Sat Jan 30 2021 23:41:43 GMT+0500 (Pakistan Standard Time).
The value of d after adding 2 hours = Sun Jan 31 2021 01:41:43 GMT+0500 (Pakistan Standard Time).
I run a landscape crew and instead of filling out our forms manually I would like to do it via cellphone and have the times auto-calculated in the form fields. I'm not familiar with JavaScript and need some assistance in getting the correct code in order to calculate the crew times and total site man-hours without this error when I change the times. Note: I will use 24-hour time.
I tried a few different JavaScript snippets I discovered and though they work I am getting a format error when manipulating the time input. Any suggestions on how to script this into Adobe?
To generate the employee times I use the code below:
UPDATE EDIT THIS IS GENERATING INCORRECT TIMES:
// start
var start = this.getField("Monday Site #1 Start Time").value;
var startArr = start.split(":");
// finish
var finish = this.getField("Monday Site #1 Depart Time").value;
var finishArr = finish.split(":");
// difference
var hourDiff = Math.abs(finishArr[0] - startArr[0]);
var minDiff = Math.floor((Math.abs(finishArr[1] - startArr[1]) / 60)*100);
if (minDiff.toString().length == 1)
minDiff = '0' + minDiff;
var output = hourDiff + "." + minDiff;
event.value = output;
if ((event.value == "") || (event.value == Infinity) || isNaN(event.value)) {
event.value = "";}
To calculate the total site time (total manhours for the specific site) I used this:
var t1 = this.getField("WS1 Total").value;
var t2 = this.getField("WS1 Total").value;
var t3 = this.getField("WS1 Total").value;
event.value = t1+t2+t3
You can calculate the elapsed time between two Javascript Date objects in milliseconds like this:
function timeDiff(startTime, endTime) {
var startArr = startTime.split(":");
var endArr = endTime.split(":");
var startDate = new Date(0, 0, 0, startArr[0], startArr[1], 0);
var endDate = new Date(0, 0, 0, endArr[0], endArr[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = Math.floor(diff / 1000 / 60 / 60);
diff -= hours * 1000 * 60 * 60;
var minutes = Math.floor(diff / 1000 / 60);
return hours + ":" + (minutes < 9 ? "0" : "") + minutes;
}
console.log(timeDiff('6:24', '8:13')) // 1:49
Or if you want to return hours as decimal.
function timeDiff(startTime, endTime) {
var startArr = startTime.split(":");
var endArr = endTime.split(":");
var startDate = new Date(0, 0, 0, startArr[0], startArr[1], 0);
var endDate = new Date(0, 0, 0, endArr[0], endArr[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var hours = diff / 1000 / 60 / 60;
return hours.toFixed(2)
}
console.log(timeDiff('6:24', '8:13')) // 1.82
I'm guessing that you can then do something like this:
var finish = this.getField("Monday Site #1 Depart Time").value;
var start = this.getField("Monday Site #1 Start Time").value;
this.getField("MS1T").value = timeDiff(start, finish);
This worked, with a tweak for NaN:
var start = this.getField("Monday Site #1 Depart Time").value;
var finish = this.getField("Monday Site #2 Depart Time").value;
this.getField("MS1 Total").value = timeDiff(start, finish);
if ((event.value == "") || (event.value == Infinity) || isNaN(event.value)) {event.value = "";}
I have two Time Stamps in the following Format:
Start Time - 2016-01-01 00:00:00
Finish Time - 2016-01-02 23:15:00
I need to calculate the number of hours between the two date times correct to two decimal places.
I need the result to be in the following format
Hrs = 47.25
This would be 23 hours and .25 of an hour not 25 mins, I do not need to round to the nearest 15 I only need to round to 2 decimal places.
Any Help shall be much appreciated. This data will then be inserted back into a cell in a DHTMLX grid.
FINAL SOLUTION
adminGrid.attachEvent("onEditCell",function(stage,rId,cInd,nValue,oValue){
if ((cInd == colStartTime || cInd == colFinishTime) && stage == 2) {
var startTime = new Date(adminGrid.cells(rId,colStartTime).getValue());
var finishTime = new Date(adminGrid.cells(rId,colFinishTime).getValue());
var Hrs = ((finishTime - startTime)/1000/60/60).toFixed(2);
adminGrid.cells(rId,colHrs).setValue(Hrs);
}
return true;
});
var startDate = new Date('2016-01-01 00:00:00');
var endDate = new Date('2016-01-02 23:15:00');
var time = endDate - startDate;
console.log(time/1000/60/60%24); //23.25
like this can calculate the hours span.
var date1 = new Date("2016-01-01 00:00:00");
var date2 = new Date("2016-01-02 23:15:00");
var diff = date2.getTime() - date1.getTime();
var Hrs = diff / (1000 * 60 * 60);
console.log(Hrs);//It's 47.25.
I've tried and got 47.25.
Basically this script will subtract StartTime from EndTime, using a jQuery plugin the html form is populated with Start and End Time in the format HH:MM, an input field is populated with the result, it works except for one issue:
If Start Time is between 08:00 and 09:59 it just returns strange results - results are 10 hours off to be precise, why?
All other inputs calculate properly!
function setValue() {
var startTime = document.getElementById('ToilA');
var endTime = document.getElementById('EndHours'); startTime = startTime.value.split(":");
var startHour = parseInt(startTime[0]);
var startMinutes = parseInt(startTime[1]);
endTime = endTime.value.split(":");
var endHour = parseInt(endTime[0]);
var endMinutes = parseInt(endTime[1]);
//var hours, minutes;
var today = new Date();
var time1 = new Date(2000, 01, 01, startHour, startMinutes, 0);
var time2 = new Date(2000, 01, 01, endHour, endMinutes, 0); var milliSecs = (time2 - time1);
msSecs = (1000);
msMins = (msSecs * 60);
msHours = (msMins * 60);
numHours = Math.floor(milliSecs/msHours);
numMins = Math.floor((milliSecs - (numHours * msHours)) / msMins);
numSecs = Math.floor((milliSecs - (numHours * msHours) - (numMins * msMins))/ msSecs); numSecs = "0" + numSecs; numMins = "0" + numMins; DateCalc = (numHours + ":" + numMins);
document.getElementById('CalculateHours').value = DateCalc; }
Whenever you have math problems with the number 8, it's something getting converted into the octal system :)
Numbers starting with 0 are interpreted as octal numbers in Javascript.
It's no problem from 01..07, because they are the same in both systems.
But 08 and 09 don't exist in the system, so they return 0.
Also see this question that also provides a solution: Specify the base parameter when doing the parseInt:
parseInt("09", 10); // base 10
For Example:
StartTime = '00:10';
EndTIme = '01:20';
These variables are string
Question: How can I Subtract them and returning the span time in minutes?
Hope you can help
Make a function to parse a string like that into minutes:
function parseTime(s) {
var c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
Now you can parse the strings and just subtract:
var minutes = parseTime(EndTIme) - parseTime(StartTime);
var startTime = "0:10";
var endTime = "1:20";
var s = startTime.split(':');
var e = endTime.split(':');
var end = new Date(0, 0, 0, parseInt(e[1], 10), parseInt(e[0], 10), 0);
var start = new Date(0, 0, 0, parseInt(s[1], 10), parseInt(s[0], 10), 0);
var elapsedMs = end-start;
var elapsedMinutes = elapsedMs / 1000 / 60;
If you're going to be doing a lot of date/time manipulation, it's worth checking out date.js.
However, if you're just trying to solve this one problem, here's an algorithm off the top of my head.
(1)Parse start/end values to get hours and minutes, (2)Convert hours to minutes, (3)Subtract
function DifferenceInMinutes(start, end) {
var totalMinutes = function(value) {
var match = (/(\d{1,2}):(\d{1,2})/g).exec(value);
return (Number(match[1]) * 60) + Number(match[2]);
}
return totalMinutes(end) - totalMinutes(start);
}
dojo.date.difference is built for the task - just ask for a "minute" interval.
Get the difference in a specific unit of time (e.g., number of months, weeks, days, etc.) between two dates, rounded to the nearest integer.
Usage:
var foo: Number (integer)=dojo.date.difference(date1: Date, date2: Date?, interval: String?);