subtracting one time from another - javascript

I have had a good search for what I'm looking for but can't seem to find exactly what I need. I'm new to jQuery and JavaScript.
All I want to do is subtract one 24 hour clock time from another to find how many hours have been allocated using JQuery or JavaScript i.e. start time: 12:00 end time: 16:00 would be 4 hours.
How would I go about doing this without having issues when going from say 12:00 till 12:00 the following day?
I am not dealing with with dates, just time.
Currently the times are stored like this as part of an object with start_time end_time:
var shift = {'location':$('#shift_location').val(),
'shift_date': $('#shift_date').val(),
'start_time':$('#shift_start_time').val(),
'end_time':$('#shift_end_time').val()
};
var shift_list = JSON.parse(localStorage.shift);
shift_list.push(shift);
localStorage.shift = JSON.stringify(shift_list);

With the given information i.e start_time and end_time there is no way you can cover multiple days. They just oscillate between 0 to 23 hours. There is no counter involved to calculate multiple days. if you need that you need two more states which will store start_date and end_date which will act as counter as pointed by #John Boker. But if you are sure that the difference never goes beyond 24 hours then we can use the parseTime from JAVASCRIPT: subtracting Time and getting its number of minutes function with our own little modifications.
function parseTime(s) {
var c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
var limit = parseTime("23:59");
function getDiff(start_time, end_time){
var a = parseTime(start_time), b = parseTime(end_time);
if(b < a) // means its the next day.
return Math.round((limit - a + b)/60);
else if(b > a)
return Math.round((b - a)/60);
else if(b - a == 0)
return 24.0;
else
alert("Invalid data");
}
alert(getDiff("12:00", "11:00"));

You can use momentjs to do things with dates in javascript.
Example (moment doc, fiddle):
var start_time = "12:00";
var end_time = "16:00";
var start = moment.duration(start_time, 'h');
var end = moment.duration(end_time, 'h');
alert(end.subtract(start).hours()); // 4
Of course, because of the simplicity of the task you could always use plain javascript:
var start_time = "12:00";
var end_time = "16:00";
alert(parseInt(end_time, 10) - parseInt(start_time, 10)); // 4

Related

Check if specified time is mentioned in an incremented time

Here are some of the variables I have:
start time: 10:45
interval time: 5 (in minutes)
specific time: 14:20
I need to find out if the specific time lands exactly on any of the times incremented from the start time.
For example, the interval time is 5.
10:45 incremented by interval time
11:00
11:05
11:10
...
14:20 << specific time found
if(specificTime is mentioned in any of the incremented times) {
console.log('Found it!');
} else {
console.log('Not found');
}
But this is hard when the start time is 10:48 and the interval time is 5 minutes. Because:
10:48
10:53
10:58
11:03
11:08
...
and 14:20 is not mentioned in this one, so it would log "Not found".
How can I find out if the specific times is mentioned in the incremented times from the start time?
The interval time will not always be 5 and the other variables will be dynamic as well.
I am NOT looking to use loops. There has to be a formula or function that can help me achieve this. Thanks!
I think you can calculate if it is possible to perform a restless division of the difference between the start time and the specified time and the interval.
Depending on the scale of your time intervals, you can calculate this in hours, minutes, seconds, milliseconds or basically any scale. Since your examples deal in minutes, the code snippet also does.
Note that this snippet assumes both times are within the same day (00:00 - 24:00) and that the specific time is later within that day than the start time. I'll let you figure out the rest :)
function toMinutes(hours, minutes) {
return (hours * 60) + minutes;
}
const startTime = toMinutes(10, 45);
const specificTime = toMinutes(14, 20);
const interval = toMinutes(0, 5);
const difference = specificTime - startTime;
if (difference % interval === 0) {
console.info('Found it!');
console.info('Minutes:', difference);
console.info('Intervals:', difference / interval);
} else {
console.error('Not found');
}
This works by:
- Turning the time strings into numeric minutes (with countOfMinutes())
- Subtracting startTime from specificTime (and adjusting if we increment past 12:00)
- Dividing the result by minsPerIncrement and checking whether the remainder is zero
// The big payoff -- calculates whether we exactly hit `specificTime`
function isExact(start, specific, increment){
let difference = countOfMinutes(specific) - countOfMinutes(start);
if(difference <= 0){ difference += 12 * 60; } // Add 12 hours if necessary
return difference % increment == 0;
}
// The converter -- because numbers are easier to divide than strings
function countOfMinutes(timeString){
const hours = timeString.slice(0, timeString.indexOf(":"));
const mins = timeString.slice(timeString.indexOf(":") + 1);
return hours * 60 + mins;
}
// The results -- some readable output
function report(){
console.log(`
Repeatedly adding ${minsPerIncrement} to ${startTime} will eventually yield ${specificTime}?:
_ ${isExact(startTime, specificTime, minsPerIncrement)} _`);
}
// The pudding -- a couple of test cases
let start, specific, minsPerIncrement;
startTime = "12:30"; specificTime = "3:55"; minsPerIncrement = 21;
report();
startTime = "4:20"; specificTime = "11:45"; minsPerIncrement = 5;
report();
startTime = "11:45"; specificTime = "4:20"; minsPerIncrement = 5;
report();

How to display one item in an array each week

I am trying to create a memory verse a week program. I have code to display the item, but only with a delay for however long I want the code to wait before it changes items. How can I display one item at a time in an array for one week then go on to the next item without waiting a week for the delay? This is what I have now:
<p id="wfm"></p>
var mind = [];
var i = 0;
var wfmind = document.getElementById('wfm');
function next_verse() {
wfmind.innerHTML = mind[i % mind.length];
i += 1;
}
setInterval(next_verse, 1000);
You could use the current time as the index, which counts from 1970 rather than the arbitrary time the user entered the site.
As of writing, the current timestamp is 1493684749486.
var d = new Date();
// +d === 1493684749486
To convert the current timestamp into an array index, you need to know the number of milliseconds in a week (1000*60*60*24*7), then figure out how many weeks have passed since 1970.
var index = Math.floor(+d / (1000*60*60*24*7));
// 2469 weeks have passed since 1970
// output `mind[index]` now.
For the sake of the answer here, I'm going to assume you want to change the item on Friday at 9am. The next closest Friday at 9am is 1494000000000.
d.setMilliseconds(0);
d.setSeconds(0);
d.setMinutes(0);
d.setHours(9);
d.setDate(d.getDate() + (7 + 5 - d.getDay()) % 7); // How many days away is Friday from Monday? Add that to the current date.
That is 315250514 milliseconds away. You'll setTimeout this long to kick off the next change.
When the item changes, kick off a new timeout for the following change. This is preferred over setInterval.
function displayNextItem() {
var d = new Date();
var timestamp = +d;
var index = Math.floor(timestamp / (1000*60*60*24*7));
wfmind.innerHTML = mind[index % mind.length];
d.setMilliseconds(0);
d.setSeconds(0);
d.setMinutes(0);
d.setHours(9);
d.setDate(d.getDate() + (7 + 5 - d.getDay()) % 7); // How many days away is Friday from Monday? Add that to the current date.
setTimeout(displayNextItem, +d - timestamp);
}
displayNextItem();

Javascript - Age Verification

Hey javascript masters,
Attempting to create an age verification page to a client's site. Code below is not functioning as it doesn't matter what year you select, it will still allow you to enter the site. Not sure what I should be looking at to correct.
Any help is appreciated.
<script type="text/javascript"><!--
function checkAge(f){
var dob=new Date();
var date=dob.getDate();
var month=dob.getMonth() + 1;
var year=dob.getFullYear();
var cmbmonth=parseInt(document.getElementById("cmbmonth").options[document.getElementById("cmbmonth").selectedIndex].value);
var cmbday=parseInt(document.getElementById("cmbday").options[document.getElementById("cmbday").selectedIndex].value);
var cmbyear=parseInt(document.getElementById("cmbyear").options[document.getElementById("cmbyear").selectedIndex].value);
age=year-cmbyear;
if(cmbmonth>month){age--;}
else{if(cmbmonth==month && cmbday>=date){age--;}}
if(cmbmonth==0){alert("You must enter the month you were born in.");return false;}
else if(cmbday==0){alert("You must enter the day you were born on.");return false;}
else if(cmbyear==2005){alert("You must enter the year you were born in.");return false;}
else if(age<13){alert("You are unable to view this site!");location.replace("http://www.dharmatalks.org");return false;}
else{return true;}
}
// --></script>
Calculating age in years, months and days is a bit trickier than it should be due to the differences in month and year lengths. Here's a function that will return the difference between two dates in years, months, days, hours, minutes and seconds.
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
var timeDiff, years, months, days, hours, minutes, seconds;
// Get estimate of year difference
years = e.getFullYear() - s.getFullYear();
// Add difference to start, if greater than end, remove one year
// Note start from restored start date as adding and subtracting years
// may not be symetric
s.setFullYear(s.getFullYear() + years);
if (s > e) {
--years;
s = new Date(+start);
s.setFullYear(s.getFullYear() + years);
}
// Get estimate of months
months = e.getMonth() - s.getMonth();
months += months < 0? 12 : 0;
// Add difference to start, adjust if greater
s.setMonth(s.getMonth() + months);
if (s > e) {
--months;
s = new Date(+start);
s.setFullYear(s.getFullYear() + years);
s.setMonth(s.getMonth() + months);
}
// Get remaining time difference, round to next full second
timeDiff = (e - s + 999) / 1e3 | 0;
days = timeDiff / 8.64e4 | 0;
hours = (timeDiff % 8.64e4) / 3.6e3 | 0;
minutes = (timeDiff % 3.6e3) / 6e1 | 0;
seconds = timeDiff % 6e1;
return [years, months, days, hours, minutes, seconds];
}
You can abbreviate the above just after the year part and return just that if you want.
Note that in your code:
var cmbmonth=parseInt(document.getElementById("cmbmonth").options[document.getElementById("cmbmonth").selectedIndex].value);
can be:
var cmbmonth = document.getElementById("cmbmonth").value;
There is no need for parseInt, the Date constructor will happily work with string values. If you have used calendar month numbers for the values (i.e. Jan = 1) then subtract 1 before giving it to the Date constructor, but simpler to use javascript month indexes for the values (i.e. Jan = 0).
You can then do:
var diff = dateDifference(new Date(cmbyear, cmbmonth, cmbdate), new Date());
if (diff[0] < 18) {
// sorry, under 18
}

Javascript, how to find the difference between two datetimes in mysql timestamp style

Let's say I have
a = "2011-11-09 08:00:00"
b = "2011-11-10 08:30:00"
What's the best way of finding how many days, hours, minutes the difference between these two timestamps are in Javascript?
So the output should be "1 day" (ignore the minutes since there is a larger unit (day) in the difference) ?
The only reliable way to convert a string to a date in javascript is to parse it manually. If the format is consistent with what you have posted, then you can convert it to a date as follows:
function stringToDate(s) {
var dateParts = s.split(' ')[0].split('-');
var timeParts = s.split(' ')[1].split(':');
var d = new Date(dateParts[0], --dateParts[1], dateParts[2]);
d.setHours(timeParts[0], timeParts[1], timeParts[2])
return d
}
so you can do:
var a = "2011-11-09 08:00:00"
var b = "2011-11-10 08:30:00"
alert(stringToDate(a) - stringToDate(b));
to get the difference in milliseconds. However, the difference in days between two dates may not be a simple matter of dividing the difference by 8.64e7 (milliseconds in one da). You need to confirm the business logic in regard to that.
EDITED to work in any browser
var matchDate = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/;
var firstDateParsed = matchDate.exec("2011-11-09 08:00:00");
var secondDateParsed = matchDate.exec("2011-11-10 08:30:00");
var a = new Date(firstDateParsed[1], firstDateParsed[2], firstDateParsed[3], firstDateParsed[4], firstDateParsed[5], firstDateParsed[6], 0);
var b = new Date(secondDateParsed[1], secondDateParsed[2], secondDateParsed[3], secondDateParsed[4], secondDateParsed[5], secondDateParsed[6], 0);
var differenceInMilliseconds = a.getTime() - b.getTime();
// minutes
alert(differenceInMilliseconds / 1000 / 60);
// hours
alert(differenceInMilliseconds / 1000 / 60 / 60);
// days
alert(differenceInMilliseconds / 1000 / 60 / 60 / 24);
Tested in IE and Firefox as well as Chrome: http://jsfiddle.net/xkBTS/4/
You'll have to parse the timestamp to a date yourself:
function parseMySQLTimestamp(timestamp) {
var parts = timestamp.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
return new Date(+parts[1], (+parts[2] - 1), +parts[3], +parts[4], +parts[5], +parts[6]);
}
Get the difference in milliseconds by subtracting one date from the other:
var msDifference = parseMySQLTimestamp(b) - parseMySQLTimestamp(a);
Simple arithmetic will let you convert milliseconds to seconds, minutes, or whatever.
By the way, this function will throw an error if a timestamp is passed in that doesn't match the expression. From a software design point of view, this behavior makes sense to me. However, if you want to be able to use that function with strings that may not be in the correct format, you can just do a null check against parts and return null if there is no match.

Comparing two dates with javascript or datejs (date difference)

I am trying to compare two dates which are in Finnish time form like this: dd.mm.YYYY or d.m.YYYY or dd.m.YYYY or d.mm.YYYY.
I am having a hard time finding out how to do this, my current code won't work.
<script src="inc/date-fi-FI.js" type="text/javascript"></script>
<script type="text/javascript">
function parseDate() {
var date = $('#date').val();
var parsedDate = Date.parse(date);
alert('Parsed date: '+parsedDate);
}
function jämförMedIdag (datum) {
if (datum == null || datum == "") {
alert('Inget datum!');
return;
}
/*resultat = Date.compare(Datum1,Datum2);
alert(resultat); */
var datum = Date.parse(datum);
var dagar = datum.getDate();
var månader = datum.getMonth();
var år = datum.getYear();
var nyttDatum = new Date();
nyttDatum.setFullYear(år,månader,dagar);
var idag = new Date();
if(nyttDatum>idag) {
var svar = nyttDatum - idag;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
} else {
var svar = idag - nyttDatum;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
}
}
</script>
This code will try to calculate the difference between two dates, one of them being today. No success lolz.
Thanks in advance!
My final code (thanks RobG!):
function dateDiff(a,b,format) {
var milliseconds = toDate(a) - toDate(b);
var days = milliseconds / 86400000;
var hours = milliseconds / 3600000;
var weeks = milliseconds / 604800000;
var months = milliseconds / 2628000000;
var years = milliseconds / 31557600000;
if (format == "h") {
return Math.round(hours);
}
if (format == "d") {
return Math.round(days);
}
if (format == "w") {
return Math.round(weeks);
}
if (format == "m") {
return Math.round(months);
}
if (format == "y") {
return Math.round(years);
}
}
It is not fully accurate, but very close. I ended up adding some addons to it to calculate in day week month year or hour, anyone can freely copy and use this code.
If you are using Datejs, and the optional time.js module, you can run your calculations with the following code by creating a TimeSpan object:
Example
// dd.mm.YYYY or d.m.YYYY
// dd.m.YYYY or d.mm.YYYY
var start = Date.parse("20.09.2011");
var end = Date.parse("28.09.2011");
var span = new TimeSpan(end - start);
span.days; // 8
Of course the above could be simplified down to one line if you really want to be extra terse.
Example
new TimeSpan(Date.parse(end) - Date.parse(start)).days; // pass 'end' and 'start' as strings
Hope this helps.
If your dates are strings in the common form d/m/y or some variation thereof, you can use:
function toDate(s) {
var s = s.split('/');
return new Date(s[2], --s[1], s[0]);
}
You may want to validate the input, or not, depending on how confident you are in the consistency of the supplied data.
Edit to answer comments
To permit different separators (e.g. period (.) or hyphen (-)), the regular expression to split on can be:
var s = s.split(/[/\.-]/);
The date will be split into date, month and year numbers respectively. The parts are passed to the Date constructor to create a local date object for that date. Since javascript months are zero indexed (January is 0, February is 1 and so on) the month number must be reduced by one, hence --s[1].
/Edit
To compare two date objects (i.e get the difference in milliseconds) simply subtract one from the other. If you want the result in days, then divide by the number of milliseconds in a day and round (to allow for any minor differences caused by daylight saving).
So if you want to see how many days are between today and a date, use:
function diffToToday(s) {
var today = new Date();
today.setHours(0,0,0);
return Math.round((toDate(s) - today) / 8.64e7);
}
alert(diffToToday('2/8/2011')); // -1
alert(diffToToday('2/8/2012')); // 365
PS. The "Finnish" data format is the one used by the vast majority of the world that don't use ISO format dates.
Using the Date object:
var today = Date.today();
var dateToday = Date.parse(today.toString('MMMM d, yyyy'));
var prevMonthDate = dateToday.addDays(-30);
var difference = (dateToday - prevMonthDate)/86400000;
console.log(difference); //will give you the difference in days.

Categories