I am a systems guy, so code isn't really my forte. I'm building a new front-end for our in-house ticketing system. I pull the tickets from the database as objects and iterate over them. I have it set up so that each ticket object has an "updates" property which is an array of objects describing each time it was interacted with. I use the type of interaction to determine if the timer should be effected, and if so, if it should be started or stopped.
User creates a ticket -> timer starts
Tech1 responds to the ticket asking for more information -> timer stops
User responds -> timer starts again
Tech1 escalates ticket to tech2 -> no change in timer status
Tech2 resolves issue and closes ticket -> timer stops
I've been able to get it to work with a single start/stop event (open/close, nothing in-between) per ticket, including subtracting non-business hours (nights, weekends, and holidays), but I'm having trouble coming up with a clean way to deal with multiple start/stops per ticket.
The main thing throwing a wrench in things is validating the input. For example, a user might submit a response (triggering a start event), then realize they forgot to add something and submit a second response (triggering another start event) before a tech responds.
I'd appreciate any thoughts on how to go about this or about what I can do to improve my existing code, I'm sure it is far less than optimal.
Here is an example of a ticket object:
{
"status":"closed",
"id":13137,
"importance":4,
"type":1,
"owner":"User1",
"category":"User Accounts",
"cc":[
"User2",
"User3"
],
"updates":[
{
"time":1393264332000,
"updator":"Tech1",
"event":"techClose",
"detail":"Done. Let us know if you need anything else."
},
{
"time":1393261496000,
"updator":"Tech2",
"event":"assigned",
"detail":"Tech1"
},
{
"time":1393030776000,
"updator":"User1",
"event":"clientReply",
"detail":"Actually, nevermind, just remove them from the groups."
},
{
"time":1393030632000,
"updator":"User1",
"event":"clientReply",
"detail":"Can you give me a list and I'll let ya know what to do with each?"
},
{
"time":1393002994000,
"updator":"Tech2",
"event":"techResponse",
"detail":"These accounts are disabled, they are still in the lists because the accounts still exist, but they are not able to be logged in to or accessed in any other way. It is standard practice to leave the accounts exactly as they were, but in a disabled state just in case you need to access them at a later date because any other changes cannot be reversed. If you'd prefer, we can remove them from the groups associated with those distribution lists or delete the accounts entirely."
},
{
"time":1392991707000,
"updator":"User1",
"event":"userCreate",
"detail":"Hey. Can you revise the All employee and other staff email groups to delete the people that are no longer here? Thx."
}
]
}
Here is how the above might be represented when passed into the function:
start = [1392991707000,1393030632000,1393030776000];
stop = [1393002994000,1393264332000];
And here is the function I am currently using (I'm not passing in arrays, just single ints at the moment):
function timeCalc(start, end){
// Array of non-working days (eg: weekends) in numerical weekday format starting with Sunday=0 and ending with Saturday=6
var daysOff = new Array(0,6);
// Array of non-working dates (eg: holidays) in any valid date format, such as: "October 13, 1975" or "75,10,13"
var holidays = new Array("2014,02,17","2014,05,26","2014,07,04","2014,08,01","2014,11,11","2014,11,27","2014,11,28","2014,12,25");
// Two arrays defining business hours in 24hour time. busHoursStart contains all starting times, busHoursEnd contains all ending times. So if you work 9-5 with a lunch break from 12-1, put "9,13" in start and "12,17" in end.
/*var busHoursStart = new Array("9");
var busHoursEnd = new Array("17");*/
// Just using start and end time, no array for now
var busHoursStart = 9;
var busHoursEnd = 17;
// Define other variables (no need to configure)
var datesBetween = new Array();
var oneDay = 24*60*60*1000;
var busHoursPerDay = (busHoursEnd - busHoursStart);
var subtractDays = 0;
// Create array of JS timestamps (UNIX time in milliseconds) representing each full day between the start and end dates (including the end date)
var dateDiff = Math.round(Math.abs(start.getTime() - end.getTime())/(oneDay));
for (var i=0; i<dateDiff; i++){
datesBetween.push(new Date(start.getTime()+(i*oneDay)));
}
// Remove days off
var noWeekends=$.grep(datesBetween, function(wDate){
var wFail;
$.each(daysOff,function(wKey,wVal){
if(wDate.getDay() == wVal) wFail=wDate;
});
return (wDate != wFail);
});
// Remove holidays
var noHolidays=$.grep(noWeekends, function(hDate){
var hFail;
$.each(holidays,function(hKey,hVal){
if(hDate.toDateString() == new Date(hVal).toDateString()) hFail=hDate;
});
return (hDate != hFail);
});
var days=(noHolidays.length - 1);
// This should be made into a function
// If start event is before business hours, set start time to when business hours start
if(start.getHours() < busHoursStart){
var startTime = busHoursStart;
}
// If start event is after business hours, set start time to when the next day's business hours start by adding a day to the counter
else if(start.getHours() >= busHoursEnd){
var startTime = busHoursStart;
subtractDays++;
}
else var startTime = start.getHours();
// If end is before business hours, set end time to when business hours start
if(end.getHours() < busHoursStart){
var endTime = busHoursStart;
}
// If end is after business hours, set end time to to when the next day's business hours start by adding a day to the counter
else if(end.getHours() >= busHoursEnd){
var endTime = busHoursStart;
subtractDays++;
}
else var endTime = end.getHours();
// If the end time is a later hour than the start time, add up hours from full days then add hours between start and end
if(endTime >= startTime){
var hours = (days - subtractDays) * busHoursPerDay) + (endTime - startTime);
}
// If the end time is an earlier hour than the start time, add up hours from full days then get hours between start and close time and hours between open time and end time, add them together and subtract a full day worth of time
else {
var hours = ((days - subtractDays) * busHoursPerDay) + ((busHoursEnd - startTime) + (endTime - busHoursStart));
}
console.log("Days: "+days+" Hours: "+hours);
return hours;
}
Related
What am looking forward to get is a split of time from current time to yesterdays midninght split by one hour
so that is
eg: if now its 03:34
so i would like to get this
var durations = [
{from:03:00, to:03:34},
{from:02:00, to:03:00},
{from:01:00, to:02:00},
{from:00:00, to:01:00}
]
SO from the above example the value of 03:34 is the current time
SO far i have been able to get the first segment via
{from:moment().startOf('hour'), to:moment()}
Now am stuck on how to split the other durations with a difference of 1 hour each
So its something like
let hours_from_midnight = moment.duration(end.diff(moment().startOf('day'))).asHours();
But now how do i proceed to use the number of hours from midnight to split the next durations and achieve the durations desired
What you need to do is keep subtracting an hour and cloning the date, as all the methods mutate the existing object:
function periods(initialTime) {
// our lower bound
const midnight = initialTime.clone().startOf("day");
// our current period start
const periodStart = initialTime.clone().startOf("hour");
const periods = [];
if (!(periodStart.isSame(initialTime))) {
// only add the last period if it isn't empty
periods.push({ start: periodStart.clone(), end: initialTime });
}
while (periodStart.isAfter(midnight)) {
// the last start is our new end
const to = periodStart.clone();
// our new start is one hour earlier
const from = periodStart.subtract(1, "hour").clone();
periods.push({
from,
to
});
}
return periods;
}
console.log(periods(moment("03:34", "HH:mm")));
console.log(periods(moment("18:00", "HH:mm")));
I know there are many questions asked about this topic here but no one is about the problem I have.
This script is for reservations where the user selects the date and the start and end time and makes a reservation.
I have a form with a date selector input field and two time selector input fields, one for the start time and one for the end time.
The problem is that the store which I'm writing the reservation script for is opened from 17:00 evening to 01:00 morning. So if someone is reserving from 23:00 to 01:00 the start time is always shown as bigger, which results in that the form is not validated.
Does anyone know if there is a solution to this or if there is a validator out there which can do this.
NOTE: I only want to compare the times and I don't want to add another date field.
var timeto=$('#timeto').val();
var timefrom=$('#timefrom').val();
if(timefrom>timeto){
alert('start time should be smaller')
}
So if time from is 23:00 and time to is 00:00 than the alert is shown,but in reality 00:00 is a greater time than 23:00
Just subtract one hour while creating object of date.
var timefrom = new Date();
temp = $('#timefrom').val().split(":");
timefrom.setHours((parseInt(temp[0]) - 1 + 24) % 24);
timefrom.setMinutes(parseInt(temp[1]));
var timeto = new Date();
temp = $('#timeto').val().split(":");
timeto.setHours((parseInt(temp[0]) - 1 + 24) % 24);
timeto.setMinutes(parseInt(temp[1]));
if (timeto < timefrom){
alert('start time should be smaller than end time!');
}
// get the times as strings
start_string = $('#timefrom').val();
end_string = $('#timeto').val();
// define an arbitrary start time since you are only comparing hours
start_time = new Date("May 26, 2016 " + start_string);
// define the end time as the same date + end time
end_time = new Date("May 26, 2016 " + end_string);
// now we need to check if your end time is beyond midnight, if so, we need to add one day to end_time
var stay_length = end_time.getTime() - start_time.getTime();
if (stay_length < 0 {
// end time is beyond midnight, re-calculate end_time with adding one to the day
end_time = new Date("May 27, 2016 " + end_string);
stay_length = end_time.getTime() - start_time.getTime();
} elseif (stay_length > 24 {
// The user probably reversed the times, so show an alert
alert("The start time must be before the end time")
} else {
// The user most likely put in correct times
}
As your times are stored as a string, you can try parsing them to a Date and compare them;
var timeto=$('#timeto').val();
var timefrom=$('#timefrom').val();
if(Date.parse(timefrom) > Date.parse(timeto) > true){
alert('start time should be smaller')
}
I think you should make the time as DateTime to compare easier. Please try this:
var end_time=$('#timeto').val();
var start_time =$('#timefrom').val();
var stt = new Date("May 26, 2016 " + start_time);
stt = stt.getTime();
var endt= new Date("May 26, 2016 " + end_time);
endt = endt.getTime();
if(stt >endt){
//do something
}
I have a CloudCode function that is called from my iOS app. The function is supposed to create a "checkin" record and return a string to represent the last 30 days of check-ins and missed days.
The strange thing is that sometimes I get the expected results and sometimes I do not. It makes me think that there is some issue with the may I am using timezones - since that could result in a different set of "days in the past" depending on what time I run this function and what time of day I checked-in in the past. But I'm baffled and could use some help here.
It's also confusing me that I do not see all of my console.log() results appear in the parse log. Is that normal?? For example, in the for loop, I can uncomment the console.log entry and call the function but I will not see all of the days in the past listed - but they are included in the final array and text string.
Here is my complete function. Any help and suggestions are appreciated.
/* Function for recording a daily check in
*
* Calculates the number of days missed and updates the string used to display the check-in pattern.
* If no days missed then we increment the current count
*
* Input:
* "promiseId" : objectID,
* "timeZoneDifference" : String +07:00
*
* Output:
* JSON String eg. {"count":6,"string":"000000000000001111101010111111"}
*
*/
Parse.Cloud.define("dailyCheckIn", function(request, response) {
var promiseId = request.params.promiseId;
var timeZoneDifference = request.params.timeZoneDifference;
var currentUser = Parse.User.current();
if (currentUser === undefined) {
response.error("You must be logged in.");
}
if (timeZoneDifference === undefined || timeZoneDifference === "") {
//console.log("timeZoneDifference missing. Set to -07:00");
timeZoneDifference = '' + '-07:00'; // PacificTime as string
}
var moment = require('cloud/libs/moment.js');
// Query for the Promise
var Promise = Parse.Object.extend("Promise");
var queryforPromise = new Parse.Query(Promise);
queryforPromise.get(promiseId, {
success: function(promis) {
// Initialize
var dinarowString = "";
var dinarowCount = 0;
// Last Check In date from database (UTC)
var lastCheckInUTC = promis.get("lastCheckIn");
if (lastCheckInUTC === undefined) {
lastCheckInUTC = new Date(2015, 1, 1);
}
// Use moment() to convert lastCheckInUTC to local timezone
var lastCheckInLocalized = moment(lastCheckInUTC.toString()).utcOffset(timeZoneDifference);
//console.log('lastCheckIn: ' + lastCheckInUTC.toString());
//console.log('lastCheckInLocalized: ' + lastCheckInLocalized.format());
// Use moment() to get "now" in UTC timezone
var today = moment().utc(); // new Date();
//console.log('today: ' + today.format());
// Use moment() to get "now" in local timezone
var todayLocalized = today.utcOffset(timeZoneDifference);
//console.log('todayLocalized: ' + todayLocalized.format());
// 30 days in the past
var thirtydaysago = moment().utc().subtract(30, 'days');
//console.log("thirtydaysago = " + thirtydaysago.format());
// 30 days in the past in local timezone
var thirtydaysagoLocalized = thirtydaysago.utcOffset(timeZoneDifference);
//console.log('thirtydaysagoLocalized: ' + thirtydaysagoLocalized.format());
// Calculate the number of days since last time user checked in
var dayssincelastcheckin = todayLocalized.diff(lastCheckInLocalized, 'days');
//console.log("Last check-in was " + dayssincelastcheckin + " days ago");
// Function takes an array of Parse.Objects of type Checkin
// itterate over the array to get a an array of days in the past as numnber
// generate a string of 1 and 0 for the past 30 days where 1 is a day user checked in
function dinarowStringFromCheckins(checkins) {
var days_array = [];
var dinarowstring = "";
// Create an array entry for every day that we checked in (daysago)
for (var i = 0; i < checkins.length; i++) {
var checkinDaylocalized = moment(checkins[i].get("checkInDate")).utcOffset(timeZoneDifference);
var daysago = todayLocalized.diff(checkinDaylocalized, 'days');
// console.log("daysago = " + daysago);
days_array.push(daysago);
}
console.log("days_array = " + days_array);
// Build the string with 30 day of hits "1" and misses "0" with today on the right
for (var c = 29; c >= 0; c--) {
if (days_array.indexOf(c) != -1) {
//console.log("days ago (c) = " + c + "-> match found");
dinarowstring += "1";
} else {
dinarowstring += "0";
}
}
return dinarowstring;
}
// Define ACL for new Checkin object
var checkinACL = new Parse.ACL();
checkinACL.setPublicReadAccess(false);
checkinACL.setReadAccess(currentUser, true);
checkinACL.setWriteAccess(currentUser, true);
// Create a new entry in the Checkin table
var Checkin = Parse.Object.extend("Checkin");
var checkin = new Checkin();
checkin.set("User", currentUser);
checkin.set("refPromise", promis);
checkin.set("checkInDate", today.toDate());
checkin.setACL(checkinACL);
checkin.save().then(function() {
// Query Checkins
var Checkin = Parse.Object.extend("Checkin");
var queryforCheckin = new Parse.Query(Checkin);
queryforCheckin.equalTo("refPromise", promis);
queryforCheckin.greaterThanOrEqualTo("checkInDate", thirtydaysago.toDate());
queryforCheckin.descending("checkInDate");
queryforCheckin.find().then(function(results) {
var dinarowString = "000000000000000000000000000000";
var dinarowCount = 0;
if (results.length > 0) {
dinarowString = dinarowStringFromCheckins(results);
dinarowIndex = dinarowString.lastIndexOf("0");
if (dinarowIndex === -1) { // Checked in every day in the month!
// TODO
// If the user has checked in every day this month then we need to calculate the
// correct streak count in a different way
dinarowString = "111111111111111111111111111111";
dinarowCount = 999;
} else {
dinarowCount = 29 - dinarowIndex;
}
}
// Update the promise with new value and save
promis.set("dinarowString", dinarowString);
promis.set("dinarowCount", dinarowCount);
promis.set("lastCheckIn", today.toDate());
promis.save().then(function() {
response.success(JSON.stringify({
count: dinarowCount,
string: dinarowString
}));
});
}, function(reason) {
console.log("Checkin query unsuccessful:" + reason.code + " " + reason.message);
response.error("Something went wrong");
});
}); // save.then
},
error: function(object, error) {
console.error("dailyCheckIn failed: " + error);
response.error("Unable to check-in. Try again later.");
}
});
});
There's too much going on in your question to answer adequately, but I will be nice and at least point out a few errors that you should look into:
You take input in terms of a fixed offset, but then you are doing operations that subtract 30 days. It's entirely possible that you will cross a daylight saving time boundary, in which case the offset will have changed.
See "Time Zone != Offset" in the timezone tag wiki. In moment, you can use time zones names like "America/Los_Angeles" with the moment-timezone add-on.
From your example, I'm not even sure if time zone even matters or not for your use case.
You should not convert the Date to a string just to parse it again. Moment can accept a Date object, assuming the Date object was created correctly.
moment(lastCheckInUTC.toString()).utcOffset(timeZoneDifference)
becomes
moment(lastCheckInUTC).utcOffset(timeZoneDifference)
Since Date.toString() returns a locale-specific, implementation-specific format, you'll also see you have a warning in the debug console from moment.
As for the rest, we can't run your program and reproduce the results, so there's not much we can do to help. You need to start by debugging your own program, and then try to reproduce your error in a Minimal, Complete, and Verifiable example. Chances are, you'll solve your own problem along the way. If not, then you will have something in a better state to share with us.
I am answering my own question as I have found the solution.
I had two questions. The first was "why do I get unexpected (incorrect) results" and I suspected that it was related to the way I am using timezones. I would see different results from day to day depending on what time I check in.
The problem is actually related to the way that moment().diff() works. Diff does not calculate "days" the way I expected it to. If I compare 2am today with 11pm yesterday diff will say 0 days because it is less than 24 hours diff. If I compare 1am on Thursday with 8pm on the previous Monday, diff will report 2 days - not 3 as I expected. It's a precision issue. Diff thinks 2.4 days is 2 days ago. But it is more than 2 therefor it is 3 days ago.
We found that the easiest solution is to compare the two dates at midnight rather than at the actual time of day that is recorded in the database. This yields correct results for days. The rest of the code is working fine.
//Find start time of today's day
var todayLocalizedStart = todayLocalized.startOf('day');
for (var i = 0; i < checkins.length; i++) {
var checkinDaylocalized = moment(checkins[i].get("checkInDate")).utcOffset(timeZoneDifference);
//Find start time of checkIn day
var checkinDaylocalizedStart = checkinDaylocalized.startOf('day');
//Find number of days
var daysago = todayLocalizedStart.diff(checkinDaylocalizedStart, 'days');
// console.log("daysago = " + daysago);
days_array.push(daysago);
}
The second question I had was "is it normal to not see every console.log at runtime". I've talked with other Parse.com users and they report that Parse is inconsistent in logging. I was spending a lot of time debugging "problems" that were simply Parse not logging correctly.
Thanks to everyone that contributed to the answer.
I did make one other change - but it was not a bug. I replaced the query limit from 30 days in the past to simply "30". It's just a bit simpler with one less calculation.
I have a website that hosts a dashboard: I can edit the JavaScript on the page and I currently have it refreshing every five seconds.
I am trying to now get a window.print() to run every day at 8 AM.
How could I do this?
JavaScript is not the tool for this. If you want something to run at a specific time every day, you're almost certainly looking for something that runs locally, like python or applescript.
However, let's consider for a moment that JavaScript is your only option. There are a few ways that you could do this, but I'll give you the simplest.
First, you'll have to to create a new Date() and set a checking interval to see whether the hour is 8 (for 8 AM).
This will check every minute (60000 milliseconds) to see if it is eight o'clock:
window.setInterval(function(){ // Set interval for checking
var date = new Date(); // Create a Date object to find out what time it is
if(date.getHours() === 8 && date.getMinutes() === 0){ // Check the time
// Do stuff
}
}, 60000); // Repeat every 60000 milliseconds (1 minute)
It won't execute at exactly 8 o'clock (unless you start running this right on the minute) because it is checking once per minute. You could decrease the interval as much as you'd like to increase the accuracy of the check, but this is overkill as it is: it will check every minute of every hour of every day to see whether it is 8 o'clock.
The intensity of the checking is due to the nature of JavaScript: there are much better languages and frameworks for this sort of thing. Because JavaScript runs on webpages as you load them, it is not meant to handle long-lasting, extended tasks.
Also realize that this requires the webpage that it is being executed on to be open. That is, you can't have a scheduled action occur every day at 8 AM if the page isn't open doing the counting and checking every minute.
You say that you are already refreshing the page every five seconds: if that's true, you don't need the timer at all. Just check every time you refresh the page:
var date = new Date(); // Create Date object for a reference point
if(date.getHours() === 8 && date.getMinutes() === 0 && date.getSeconds() < 10){ // Check the time like above
// Do stuff
}
With this, you also have to check the seconds because you're refreshing every five seconds, so you would get duplicate tasks.
With that said, you might want to do something like this or write an Automator workflow for scheduled tasks on OS X.
If you need something more platform-agnostic, I'd seriously consider taking a look at Python or Bash.
As an update, JavaScript for Automation was introduced with OS X Yosemite, and it seems to offer a viable way to use JavaScript for this sort of thing (although obviously you're not using it in the same context; Apple is just giving you an interface for using another scripting language locally).
If you're on OS X and really want to use JavaScript, I think this is the way to go.
The release notes linked to above appear to be the only existing documentation as of this writing (which is ~2 months after Yosemite's release to the public), but they're worth a read. You can also take a look at the javascript-automation tag for some examples.
I've also found the JXA Cookbook extremely helpful.
You might have to tweak this approach a bit to adjust for your particular situation, but I'll give a general overview.
Create a blank Application in Automator.
Open Automator.app (it should be in your Applications directory) and create a new document.
From the dialog, choose "Application."
Add a JavaScript action.
The next step is to actually add the JavaScript that will be executed. To do that, start by adding a "Run JavaScript" action from the sidebar to the workflow.
Write the JavaScript.
This is where you'll have to know what you want to do before proceeding. From what you've provided, I'm assuming you want to execute window.print() on a page loaded in Safari. You can do that (or, more generally, execute arbitrary JS in a Safari tab) with this:
var safari = Application('Safari');
safari.doJavaScript('window.print();', { in: safari.windows[0].currentTab });
You might have to adjust which of the windows you're accessing depending on your setup.
Save the Application.
Save (File -> Save or ⌘+S) the file as an Application in a location you can find (or iCloud).
Schedule it to run.
Open Calendar (or iCal).
Create a new event and give it an identifiable name; then, set the time to your desired run time (8:00 AM in this case).
Set the event to repeat daily (or weekly, monthly, etc. – however often you'd like it to run).
Set the alert (or alarm, depending on your version) to custom.
Choose "Open file" and select the Application file that you saved.
Choose "At time of event" for the alert timing option.
That's it! The JavaScript code that you wrote in the Application file will run every time that event is set to run. You should be able to go back to your file in Automator and modify the code if needed.
function every8am (yourcode) {
var now = new Date(),
start,
wait;
if (now.getHours() < 7) {
start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0);
} else {
start = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8, 0, 0, 0);
}
wait = start.getTime() - now.getTime();
if(wait <= 0) { //If missed 8am before going into the setTimeout
console.log('Oops, missed the hour');
every8am(yourcode); //Retry
} else {
setTimeout(function () { //Wait 8am
setInterval(function () {
yourcode();
}, 86400000); //Every day
},wait);
}
}
To use it:
var yourcode = function () {
console.log('This will print evryday at 8am');
};
every8am(yourcode);
Basically, get the timestamp of now, the timestamp of today 8am if run in time, or tomorrow 8am, then set a interval of 24h to run the code everyday. You can easily change the hour it will run by setting the variable start at a different timestamp.
I don t know how it will be useful to do that thought, as other pointed out, you ll need to have the page open all day long to see that happen...
Also, since you are refreshing every 5 seconds:
function at8am (yourcode) {
var now = new Date(),
start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0);
if (now.getTime() >= start.getTime() - 2500 && now.getTime() < start.getTime() + 2500) {
yourcode();
}
}
Run it the same way as every8am, it look if 8am is 2.5second ahead or behind, and run if it does.
I try to give my answer hoping it could help:
function startJobAt(hh, mm, code) {
var interval = 0;
var today = new Date();
var todayHH = today.getHours();
var todayMM = today.getMinutes();
if ((todayHH > hh) || (todayHH == hh && todayMM > mm)) {
var midnight = new Date();
midnight.setHours(24,0,0,0);
interval = midnight.getTime() - today.getTime() +
(hh * 60 * 60 * 1000) + (mm * 60 * 1000);
} else {
interval = (hh - todayHH) * 60 * 60 * 1000 + (mm - todayMM) * 60 * 1000;
}
return setTimeout(code, interval);
}
With the startJobAt you can execute only one the task you wish, but if you need to rerun your task It's up to you to recall startJobAt.
bye
Ps
If you need an automatic print operation, with no dialog box, consider to use http://jsprintsetup.mozdev.org/reference.html plugin for mozilla or other plugin for other bowsers.
I will suggest to do it in Web Worker concept, because it is independent of other scripts and runs without affecting the performance of the page.
Create a web worker (demo_worker.js)
var i = 0;
var date = new Date();
var counter = 10;
var myFunction = function(){
i = i + 1;
clearInterval(interval);
if(date.getHours() === 8 && date.getMinutes() === 0) {
counter = 26280000;
postMessage("hello"+i);
}
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
Use the web worker in Ur code as follows.
var w;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("demo_worker.js");
w.onmessage = function(event) {
window.print();
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support HTML5 Web Workers";
}
}
}
I think it will help you.
I have written function which
allows expressing delay in seconds, new Date() format and string's new Date format
allows cancelling timer
Here is code:
"use strict"
/**
This function postpones execution until given time.
#delay might be number or string or `Date` object. If number, then it delay expressed in seconds; if string, then it is parsed with new Date() syntax. Example:
scheduleAt(60, function() {console.log("executed"); }
scheduleAt("Aug 27 2014 16:00:00", function() {console.log("executed"); }
scheduleAt("Aug 27 2014 16:00:00 UTC", function() {console.log("executed"); }
#code function to be executed
#context #optional `this` in function `code` will evaluate to this object; by default it is `window` object; example:
scheduleAt(1, function(console.log(this.a);}, {a: 42})
#return function which can cancel timer. Example:
var cancel=scheduleAt(60, function(console.log("executed.");});
cancel();
will never print to the console.
*/
function scheduleAt(delay, code, context) {
//create this object only once for this function
scheduleAt.conv = scheduleAt.conv || {
'number': function numberInSecsToUnixTs(delay) {
return (new Date().getTime() / 1000) + delay;
},
'string': function dateTimeStrToUnixTs(datetime) {
return new Date(datetime).getTime() / 1000;
},
'object': function dateToUnixTs(date) {
return date.getTime() / 1000;
}
};
var delayInSec = scheduleAt.conv[typeof delay](delay) - (new Date().getTime() / 1000);
if (delayInSec < 0) throw "Cannot execute in past";
if (debug) console.log('executing in', delayInSec, new Date(new Date().getTime() + delayInSec * 1000))
var id = setTimeout(
code,
delayInSec * 1000
);
//preserve as a private function variable setTimeout's id
return (function(id) {
return function() {
clearTimeout(id);
}
})(id);
}
Use this as follows:
scheduleAt(2, function() {
console.log("Hello, this function was delayed 2s.");
});
scheduleAt(
new Date().toString().replace(/:\d{2} /, ':59 '),
function() {
console.log("Hello, this function was executed (almost) at the end of the minute.")
}
);
scheduleAt(new Date(Date.UTC(2014, 9, 31)), function() {
console.log('Saying in UTC time zone, we are just celebrating Helloween!');
})
setInterval(() => {
let t = `${new Date().getHours() > 12 ? new Date().getHours() - 12 : new Date().getHours()}:${new Date().getMinutes().length < 2 ? '0' + new Date().getMinutes() : new Date().getMinutes()}:${new Date().getSeconds().length < 2 ? '0' + new Date().getSeconds() : new Date().getSeconds()} ${new Date().getHours()>12?"pm":"am"}`
console.log(t);
}, 1000);
http://jsbin.com/ocuceb/6/edit
The above link is where the full code is, I am trying to get a count down timer of how many hours and minutes are left till a business closes.
function countDown() {
var d = new Date();
var hour = d.getHours();
if(hour<10){hour="0"+hour;}
else if(hour>12){hour=hour - 12;}
var minutes = d.getMinutes();
if(minutes<10){minutes="0"+minutes;}
var seconds = d.getSeconds();
if(seconds<10){seconds="0"+seconds;}
var open = weekday[day.getDay()].open.replace(/am/g,'');
var close = weekday[day.getDay()].close.replace(/pm/g,'');
open = parseInt(open,10);
close = parseInt(close,10);
//confused here!
var timeClose = close;
var timeRemaining = Math.floor(d.getHours() - timeClose);
document.write('<br><br>Close At: '+timeClose+"pm<br>Time Remaining:"+timeRemaining);
}
And that is where I am having the trouble, I can get the time of being opened and the time of being closed. Originally I tried this
var timeClose = parseInt(close+':00:00',10);
var difference = Math.floor(d.getDay() - timeClose);
And of course this didn't work, it either said Undefined or NaN I'm not sure how to go about this, the timing is all new to me never needed this though a client asked for this. Where it states the Actual Time, What time they close, and show an image if the time is within the open to close time (basically an Open Neon Sign) and when past closed (a closed Neon Sign)... I figured it would be very simple, though I am having so tricky corners to pass.
JavaScript time does not think in 12-hour format. It thinks in 24-hour format. Change your array of objects to reflect (22 being 10pm):
hours[0]= {open:"8:00:00",close:"22:00:00"};
hours[1]={open:"8:00:00",close:"22:00:00"};
hours[2]={open:"8:00:00",close:"22:00:00"};
hours[3]={open:"8:00:00",close:"22:00:00"};
hours[4]={open:"8:00:00",close:"22:00:00"};
hours[5]={open:"8:00:00",close:"22:00:00"};
hours[6]={open:"8:00:00",close:"22:00:00"};
Also, parsing an int like this could lead to issues:
var timeClose = parseInt(close+':00:00',10);
You should substring everything between the colons to get your desired hours or minutes.
var timeClose = parseInt(open.substring(0,open.indexOf(":")),10);
Also with the way you have it set up, during business hours (or before 10pm), you will always have a negative number because you subtract the current hours from the close time. If it's 8pm and the close time is 10pm, we will have -2 hours remaining? Switch the operands to subtract getHours from time instead:
var timeRemaining = Math.floor(timeClose - d.getHours());
After that, you can probably check timeRemaining for a negative value. If it is negative, that means the business is closed, and you can modify your output message to reflect as such, i.e.
var timeRemaining = Math.floor(timeClose - d.getHours());
if (timeRemaining < 0) {
output = "Sorry we are closed already";
} else {
output = "You have " + timeRemaining + " to come in and shop till you drop";
}
I think a simpler way to do this would be something like this
var now=new Date();
var closing=new Date(now.getFullYear(),now.getMonth(),now.getDate(),21);//Set this to 10:00pm on the present day
var diff=closing-now;//Time difference in milliseconds
if(now.getHours<7){
//It's before opening time
}
else if(diff<0){
//It's after closing time
}
else{
var hours=Math.floor(diff/(1000*60*60));
diff=diff%(1000*60*60);
var mins=Math.floor(diff/(1000*60));
diff=diff%(1000*60);
var secs=Math.floor(diff/(1000));
}
Here is a reference on the time object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date