I have call center and I use this JS code to let messages come in during business hours and after business hours/weekends it display a message saying that is outside of support time, my question is, how I make this code work also for holidays?
exports.handler = async function(context, event, callback) {
const moment = require('moment-timezone');
var now = moment().tz('America/New_York');
console.log('Current time-->'+now);
console.log('current hours-->'+now.hour());
let isWorkingHours = false;
//let isWorkingHours = true; // testing
const weekday = now.isoWeekday();
console.log('weekday-->'+weekday);
if (now.hour() >= 9 && now.hour() <= 17 && weekday <= 5) {
//if (now.hour() >= 4 && now.hour() <= 20 && weekday <= 2) { // testing
isWorkingHours = true;
//Console.log('This is outside working hours');
}
callback(null, {
isWorkingHours: isWorkingHours
});
}
I got this holiday checker from someone else's post here on StackOverflow (I should have documented the link, but I forgot to). You can iterate through all the dates you are interested in to create a complete list of holidays, or just check if a given date is a holiday
function check_holiday (dt_date) {
// check simple dates (month/date - no leading zeroes)
var n_date = dt_date.getDate(),
n_month = dt_date.getMonth() + 1;
var s_date1 = n_month + '/' + n_date;
if ( s_date1 == '1/1' // New Year's Day
|| s_date1 == '6/14' // Flag Day
|| s_date1 == '7/4' // Independence Day
|| s_date1 == '11/11' // Veterans Day
|| s_date1 == '12/25' // Christmas Day
) return true;
// weekday from beginning of the month (month/num/day)
var n_wday = dt_date.getDay(),
n_wnum = Math.floor((n_date - 1) / 7) + 1;
var s_date2 = n_month + '/' + n_wnum + '/' + n_wday;
if ( s_date2 == '1/3/1' // Birthday of Martin Luther King, third Monday in January
|| s_date2 == '2/3/1' // Washington's Birthday, third Monday in February
|| s_date2 == '5/3/6' // Armed Forces Day, third Saturday in May
|| s_date2 == '9/1/1' // Labor Day, first Monday in September
|| s_date2 == '10/2/1' // Columbus Day, second Monday in October
|| s_date2 == '11/4/4' // Thanksgiving Day, fourth Thursday in November
) return true;
// weekday number from end of the month (month/num/day)
var dt_temp = new Date (dt_date);
dt_temp.setDate(1);
dt_temp.setMonth(dt_temp.getMonth() + 1);
dt_temp.setDate(dt_temp.getDate() - 1);
n_wnum = Math.floor((dt_temp.getDate() - n_date - 1) / 7) + 1;
var s_date3 = n_month + '/' + n_wnum + '/' + n_wday;
if ( s_date3 == '5/1/1' // Memorial Day, last Monday in May
) return true;
// misc complex dates
if (s_date1 == '1/20' && (((dt_date.getFullYear() - 1937) % 4) == 0)
// Inauguration Day, January 20th every four years, starting in 1937.
) return true;
if (n_month == 11 && n_date >= 2 && n_date < 9 && n_wday == 2
// Election Day, Tuesday on or after November 2.
) return true;
return false;
}
The logic for checking if an specific instant in time is outside working ours is in your if statement.
I would abstract this in some sort of storage, based on time ranges for holidays or any day off. You could either have a table or cache where to store these holidays (you should load them in advance).
That way, you can do something like:
Search if there's a holiday whose date matches with the current date (matching just date without timestamp, you can use moment's isSame checking just by date)
If there's a match, return isWorkingHours as false
To check if the date matches, you can use this (regardless of current time, it returns true as you're comparing at date level):
console.log(moment('2021-05-10 14:00:00').isSame('2021-05-10', 'day'));
Here's a list of things that you might want to check for:
Weekends
"Static date" holidays (eg: Christmas)
"Variable date" holidays (eg: Easter)
Times (eg: your office opens at 8:00)
/* Function that checks if office is available at a specific date
* #returns {boolean}
*/
function is_office_available (date = new Date()) {
// weekends, or actually any other day of the week
let day = date.getDay();
if ( [0 /*sunday*/, 6 /*saturday*/].includes(day) ) return false;
// "static date" holidays (formatted as 'DD/MM')
let dd_mm = date.getDate() + '/' + (date.getMonth()+1);
if ( ['24/12', '25/12'].includes(dd_mm) ) return false;
// TODO: "variable date" holidays
// specific times
// this logic has to be extended a LOT if, for example, you have
// the office open from 8:30 to 17:30 with a launch break from 12:00 to 13:00 on weekdays
// and from 9:00 to 12:00 only on mondays
let hh = date.getHours();
if (9 < hh || hh > 17) return false;
// if no test returned true then the office is going to be available on that date
return true;
}
You can simply call this function in an if statement.
"Variable date" holidays have a quite a long (and boring) implementation to do and it depends on the ones you have in your country office.
Related
I currently need to display a message on an order receipt notification that let's the use know that if they placed the order before Mondays at 7:00am, that it will ship on Thursday of the same week, and if they placed the order after Mondays at 7:00am, the delivery will go on Thursday of the following week.
Unfortunately I am not a javascript developer, but here is what I got so far:
<p id="shipment_note"></p>
<script>
var today, cutDate, text;
today = new Date();
cutDate = new Date();
cutDate.getDay([1])
cutDate.setHours([0,1,2,3,4,5,6,7])
if (today.getDay() <= cutDate) {
text = "Your order will ship next Thursday" ;
} else {
text = "Your order will ship Thursday of next week.";
}
document.getElementById("shipment_note").innerHTML = text;
</script>
I'm not sure if this approach is right and wanted to get some feedback if possible.
It says, if it's sunday, or if it's monday before 7....
see getHours and getDay.
const isBeforeMondayAt7 = d=>d.getDay() === 0 ||
(d=>d.getDay() === 1 && d.getHours() < 7);
if(isBeforeMondayAt7(new Date)){
alert("Your stuff's comin this thursady");
}else{
alert("Your stuff's comin next thurzday");
}
There are a number of issues with the code:
var today, cutDate, text;
today = new Date();
cutDate = new Date();
can be
var today = new Date(),
cutDate = new Date(),
text;
Then:
cutDate.getDay([1])
does nothing. getDay doesn't take any parameters, it returns the day number in the week (0 = Sunday, 1 = Monday, etc.). The returned value isn't stored or used so this line can be removed.
cutDate.setHours([0,1,2,3,4,5,6,7])
setHours requires integer parameters, not an array. Passed as values:
cutDate.setHours(0, 1, 2, 3, 4, 5, 6, 7)
will set the date's time to 0:01:02.003. The rest of the values are ignored.
if (today.getDay() <= cutDate) {
Here you're comparing the day number to a Date object. The <= operator coerces its arguments to number, so cutDate will be the time value for the Date, which will always be larger than today.getDay() for any date after 1970-01-01T00:00:00.006.
What you want to check is:
Is it currently Monday and
is the time before 7:00?
If so, set the delivery date to Thursday. If not, set the delivery date for Thursday of the following week. I assume your week starts on Monday not Sunday.
So in that case:
var today = new Date(),
cutDate = new Date(+today),
opts = {weekday:'long', day:'numeric', month:'long'},
text;
// If it's Monday and before 7am
if (today.getDay() == 1 && today.getHours() < 7) {
// Set cutDate to Thursday
cutDate.setDate(cutDate.getDate() + 3);
text = 'Your order will ship on ' +
cutDate.toLocaleString(undefined, opts) ;
} else {
// Set cutDate to thursday of next week
cutDate.setDate(cutDate.getDate() + (11 - (cutDate.getDay() || 7)));
text = 'Your order will ship on ' +
cutDate.toLocaleString(undefined, opts) ;
}
console.log('Today is ' + today.toLocaleString(undefined, opts) + '. ' + text);
I've included a more useful message (to me anyway). ;-)
It appears you may have inverted the order of the operators inside the if statement.
Perhaps...
change this line...
if (today.getDay() <= cutDate) {
to...
if (today.getDay() =< cutDate) {
Here is a sample using a ternary operator:
var today = new Date();
var text = new String();
text = (today.getDay() == 0 || (today.getDay() == 1 && today.getHours() < 7) || today.getDay() > 3) ? "Your order will ship next Thursday" : "Your order will ship Thursday of next week";
alert(text);
How about this guys?
<script>
var today, cutDate, text;
today = new Date();
cutDate = new Date();
cutDate.getDay([1,2,3,4,])
cutDate.setHours([0,1,2,3,4,5,6,7])
if (today.getDay() >= cutDate) {
text = "Your order will ship Thursday of next week." ;
} else if (today.getDay([5,6,7,0])) {
text = "Your order will ship next Thursday";
}
document.getElementById("shipment_note").innerHTML = text;
</script>
I want to disable the 2nd Saturday, 4th Saturday, Sunday and public holidays, throughout the year, using jQuery Calendar.
Jquery Calendar plugin provide you a option "beforeShowDay", you can
find more information on DataPickerUI
To Disable 2nd Saturday & 4th Saturday, you need to first calculate the sat or sunday of specific month then disable those dates, like we did for others calendars
sample code calculate sat & sunday https://www.hscripts.com/scripts/JavaScript/second-fourth.php
Created plunker for you,
https://plnkr.co/edit/inBYY748BptaCd7Ulwwg?p=preview
//To disable Sundays you need to find out the Day of current date.
$(function () {
var publicHolidays = [
[11, 28, 2015],
[11, 30, 2015]
];
$("#datepicker").datepicker({
beforeShowDay: function (date) {
var day = date.getDay();
return [(day !== 0), ''];
}
});
//To disable public holidays create an array with you holiday list then
//return false when you browse calender.
$("#datepicker2").datepicker({
beforeShowDay: function (date) {
for (i = 0; i < publicHolidays.length; i++) {
if (date.getMonth() == publicHolidays[i][0] &&
date.getDate() == publicHolidays[i][1] &&
date.getFullYear() == publicHolidays[i][2]) {
return [false];
}
}
return [true];
}
});
});
For what it's worth, here's a couple of functions for the second/fourth Saturday part of the problem.
Both functions accept an instance of javascript Date() and return true or false. You can use either one.
function is2ndOr4thSat_1(date) {
var day = date.getDay(),
week = Math.floor(date.getDate() / 7);
return day == 6 && (week == 1 || week == 3)
}
Hopefully is2ndOr4thSat_1() is self explanatory.
function is2ndOr4thSat_2(date) {
var d = date.getDate(),
offset = (((1 + date.getDay() - d) % 7) + 7) % 7;
return !((offset + d) % 14);
}
is2ndOr4thSat_2() is more obscure.
The expression (((1 + date.getDay() - d) % 7) + 7) % 7 finds the offset of the first of the month from a nominal zero (the 1st's preceding Saturday), using a true modulo algorithm that caters for negative numbers.
Then (offset + d) % 14 returns 0 if date is either 14 or 28 days ahead of the nominal zero, and ! converts to a boolean of the required sense (true for qualifying Saturdays otherwise false).
I need help with some Javascript strtotime-type code, please.
Our company runs a weekly promotion for 2 days only for its members. So when a member logs in, they see a banner promoting the promotion. If they happen to login outside of the promotion dates, the banner links to an information page. Otherwise, it links directly to the promotion.
Currently we're updating this by hand each week, which is a pain. We'd like to be able to use Javascript* to automatically change the link for us. OK, no problem, right?
Well, the thing is, what we don't want to have to do is go in and edit the script every week with the specific dates/times -- otherwise, what's the point? Currently the promotion runs Wednesday at 9a.m. to Thursday at 9a.m. It changes from time to time, every couple of months or so (Mon-Tue, 9a-9p, that sort of thing) so we will have to edit the script from time to time, but if we can avoid doing it weekly, that'd be great.
So here's what I came up with. It's heavily commented so my not-so-technical co-workers can go in and make the edits without too much difficulty.
var getData = function(){
var d = new Date();
var today = d.getDay(); // current day, numerically
var hr = d.getHours(); // current hour
// For Days:
// 0 = Sunday
// 1 = Monday
// 2 = Tuesday
// 3 = Wednesday
// 4 = Thursday
// 5 = Friday
// 6 = Saturday
var startDay = 3;
var endDay = 4;
// For Hours:
// This is a 24-hour clock. Midnight (12:00 AM) is 0, Noon = 12, 9 PM = 21, etc.
// So for a start time of 9 AM, put 9, and for an end time of 9 PM, put 21.
var startTime = 12;
var endTime = 15;
// Set the "url" variable to the NON-sale landing page. Put the SALE page URL in
// the "url" variables within the nested "if" statements below:
var url = 'http://link-to-the-non-promo-info-page';
if (( today >= startDay ) && ( hr >= startTime )) {
if ( today <= endDay ) && ( hr <= endTime )) {
url = 'http://link-to-the-live-promotion';
}
}
// ... non-essential variables and the actual display code
// below this line...
// ...
}
Notice I set the vars so that the promo runs 12p-3pm. If this were the real thing, the desired result would be for the promo link to display Wednesday 12pm to Thursday 3pm. What happens with this code, obviously, is that the promo banner is live Wednesday 12-3 and then Thursday 12-3.
I've goofed around with various permutations of the logic and haven't been able to hit the right one. Ultimately, I'd like to be able to open the script (or for one of my co-workers to open it), and be able to set the start day/time and end day/time, without having to set specific dates (Wednesday, July 24 to Thursday, July 25) and it just work.
If this were PHP I'd have it wrapped up. But it's Javascript, so any assistance I can get making this work would be fantastic.
Thanks,
Bob
UPDATE: #Kamala, I tweaked the time a bit by adding minutes, and a few other tweaks, but there's an issue of it not accepting the end time. Note that the script is set so that the start and end day is today, and the start/end times are now past (for EST zone, anyway) but the promo link is still being displayed:
var d = new Date();
var today = d.getDay(); // current day, numerically
var hr = d.getHours(); // current hour
var mn = d.getMinutes();
if (mn < 10) {
mn = "0"+mn;
}
var time = hr+":"+mn;
// For Days:
// 0 = Sunday
// 1 = Monday
// 2 = Tuesday
// 3 = Wednesday
// 4 = Thursday
// 5 = Friday
// 6 = Saturday
var startDay = 5;
var endDay = 5;
// For Hours:
// This is a 24-hour clock. Midnight (12:00 AM) is 0, Noon = 12, 9 PM = 21, etc.
// So for a start time of 9 AM, put 9, and for an end time of 9 PM, put 21.
var startTime = "11:00";
var endTime = "12:00";
// Set the "url" variable to the NON-sale landing page. Put the SALE page URL in
// the "url" variables within the nested "if" statements below:
var url1 = 'http://info-landing-page';
if (( today >= startDay ) && ( today <= endDay ) ) { // Awesome, we're within the promo days
if ( ( today != startDay && today != endDay ) // The promo is in full-swing - doesn't matter what time it is
|| ( today == startDay && time >= startTime )
|| ( today == endDay && time <= endTime ) ) {
url1 = 'http://promo-url';
alert("promo url set");
}
} else {
alert("we're pointing to the LP");
}
Is additional logic needed? Another nested "if" perhaps? I'm lost.
Thanks,
Bob
Try this...
if (( today >= startDay ) && ( today <= endDay ) ) { // Awesome, we're within the promo days
if( ( today != startDay && today != endDay ) // The promo is in full-swing - doesn't matter what time it is
||( today == startDay && hr >= startTime )
|| (today == endDay && hr <= endTime ) )
url = 'http://link-to-the-live-promotion';
}
}
So, what you need are two checks. If the promo's on day 1, is it after a certain time? Or if it's on day 2, is it before a certain time?
if ( today === startDay && hr >== startTime ) {
url = 'http://link-to-the-live-promotion';
} else if ( today === endDay && hr <== endTime ) {
url = 'http://link-to-the-live-promotion';
}
For your problem, there are no days in between the two days.. no need to check if day > startDay && day < endDay.
EDIT: Well, you probably want that capability in case your promo ever goes to 3 days. Here's another try handling this (rewritten to use OR's instead of if-else-if's:
if ((today > startDay && today < endDay) ||
(today == startDay && hr >= startTime) ||
(today == endDay && hr <= endTime)) {
url = 'http://link-to-the-live-promotion';
}
I have some friends' birthdays and want to separate them as follows :
birthdays which fall within the current week (within remaining days of current week starting from current day).
birthdays which fall within the current month (within remaining days of current month starting from current day).
birthdays which fall within the next month.
So all I want to know how to test each date in javascript to see if it falls within the remaining days of the current week/current month/next month.
N.B: say I have those dates in m/d/Y(06/29/1990) format.
Thanks
Convert your date and current time to Date object and use it for comparison. Some dry coding:
var now = new Date()
if (
(check.getFullYear() == now.getFullYear()) &&
(check.getMonth() == now.getMonth()) &&
(check.getDate() >= now.getDate())
) {
// remanining days in current month and today. Use > if you don't need today.
}
var nextMonth = now.getMonth() + 1
var nextYear = now.getFullYear()
if (nextMonth == 12) {
nextMonth = 0
nextYear++
}
if (
(check.getFullYear() == nextYear) &&
(check.getMonth() == nextMonth)
) {
// any day in next month. Doesn't include current month remaining days.
}
var now = new Date()
now.setHours(12)
now.setMinutes(0)
now.setSeconds(0)
now.setMilliseconds(0)
var end_of_week = new Date(now.getTime() + (6 - now.getDay()) * 24*60*60*1000 )
end_of_week.setHours(23)
end_of_week.setMinutes(59)
end_of_week.setSeconds(59) // gee, bye-bye leap second
if ( check >=now && check <= end_of_week) {
// between now and end of week
}
the code Using the Parse Date is
var selecteddate = '07/29/1990';
var datestr = selecteddate.split('/');
var month = datestr[0];
var day = datestr[1];
var year = datestr[2];
var currentdate = new Date();
var cur_month = currentdate.getMonth() + 1;
var cur_day =currentdate.getDate();
var cur_year =currentdate.getFullYear();
if(cur_month==month && day >= cur_day)
{
alert("in this month");
}
else
{
alert("not in this month");
}
I need Javascript code for a website to automatically adjust a date. The goal is to have the code automatically adjust the following statement to be the second Saturday of every month from now until eternity:
Next membership meeting: Saturday, MONTH, DAY, YEAR 11 a.m. to noon.
Anyone have an idea? Much appreciated!
This function will get you the date object, you can pull out what you need from it:
var getMeeting = function(year, month){
var date = new Date(year, month, 1, 0, 0, 0, 0);
date.setDate(14-date.getDay());
return date;
};
alert(getMeeting(2011,5));
I didn't test but here is the basics:
//our main code
var Months = ["Jan", "Feb", "Mar", /*... you finish... */ ];
var meetingDate = getMonthlyMeeting();
document.Write( "<i>Next membership meeting:</i> Saturday, " + Months[meetingDate.getMonth()] + ", " + meetingDate.getDay() + ", " + meetingDate.getYear() + " 11 a.m. to noon.");
// call this to get the monthly meeting date
// returns a Date() object
function getMonthlyMeeting(){
var today = new Date(); //JS automatically initializes new Date()s to the current time
//first, see if today is our meeting day
var meetingDate;
var thisMonthsMeeting = getSecondTuesdayInMonth(today.getMonth(), today.getYear());
if( thisMonthsMeeting.getDay() == today.getDay() ){
// today is our meeting day!
meetingDate = today;
}
else {
if ( today.getDay() < thisMonthsMeeting.getDay() ){
// it hasn't happened this month yet
meetingDate = thisMonthsMeeting;
} else {
//this month's meeting day has already passed
if( today.getMonth() == 11 ){
// rolling over to the next year
meetingDate = getSecondTuesdayInMonth(0, today.getYear() + 1);
} else {
meetingDate = getSecondTuesdayInMonth(today.getMonth() + 1, today.getYear());
}
}
}
return meetingDate;
}
// this is a helper function to get the second tuesday in any month
// returns a Date() object
function getSecondTuesdayInMonth(var month, var year){
var saturdays = 0;
var testDay= new Date();
while( testDay.getDay() != 2 && saturdays < 2 ){
//while the day we are testing isnt tuesday (2) and we haven't found it twice
if( testDay.getDay() == 2 )
saturdays = saturdays + 1; //we found a saturday
testDay= new Date(testDay.getTime() + 86400000); //increment our day to the next day
}
//when we finish the while loop, we are on our day
return testDay;
}
So, I figure that the meat of your problem is: How do I know what the second saturday of each month is?
Not tested, but this is what I came up with:
It is abstracted for any nth day of any month.
nthDate = function(nth_week, nth_day, month){
var src_date = new Date();
src_date.setDate(1);
src_date.setMonth(month);
return ( (nth_week * 7) - src_date.getDay() ) - ( Math.abs( nth_day - 6) );
};
var cur_date = new Date();
var cur_day = cur_date.getDay();
//2 for the 2nd week of the month
//6 is the integer value for saturday (days of the week 0-6)
var nth_date = nthDate( 2, 6, cur_date.getMonth() );
if(cur_day < nth_date){
//display the upcoming date here
}else if( cur_day > nth_date){
//figure out next month's date and display that
var next_date = nthDate(2, 6, (cur_date.getMonth() +1) );
//does this deal with the case of the month being december?? not sure.
}
The 2nd week is in the range of 14 days into the month.
We can:
first subtract the offset for the day of the week that this month starts with,
then second:
we can subtract the offset for the day of the week that we are looking for.
(this needs to be the offset of days, so saturday is a 0 (zero) offset. We get this value from the absolute value of nth day minus the number of days in the week.
This gives us the date of the second saturday.
Then, because you have some ints you can do a simple compare against the values.
If we're before the second saturday, display that, if not calculate a new date for next month.
Hope that helps.