In a JavaScript step in Pentaho Data Integration, I want calculate the time in hours which passes between one date and another.
After following along with this this blog post, I realize that I need to adjust the startDate and endDate values in the function below which fall outside business hours so that they're within business hours so the function doesn't return zero. The dates are in the format 09/27/2018 18:54:55.
Here's my attempt so far:
var Approve_Gap;
var created_at_copy;
var approved_at_copy1;
// Function that accepts two parameters and calculates
// the number of hours worked within that range
function workingHoursBetweenDates(startDate, endDate) {
// Store minutes worked
var minutesWorked = 0;
// Validate input
if (endDate < startDate) { return 0; }
// Loop from your Start to End dates (by hour)
var current = startDate;
// Define work range
var workHoursStart = 8;
var workHoursEnd = 17;
var includeWeekends = true;
// bring dates into business hours
if(current.getHours() > workHoursEnd) {
current = current - (current.getHours() - workHoursEnd);
}
else if(current.getHours() < workHoursStart) {
current = current + (workHoursStart - current.getHours())
}
if(endDate.getHours() > workHoursEnd) {
endDate = endDate - (endDate.getHours() - workHoursEnd);
}
else if(endDate.getHours() < workHoursStart) {
endDate = endDate + (workHoursStart - endDate.getHours())
}
// Loop while currentDate is less than end Date (by minutes)
while(current <= endDate){
// Is the current time within a work day (and if it
// occurs on a weekend or not)
if(current.getHours() >= workHoursStart && current.getHours() < workHoursEnd && (includeWeekends ? current.getDay() !== 0 && current.getDay() !== 6 : true)){
minutesWorked++;
}
// Increment current time
current.setTime(current.getTime() + 1000 * 60);
}
// Return the number of hours
return minutesWorked / 60;
}
Approve_Gap = workingHoursBetweenDates(created_at_copy, approved_at_copy1);
I got the dates into business hours by adjusting copies of the dates as shown below:
if(created_at_copy.getHours() >= workHoursEnd) {
created_at_copy.setDate(created_at_copy.getDate() + 1);
created_at_copy.setHours(8);
created_at_copy.setMinutes(0);
created_at_copy.setSeconds(0);
} else if(created_at_copy.getHours() < workHoursStart) {
created_at_copy.setHours(8);
created_at_copy.setMinutes(0);
created_at_copy.setSeconds(0);
}
if(approved_at_copy1.getHours() >= (workHoursEnd)) {
approved_at_copy1.setDate(approved_at_copy1.getDate() + 1);
approved_at_copy1.setHours(8);
approved_at_copy1.setMinutes(0);
created_at_copy.setSeconds(0);
} else if(approved_at_copy1.getHours() < workHoursStart) {
approved_at_copy1.setHours(8);
approved_at_copy1.setMinutes(0);
created_at_copy.setSeconds(0);
}
i have an application that executes a cron job every 6 hours:
00:00, 06:00, 12:00, 18:00
How do i round the current time to the lowest matching hour of the above?
So if its 13:05 now, it should return 12:00
edit: i meant in javascript, not in php. updated my question
You can use this function and it is without moment.js
function getRoundedTime(){
var d = new Date();
var now = d.getHours();
if(now > 6){
var roundedTime = now - (now % 6);
var stringTime = roundedTime.toString().concat(":00");
return stringTime;
}
if(now < 6){
return "00:00";
}
if(now % 6 === 0) {
return "0" + now.toString().concat(":00");
}
}
getRoundedTime();
Or if you want moment.js then import moment and inside function declare now like this var now = moment().hour();
So basically I have done a calculation that increments a clock time:
function Clock(year,month,day,hours,minutes,seconds){
if(seconds !== null){
this.seconds = seconds;
}
if(minutes !== null){
this.minutes = minutes;
}
if(hours !== null){
this.hours = hours;
}
if(day !== null){
this.day = day;
}
if(month !== null){
this.month = month;
}
if(year !== null){
this.year = year;
}
}
function incrementClock(){
clock.seconds++;
if (clock.seconds >=60) {
clock.seconds = 0;
clock.minutes++;
if (clock.minutes >=60) {
clock.minutes = 0;
clock.hours++;
if (clock.hours >=24) {
clock.hours = 0;
clock.days++;
}
}
}
}
function showClock(){
//prints clock in format yyyy/mm/dd hh:mm:ss
}
This would increment the seconds, minutes, hours and days accordingly...
So if I call print the clock each second it would look like this:
var c = new Clock(2014,04,01,12,13,01);
showClock();
2014/4/1 12:13:1
I get stuck on the month part...
My question is how would I go about checking if a month has passed as there are different amount of days each month?
EDIT
I am creating my own minified Date function... so please don't recommend using Date objects as I am trying to implement my own
Is this what you're looking for?
function incrementClock(){
clock.seconds++;
if (clock.seconds >=60) {
clock.seconds = 0;
clock.minutes++;
if (clock.minutes >=60) {
clock.minutes = 0;
clock.hours++;
if (clock.hours >=24) {
clock.hours = 0;
clock.days++;
var months = [31,((clock.year%4==0)&&((clock.year%100!=0)||(clock.year%400==0)))?29:28,31,30,31,30,31,31,30,31,30,31];
if (clock.days>months[clock.month-1]){
clock.days = 0;
clock.months++;
}
}
}
}
}
This line:
var months = [31,((clock.year%4==0)&&((clock.year%100!=0)||(clock.year%400==0)))?29:28,31,30,31,30,31,31,30,31,30,31];
creates an array of the months and the days in each month. Thus it is easy to determine the amount of days per month like so:
days_in_jan = months[0]
days_in_feb = months[1]
...
days_in_dec = months[11]
You don't. You don't increment anything actually. If you want your own clock, that's fine, but you still need to access the current time using a Date object, so when you want to know how much time has elapsed, get a new Date object and figure it out:
pseudo structure:
Class Clock
- start date
- function timeElapsed
- elapsed = now - start date
In that function, compare the month, day, etc.
And honestly, if you don't like that answer you're on your own, as the answer to "how do I do this random thing as purely a thought exercise" is exactly that -- a thought exercise. There's no real point to it, so it shouldn't be asked or answered on SO.
As others have done, I would suggest using the Date object, or a date library like MomentJS, but it seems like you want to do the implementation yourself as an exercise. In that case, your code will need to know how many days are in each month if it is going to do the calculation correctly. Consider including in your code an array of the months' lengths:
var monthLengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
You'll also need a function to determine whether or not it's a leap year:
function isLeapYear(year) {
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}
Armed with those, you should be able to tell if a date has exceeded its month by checking the array to know how many days are in that month, and (if it's February) using the leap year function to determine if you should count 29 days for February.
I have two issues I need to solve using javascript or jQuery.
1) I need to test whether the current time falls between 7am and 7pm.
var now = new Date();
if (now >= *7am* && now < *7pm*){} else {}
2) On document load, I need a function to run everyday at 7am and 7pm.
Any help is appreciated.
Resolved part 2 by running a time check every 15 minutes.
var checkTime = setInterval(myFunction(), 900000);
You can use var currentHour = (new Date()).getHours(); to retrieve the specific hour as an integer between 0 and 23, according to the local timezone of your environment:
var currentHour = (new Date()).getHours();
if (currentHour >= 7 && currentHour < 19) { /* stuff */ } else { /* other stuff }
If you need to get UTC, there is the .getUTCHours() method.
The documentation has more information if you're interested: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours
Look at Date.getHours
$(function(){
var now = new Date();
var hours = now.getHours();
if (hours >= 7 && now < hours < 19){} else {}
});
I'm displaying a message between Saturday at 6pm and Sunday 4am. The last time I had to do this it didn't work because I didn't take into account UTC time going negative when changing it to NYC time.
I am doing the math right (displaying at the appropriate times)?Should I put the UTC conversion code into its own function? Is this the worst js you've ever seen?
-- jquery is called --
$(document).ready(function() {
var dayTime = new Date();
var day = dayTime.getUTCDay();
var hour = dayTime.getUTCHours();
//alert(day.toString()+" "+hour.toString());
if (hour >= 5){
hour = hour-5;
}
else{
hour = hour+19;
if(day > 0){
day--;
}
else{
day = 6;
}
}
//alert(day.toString()+" "+hour.toString());
if ((day == 6 && hour >= 18) || (day == 0 && hour < 4)){
}
else{
$('#warning').hide(); //Want this message to show if js is disabled as well
}
});
Why do you even need that UTC stuff? Just work with local time:
var day = dayTime.getDay();
var hour = dayTime.getHours();
And you can clean up that conditional a bit too:
if (!(day == 6 && hour >= 18) && !(day == 0 && hour < 4)) {
$('#warning').hide();
}
This should get you your server's time:
var dayTime = new Date();
localOffset = dayTime.getTimezoneOffset() * 60000;
serverOffset = 5 * 60 * 60000;
dayTime = new Date(dayTime.getTime() + (localOffset - serverOffset));
Play around with that "5" in the server offset; it's the hours. It may need to be a -5; I'm not really sure.
Also, that's going to break every daylight savings. You'll have to detect that somehow and modify serverOffset.