I need to round up quarter my time even if I'm on the current quarter.
Here is my code :
const currentDate = new Date(2020, 1, 8, 9, 42, 0, 0);
let roundedUpQuarter = Math.ceil(currentDate.getMinutes() / 15) * 15 % 60;
So in my exemple the current time is 09:42 so in my roundedUpQuarter variable I'll get the good result 09:45
But I have a problem when I send 0, 15, 30 or 45 minutes on my current time because I need to round up too.
For an example if my current time is 09:30 I need to get 09:45
I don't want to use if condition to do that. It's possible to do this only with a formula ?
const currentDate = new Date(2020, 1, 8, 9, 42, 0, 0);
let roundedUpQuarter = Math.ceil((currentDate.getMinutes()+0.1) / 15) * 15 % 60;
Check % 15 === 0 and add 1 minute to real minutes. Than continue with your equation.
const currentDate = new Date(2020, 1, 8, 9, 45, 0, 0);
var minutes = currentDate.getMinutes() % 15 === 0 ? (currentDate.getMinutes() + 1) : currentDate.getMinutes();
let roundedUpQuarter = Math.ceil(minutes / 15) * 15 % 60;
console.log(roundedUpQuarter); // for 45 return 0
Related
I want to run a function at specific time points in a particular timeframe, say from 5:30 to 14:30. The specific time points would be increments of 3 minutes from 5:30 like so, 5:30, 5:33, 5:36,...,6:00 etc until 14:30. I thought the logic would be as simple as checking if the current time in integer format was a multiple of 3 and checking if the "seconds" in the current time was "00", since I want to run it only at the beginning of these specific time points. But this logic is incorrect. Since a lot of time points such as 10:00, 11:00, 13:00, 14:00 etc are not divisible by 3. Also, the browser freezes because of the while loop. How do I go about this and what is the correct logic here?
myFunc = () => {
//Some Task
};
myFunc();
var dateToday = Date();
while (Number(dateToday.getHours()+(dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes())) >= 530 && Number(dateToday.getHours()+(dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes()) <= 1430){
var dateTodayCheck = new Date(),
hoursCheck = dateTodayCheck.getHours(),
minutesCheck = (dateTodayCheck.getMinutes()<10?'0':'')
+ dateTodayCheck.getMinutes(),
secondsCheck = (dateTodayCheck.getSeconds()<10?'0':'')
+ dateTodayCheck.getSeconds();
var timeNowCheck = Number(hoursCheck+minutesCheck)
var remainder = timeNowCheck % 3
if (remainder === 0 && secondsCheck==="00") {
myFunc();
};
};
Okay, I got it to work for me. I came up with new logic. I hard-coded the minutes, I wanted the function to run at, ex: [0, 3, 6, 9, 12, 15,....,60]. Now say the current time is 6:35:15 the "minutes" part of the current time would be 35, so I checked for the number from my array that was closest to 35, which would be 36 (Found the code for this online). Then I took the difference between the closest value and the "minutes" part of the current time, in this case, 36 - 35 = 1 (1 minute). Later I accounted for the seconds, so 1 min - 15 seconds = 45 seconds. Finally, passed 45 seconds into a Timeout Function which contains an Interval Function that calls myFunc() every 3 minutes. This way if I open the app at 6:35:15, the program would know to wait for 45 seconds and call myFunc() at 6:36, and every 3 minutes from that point.
var dateToday = new Date(),
hours = dateToday.getHours(),
minutes = (dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes(),
seconds = (dateToday.getSeconds()<10?'0':'') + dateToday.getSeconds();
var timeNow = hours+minutes
if(Number(timeNow) >= 530 && Number(timeNow) <= 1430){
const closest = [0, 3, 6, 9, 12, 15, 18, 21, 24,
27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57,
60].reduce((a, b) => {
let aDiff = Math.abs(a - Number(minutes));
let bDiff = Math.abs(b - Number(minutes));
if (aDiff === bDiff) {
return a > b ? a : b;
} else {
return bDiff < aDiff ? b : a;
};
});
var difference = closest - Number(minutes)
var timeoutTime = difference === -1 ? 2 : difference
var timeoutTimeCorrected = (timeoutTime * 1000 * 60) - (Number(seconds) * 1000)
setTimeout(() => {
myFunc();
setInterval(() => {
myFunc();
}, 180000);
},timeoutTimeCorrected);
};
Please let me know, if there is a more elegant way to do this.
Example:
GMT Wednesday, January 20, 2016 12:00:01 AM = 1453248001 =>
2016.0533
Just this, accurate to the day:
Time.at(1453248001).then { |t| t.year + t.yday / 365.25 }
and a bit more cumbersome to be precise to the second:
Time.at(1453248001).then do |t|
beginning_of_year = Time.utc("#{t.year}-01-01")
seconds_in_year = Time.utc("#{t.year + 1}-01-01") - beg_of_year
num_seconds = t - beginning_of_year
t.year + num_seconds / seconds_in_year
end
Given time values in seconds, the decimal part of the year is given by:
(supplied_time - year_start_time) / seconds_in_year
E.g.
// Return decimal UTC year given a time value in seconds
// e.g. 1453248001 (2016-01-20T00:00:01Z) = 2016.0519125999292
function decimalYear(tv) {
let d = new Date(tv * 1e3);
let y = d.getUTCFullYear();
let start = Date.UTC(y, 0, 1); // Start of UTC year
let end = Date.UTC(y + 1, 0, 1); // Start of following UTC year
return y + (d - start) / (end - start);
}
// Time values in seconds
[Date.UTC(2016, 0, 1, 0, 0, 0)/1e3|0, // 2016-01-01T00:00:00Z
Date.UTC(2016, 0, 1, 0, 0, 1)/1e3|0, // 2016-01-01T00:00:01Z
Date.UTC(2016, 0,20, 0, 0, 1)/1e3|0, // 2016-01-20T00:00:01Z
Date.UTC(2016,11,31,23,59,59)/1e3|0, // 2016-12-31T23:59:59Z
Date.UTC(2017, 0, 1, 0, 0, 0)/1e3|0 // 2017-01-01T00:00:00Z
].forEach(tv => console.log(tv + ' => ' + decimalYear(tv)));
Using a general formula gives accurate results regardless of whether the time value is in a leap year or not.
The example in the OP is incorrect:
Example: GMT Wednesday, January 20, 2016 12:00:01 AM = 1453248001 => 2016.0533
All the following are seconds UTC:
Time value for 2016-01-12T00:00:01Z is 1453248001
Start of 2016 is 1451606400
End of 2016 (i.e. start of 2017) is 1483228800
(timeValue - startOfYear) รท (endOfYear - startOfYear) = 0.0519125999292
I want to calculate between two dates difference to percent. Only not date, hours needed to scale.
Example:
22-08-2017 09:00 start date,
30.09.2017 22:00 finish date,
The today date is 01.09.2017. When I look to system today, the application show to me "%47 percent completed" I want to this.
function getpercent(){
var strt = new Date(document.getElementById('start').value).getTime();
var end = new Date(document.getElementById('end').value).getTime();
var current = new Date(document.getElementById('current').value).getTime();
var completed = ((current - strt) / (end - strt)) * 100;
document.getElementById('percent').innerHTML = completed+"%";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>start <input id="start" type="date" /></p>
<p>end <input id="end" type="date" /></p>
<p>current <input id="current" type="date" /></p>
<p>percent <span id="percent"></span></p>
<button onclick="getpercent()">get percent</button>
new Date() will take a date string and turn it into unix standard time as seconds.
The javascript Date object can be used in arithmetic expressions. It will convert to milliseconds.
var start, finish, midpoint, percent, elapsed;
start = new Date(2017, 8, 22, 9);
finish = new Date(2017, 9, 30, 22);
midpoint = new Date(2017, 8, 29, 12);
elapsed = midpoint - start;
percent = (elapsed / (finish - start)) * 100;
console.log('elapsed', elapsed, ' ms', percent, ' % complete');
https://jsfiddle.net/fwb3g4nc/1/
This is a simple class DiffTracker that accepts two dates in the constructor - start and end date and has one method getPercentage() that will return the percentage of hours passed from start date against the total hours between start and end date.
Let's see the following scenario:
Start Date = 2017-08-23 09:00
End Date = 2017-08-24 09:00
So now the total difference of hours is 24
If we call getPercentage() with date 2017-08-24 21:00 we should see result of 50%.
If we call getPercentage() with date 2017-08-24 03:00 we should see result of 75% because the difference is 18 hours
var diffTraker = new DiffTracker(new Date(2017, 7, 23, 9), new Date(2017, 7, 24, 9));
console.log('Start Date');
console.log(new Date(2017, 7, 23, 9));
console.log('-------------------');
console.log('End Date');
console.log(new Date(2017, 7, 24, 9));
console.log('-------------------');
console.log(diffTraker.getPercentage(new Date(2017, 7, 23, 21)) + '% from start date (' + new Date(2017, 7, 23, 21) + ')');
console.log(diffTraker.getPercentage(new Date(2017, 7, 24, 3)) + '% from start date (' + new Date(2017, 7, 24, 3) + ')');
console.log(diffTraker.getPercentage(new Date(2017, 7, 24, 5)) + '% from start date (' + new Date(2017, 7, 24, 5) + ')');
function DiffTracker(startDate, endDate){
var self = this;
self.start = startDate;
self.end = endDate;
self.totalHours = getDiffHours(self.start, self.end);
self.getPercentage = function(date){
var hoursFromStart = getDiffHours(self.start, date);
return (hoursFromStart * 100 / self.totalHours).toFixed(2);
}
function getDiffHours(start, end){
/* 36e5 is the scientific notation for 60*60*1000, dividing by which converts the milliseconds difference into hours */
return Math.abs(start - end) / 36e5;
}
}
$FirstDate = "22-08-2017 09:00";
$SecondDate = "23.09.2017 22:00";
Even if one day it shows 100%
In php i use this method:
<?php
$FirstDate = "22-08-2017 09:00";
$SecondDate = "30.09.2017 22:00";
$start = strtotime($FirstDate);
$finish = strtotime($SecondDate);
$diff = $finish - $start;
$progress = time() - $start; // You might have to modify the time function depending on where you live
$procent = ($progress / $diff) * 100;
$width = round($procent);
// The if statment below just makes sure that it does not show 110% for example.
if ($width >= 100)
{
echo "100 %";
}
else
{
echo $width;
}
Hope this helps!
I have tried to show time between two time while page load.
Please check below my code -
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
function hourDiff(start, end) {
start = start.split(":");
end = end.split(":");
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[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 < 9 ? "0" : "") + hours + ":" + (minutes < 9 ? "0" : "") + minutes;
//setTimeout(function(){hourDiff(start, end)},500);
}
document.getElementById("diff").value = hourDiff(start, end);
<input id="start" value="20:00"> <!-- 08.00 PM -->
<input id="end" value="09:30"> <!-- 09.30 AM -->
<input id="diff">
I have used start time 20.00 and end time 09.30 the different between two time is = 13.30 hours but it is showing wrong hour. Please check and let me know.
Edit:
Also I want to the how many hour:minute:second left
If your dates are always in the same format hh:mm, why don't you try my suggestion.
It is quite simple:
var hours = end[0] - start[0];
if(start[0] > end[0]) {
hours = 24 + hours;
}
var minutes = end[1] - start[1];
if(start[1] > end[1]) {
minutes = 60 + minutes;
if(hours == 0) {
hours = 23;
} else {
hours--;
}
}
I just substract them each other and react if the start value is bigger than the end value.
Fiddle: https://jsfiddle.net/rvwr9h0w/1/
Edit
I found a simpler solution, because of Shotgun Ninja's post:
https://jsfiddle.net/rvwr9h0w/4/
var endDate = new Date(0, 0, (start > end)?1:0 , end[0], end[1], end[2]);
If the start time is bigger than the end time, just set the end date 1 day ahead.
Okay, the problem with your code here is that you're subtracting an earlier time from a later time, which results in a negative time difference. I think what you meant to do was to have the system subtract 9:30am the next day from 8:00pm the previous day, but you've supplied no information that would indicate that they are separate days.
You have:
var startDate = new Date(0, 0, 0, 20, 0, 0); // 8:00pm, Dec 31st, 1899 (current TZ)
var endDate = new Date(0, 0, 0, 9, 30, 0); // 9:30am, Dec 31st, 1899 (current TZ)
(Year = 0 corresponds to 1900, Month = 0 corresponds to January, and Day = 0 corresponds to 1 day before the 1st, which rolls back to Dec 31.)
The important part here is that by setting all values to 0, you're getting the same day, but a different hour. So you're actually getting a negative value in the diff; the code functions correctly, but is giving you a negative hour value because the dates are out of order.
Try using Math.floor with the whole math equation required for each part:
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
function hourDiff(start, end) {
start = start.split(":");
end = end.split(":");
var startDate = new Date(0, 0, 0, start[0], start[1], 0);
var endDate = new Date(0, 0, 0, end[0], end[1], 0);
var diff = endDate.getTime() - startDate.getTime();
var msec = diff;
var hh = Math.floor(msec / 1000 / 60 / 60);
msec -= hh * 1000 * 60 * 60;
var mm = Math.floor(msec / 1000 / 60);
return hh + ":" + mm;
//setTimeout(function(){hourDiff(start, end)},500);
}
document.getElementById("diff").value = hourDiff(start, end);
<input id="start" value="20:00"> <!-- 08.00 PM -->
<input id="end" value="09:30"> <!-- 09.30 AM -->
<input id="diff">
Ive been searching quite a lot find an answer for this , and couldn't find one.
I have 2 dates ,
I want to calc days between them
but I Also want the end day to be counted.
Example :
me and my wife go to hotel from [20 jan] till [26 Jan] , so its 7 days total.
the only code which I find working is :
Math.round((b - a) / ( 1000 * 60 * 60 * 24)) +1
where :
var a= new Date (y,0,20);
var b= new Date (y,0,26);
I also made a nested loop to test all months within a 150 years , and it works Ok.
var y = 1970;
var m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for(var i = 0; i < 150; i++)
{
for(var j = 0; j < 12; j++)
{
var a = new Date(y + i, m[j], 20);
var b = new Date(y + i, m[j], 26);
var days = Math.round((b - a) / (1000 * 60 * 60 * 24)) + 1;
if(days != 7) console.log(i + y); //tell me if result is unexpected.
}
}
console.log('-FINISH-' + new Date().getTime())
So where is the problem ?
I can't figure how the math function like round can do the trick here.
We are talking about milliseconds here and I can't see where the round behavior gives me the right result.
(p.s. - forget about ceil and floor , they do not help here and have inconsistent results) , I have also tried to add one day to the b value , and use ceil || floor but with no success
here is the code
The reason your rounding is working is because you're only working with full days. myDate.getTime() will yield the number of milliseconds since 1970-01-01. If you're always assigning your dates as new Date(y,m,d) you will always have the time part set to 00:00:00.000, and hence the date comparison will always yield a multiple of 86400000, which is your divisor. The rounding here is for the most part superfluous.
If you're creating all of your dates as specified above, the only time rounding does come into play, is when the daylight savings offset at date b is different from that at date a. round will take care of these discrepancies, as they're rarely more than an hour.
From your script, October 1970 is problematic (in CEST) because Oct 20th is in daylight savings, and Oct 26th isn't.
var a = new Date(1970, 9, 20);
var b = new Date(1970, 9, 26);
(b - a) / (1000 * 60 * 60 * 24) // 6.041666666666667
You could work around this by rounding, or by using UTC dates
var a = new Date(Date.UTC(1970, 9, 20));
var b = new Date(Date.UTC(1970, 9, 26));
(b - a) / (1000 * 60 * 60 * 24) // 6
Here is your answer:
http://www.direct.gov.uk/en/Nl1/Newsroom/DG_185398
Basically, March 25 has 23 hours in it instead of 24. And 28'th October has 25 hours in it. That's why rounding works well while floor/ceil does not.
Also, as you can see, DST date changes with each year (you can see that in same article), that's why only once every 5-10 years the floor/cail test fails. On other years DST is applied to different date, therefore test result appears to be normal.
I found the reason! :) (e.g. year 2035)
Date {Sun Mar 25 2035 00:00:00 GMT+0100 (CET)}
Date {Mon Mar 26 2035 00:00:00 GMT+0200 (CEST)}
Look at the GMT Times one is GMT+0100 (CET) and one is GMT+0200 (CEST)
To get always the result without round you have to use UTC:
var a = Date.UTC(y + i, m[j], 25);
var b = Date.UTC(y + i, m[j], 26);
var days = (b - a) / (1000 * 60 * 60 * 24);
I modified your code slightly to find this bug:
var y = 1970;
var m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for(var i = 0; i < 150; i++)
{
for(var j = 0; j < 12; j++)
{
var a = new Date(y + i, m[j], 25);
var b = new Date(y + i, m[j], 26);
var days = (b - a);
if(days != 86400000) console.log(i + y, days); //tell me if result is unexpected.
}
}
1983 90000000
1984 82800000
1988 90000000
...
This was already discussed here:
http://www.webdeveloper.com/forum/archive/index.php/t-5195.html
As already answered in a previous post:
var days = Math.floor(enddate.getTime()-startdate.getTime())/(24*60*60*1000);