I have a input date picker which will pick the current system date. onclick of button. I need to add nine bussiness days to current day and display it into input value,
so that only weekdays are exclude when we add the days.
For example,
if you have today's date (01/31/2011) and i want to add 9 days, the
answer should be 10/3/06 because the(02/03/2011) weekend should not be counted.
Does anyone know how this can be done?
for this you need to crate one sql function like:
create function fn_IsWeekDay
(
#date datetime
)
returns bit
as
begin
declare #dtfirst int
declare #dtweek int
declare #iswkday bit
set #dtfirst = ##datefirst - 1
set #dtweek = datepart(weekday, #date) - 1
if (#dtfirst + #dtweek) % 7 not in (5, 6)
set #iswkday = 1 --business day
else
set #iswkday = 0 --weekend
return #iswkday
end
Short and sweet. Now you can simply do this:
if dbo.fn_IsWeekDay(#date) = 1
begin
--do some magic here ;
end
--or
implemented functionality
You probably will need something more advanced, but assuming that you just want to discard Saturday and Sunday you can do something like this (just basic calculation, hope I did not count wrong):
<script>
today = new Date();
endDate=today; //Init.
alert(today);
dayOfWeek=today.getDay();
//0: Sunday
if(dayOfWeek==0 || dayOfWeek==1)endDate.setDate(today.getDate() + 11);
else if(dayOfWeek==6)endDate.setDate(today.getDate() + 12);
else endDate.setDate(today.getDate() + 13);
alert(endDate);
</script>
EDIT: this assumes "woking days" Mon, Tue, Wed, Thu, Fri
Related
I'm working on a program where I get dates like this:
2016-08-31T00:00:00
so my goal is to do 3 comparisons:
1.- Need to show "Due" if appoinment has already happended.
2.- Need to show "Due next Month" if appoinment is due next month.
3.- Need to show "Due this month" if appoinment is due this month.
So far I'm able to show message "Due" by doing this:
var someTime = "2016-08-31T00:00:00";
if(new Date(someTime).getTime() < new Date()){
console.log("Due");
}
So how can I get the "Due next Month" and "Due this month" calculations working? Thanks a lot in advance!
Why not something like this:
function appointment(srcDate) {
console.log('');
console.log(srcDate);
var today = new Date();
var todayNextMonth = today.getMonth() + 1;
todayNextMonth = todayNextMonth > 11 ? 0 : todayNextMonth;
if (srcDate < today) {
console.log("Due");
} else if (srcDate.getMonth() === today.getMonth()) {
console.log("Due this month");
} else if (srcDate.getMonth() === todayNextMonth) {
console.log("Due next month");
}
}
appointment(new Date("2016-08-31T00:00:00"));
appointment(new Date("2018-05-29T00:00:00"));
appointment(new Date("2018-06-15T00:00:00"));
See jsfiddle
Use a function, easier to test.
Keep in mind that getMonth() is zero-indexed, so januari equals 0, not 1 etc.
Not sure why you use getTime() to compare with a Date object, you can omit the getTime(). But keep in mind that if an appointment date is 5 minutes in the future, it will show 'Due this month'. You'll have to add in extra logic to show 'Due today' if you require that.
You can get the current month by doing:
const today = new Date();
const month = today.getMonth();
Technically then, you can add 1 to get the next month: const nextMonth = month + 1;
But understand that doing it like that can run into issues if the date is something like Jan 31 (which then the above will give you March as the next month).
See this question and answers for more information on that: Javascript Date: next month
Alternatively, if you're doing a lot of work with dates, you can use a library like moment.js.
I am looking to do something quite complex and I've been using moment.js or countdown.js to try and solve this, but I think my requirements are too complex? I may be wrong. Here is the criteria...
I need to be able to have the following achievable without having to change the dates manually each year, only add it once and have many countdowns on one page.
Find current date
Find current year
Find current month
Find day within week of month that applies
¬ 3rd Sunday or 2nd Saturday
Convert to JS and output as html and run countdown
When past date - reset for following year
Pretty mental. So for example if an event is always on the 3rd Sunday of March. The date would not be the same each year.
2016 - Sunday March 19th
2017 - Sunday March 20th
2018 - Sunday March 18th etc.
I hope this is explained well, I realise it may be a total mess though. I managed to get it resetting each year with the date added manually but then someone threw in the spanner of the date being different each year.
var event = new Date();
event = new Date(event.getFullYear() + 1, 3 - 1, 19);
jQuery('#dateEvent').countdown({ until: event });
<div id="dateEvent"></div>
I have edited this answer as I have now put together a solution that works for me. As I believe this isn't simple coding due to the fact it wasn't actually answered 'Please, this is basic coding. pick up a javascript book and learn to code', yeah thanks...
// get the specific day of the week in the month in the year
function getDay(month) {
// Convert date to moment (month 0-11)
var myMonth = moment("April", "MMMM");
// Get first Sunday of the first week of the month
var getDay = myMonth.weekday(0); // sunday is 0
var nWeeks = 3; // 0 is 1st week
// Check if first Sunday is in the given month
if (getDay.month() != month) {
nWeeks++;
}
// Return 3rd Sunday of the month formatted (custom format)
return getDay.add(nWeeks, 'weeks').format("Y-MM-D h:mm:ss");
}
// print out the date as HTML and wrap in span
document.getElementById("day").innerHTML = '<span>' + getDay() + '</span>';
Using
<script src="moment.js"></script>
Hope it helps someone - I'll update when I figure how to + 1 year after it's checked current date and event has passed. I'll look in that JS book.
Please take a look at the below code, I explained in the comment what what does.
You use it by supplying a javascript Date object of any wished start date, and then add as a second value the corresponding year you wish to know the date in.
var date = new Date("2016-03-20");
function getDayInYear(startDate, year) {
// get a moment instance of the start date
var start = moment(startDate);
// collect the moment.js values for the day and month
var day = start.day();
var month = start.month();
// calculate which week in the month the date is.
var nthWeekOfMoth = Math.ceil(start.date() / 7);
// Build up the new moment with a date object, passing the requested year, month and week in it
var newMoment = moment(new Date(year,month,(nthWeekOfMoth * 7)));
// Return the next instance of the requested day from the current newMoment date value.
return newMoment.day(day);
}
var oldMoment = moment(date);
var newMoment2017 = getDayInYear(date,2017);
var newMoment2018 = getDayInYear(date,2018);
console.log(oldMoment.format('YYYY MMMM dddd DD'));
console.log(newMoment2017.format('YYYY MMMM dddd DD'));
console.log(newMoment2018.format('YYYY MMMM dddd DD'));
/** working from today up to 10 years into the future **/
var date = new Date();
var year = date.getFullYear();
for(var i = 0; i < 11; i++) {
console.log(getDayInYear(date, year+i).format('YYYY MMMM dddd DD'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
I seem to have a bit of a problem getting the previous Monday given a particular date. I'm trying to use Moment js for the task. Obviously, I can do it by hand, but found it curious that I couldn't get it to work using the example in the moment.js documentation on their website: http://momentjs.com/docs/#/get-set/day/.
I was trying something like:
moment([2013, 08, 15, 15, 20]).day(-1).format('ddd, MMM DD')
which results in the 'two days ago' date, that being September 13 instead of the expected September 9th.
Does anybody have a clue here? Thanks.
Here is how it works:
moment().day(1) // this monday
moment().day(-6) // last monday, think of it as this monday - 7 days = 1 - 7 = -6
Same applies in other direction:
moment().day(8) // next monday, or this monday + 7 days = 1 + 7 = 8
Your code moment().day(-1) can be explained as this Sunday - 1 day = 0 - 1 = -1
or this Saturday - 7 days = 6 - 7 = -1
The accepted answer only works if you already know whether the day in question is in this week or next week. What if you don't know? You simply need the next available Thursday following some arbitrary date?
First, you want to know if the day in question is smaller or bigger than the day you want. If it's bigger, you want to use the next week. If it's smaller, you can use the same week's Monday or Thursday.
const dayINeed = 4; // for Thursday
if (moment().isoWeekday() <= dayINeed) {
return moment().isoWeekday(dayINeed);
} else...
If we're past the day we want already (if for instance, our Moment is a Friday, and we want the next available Thursday), then you want a solution that will give you "the Thursday of the week following our moment", regardless of what day our moment is, without any imperative adding/subtracting. In a nutshell, you want to first go into the next week, using moment().add(1, 'weeks'). Once you're in the following week, you can select any day of that week you want, using moment().day(1).
Together, this will give you the next available day that meets your requirements, regardless of where your initial moment sits in its week:
const dayINeed = 4; // for Thursday
// if we haven't yet passed the day of the week that I need:
if (moment().isoWeekday() <= dayINeed) {
// then just give me this week's instance of that day
return moment().isoWeekday(dayINeed);
} else {
// otherwise, give me next week's instance of that day
return moment().add(1, 'weeks').isoWeekday(dayINeed);
}
See also: https://stackoverflow.com/a/27305748/800457
function nextWeekday (day, weekday) {
const current = day.day()
const days = (7 + weekday - current) % 7
return day.clone().add(days, 'd')
}
// example: get next Friday starting from 7 Oct 2019
nextWeekday(moment('2019-10-07'), 5)) // 2019-10-11
I think the point is that using day() or isoWeekday() you get a date in the current week, no matter which day of the week is today. As a consequence, the date you get can be past, or still to come.
Example:
if today is Wednesday, moment().isoWeekday(5).format() would return the date of the upcoming Friday.
While
moment().isoWeekday(1).format() would return the previous Monday.
So when you say you want the date of, let's say, "last Tuesday", this date could belong to the current week or to the previous week, depending on which day is today.
A possible function to get the date of the last dayOfTheWeek is
function getDateOfPreviousDay(dayOfTheWeek) {
currentDayOfTheWeek = moment().isoWeekday();
if ( currentDayOfTheWeek >= dayOfTheWeek ) {
return moment().isoWeekday(dayOfTheWeek).format(); // a date in the current week
}
else {
return moment().add(-1,'weeks').isoWeekday(dayOfTheWeek).format(); // a date in the previous week
}
}
const upcomingDay = (dayIndex, format = "DD MMMM YYYY") => {
if (
Number(moment().format("D")) >= Number(moment().day(dayIndex).format("D"))
) {
return moment()
.day(7 + dayIndex)
.format(format);
}
return moment().day(dayIndex).format(format);
};
Problem
I'm using AngularJS and in my view I have 7 days in a row like the pic below. The red, grey, and blue are based on a date (9/1/2013 Sunday). When I click Friday or Monday I want that date to be returned so I can reload the 0/3 with the stats for that date.
I don't need anything fancy for AngularJS I can't figure out the logic to take a base date and then switch the day out for the day that was clicked.
How do I get this to return a date?
Current base date: 9/1/2013 - Sunday
I click: Thursday
I receive: 8/29/2013 - Thursday
I click: Sunday
I receive: 9/1/2013
What it looks like
I'm currently trying to convert this function from:
JavaScript - get the first day of the week from current date
function getMonday(d) {
d = new Date(d);
var day = d.getDay(),
diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
return new Date(d.setDate(diff));
}
getMonday(new Date()); // Mon Nov 08 2010
Solved!
I render the dates server side when I render my stats.
Using AngularJS:
My directives: http://paste.laravel.com/Nz9
My HTML template: http://paste.laravel.com/Nza
My PHP: http://paste.laravel.com/Nzc
Forget about what it looks like, let's focus on what data you have.
If I'm understanding you correctly, you have an associative array of something like:
[{'M',0},{'T',1},{'W',2},{'T',3},{'F',4},{'S',5},{'S',6}]
And you also have a base date
var base = moment('2013-09-01');
And the base is associated with the last value - the 6.
So then what you could do is something like this:
var x = 3; // I clicked on Thursday and got a 3
var target = base.subtract('days', 6-x); // move back 6-x days
That would work, but wouldn't it be much easier just to precalculate your associative array in the first place?
[{'M','2013-08-26'},
{'T','2013-08-27'},
{'W','2013-08-28'},
{'T','2013-08-29'},
{'F','2013-08-30'},
{'S','2013-08-31'},
{'S','2013-09-01'}]
Then you would already know what value to use when it was clicked.
The problem with moment's day() is that Sunday == 0, not Monday, so you have to jump one week back and use the range 1..7 for Monday..Sunday:
base = '9/1/2013'
console.log(moment(base).day(-7).day(4))
> Thu Aug 29 2013 00:00:00 GMT+0100
console.log(moment(base).day(-7).day(7))
> Sun Sep 01 2013 00:00:00 GMT+0100
This is very weird I don't know what I'm doing wrong. I have a function to grab the date (i.e in this format: 06/24/2011), here's the function:
function checkDate(input){
var d = new Date();
var dspl = input.split("/");
if(dspl.length != 3)
return NaN;
d.setDate(dspl[1]);
d.setMonth(Number(dspl[0])-1);
if(dspl[2].length == 2)
d.setYear("20"+(dspl[2]+""));
else if(dspl[2].length == 4)
d.setYear(dspl[2]);
else
return NaN;
var dt = jsToMsDate(new Date(d));
return dt;
}
If I enter any date of the month, it would parse the date correctly, but if I enter 31st, i.e "01/31/2011", then it would turn into "01/01/2011". I'm not sure what to do and not really sure where the problem might be.
JavaScript's Date objects allow you to give invalid combinations of months and days; they automagically correct those for you (so for instance, if you set the day of the month to 31 when the month is June, it automatically makes it July 1st). That means if you set the fields individually, you can run into situations where that automagic correction gets in your way.
In your case, if you're going to set all three of those fields, you're better off using the form of the Date constructor that accepts them as arguments:
var dt = new Date(year, month, day);
(If you want hours, minutes, seconds, and milliseconds, you can add them as parameters as well.)
So looking at your code, an off-the-cuff update:
function checkDate(input){
var year, month, day, d, dt;
var dspl = input.split("/");
if(dspl.length != 3)
return NaN;
year = parseInt(dspl[2], 10);
month = parseInt(dspl[0], 10) - 1;
day = parseInt(dspl[1], 10);
if (isNaN(year) || isNaN(month) || isNaN(day)) {
return NaN;
}
if (year < 100) {
year += 2000;
}
d = new Date(year, month, day);
var dt = jsToMsDate(d);
return dt;
}
Some other notes on that update:
It's best to use parseInt to parse numbers from end users, and to always specify the radix (10 for decimal). (No, parseInt is not slower than Number or the unary + trick. People assume it is, but it isn't.)
No need to muck about with strings to add 2000 to years given with only two digits. But you can if you like. Note I weakened the validation there, allowing one-digit years for (say) 2001 and three-digit years for (say) 300 AD. So if you need it to be that strong, you'll need to readjust that.
No need to feed the date instance into new Date() again.
You need to set the month before setting the day (or as Marc B points out in his comment, use the Date(yearval, monthval, dayval) constructor).
When you create a Date object, it defaults to the current date. At the time of writing that's in June, so when you try to set the day to 31 it wraps.
...And because of similar behaviour in leap years, you should set the year before setting the month or day.
(It's a good job you developed this code in June rather than in July - the bug would have lurked undiscovered until September, and it would probably have been your users that found it rather than you. :-)
Right hierarchy is set year, then Month and at last add the Day.
This will return the exact date that you added.
function checkDate() {
//Wrong order- will return 1 May 2016
var start = new Date();
start.setDate(31);
start.setMonth(4);
start.setFullYear(2016);
alert(start)
//Right order - will return 31 May 2016
var end = new Date();
end.setFullYear(2016);
end.setMonth(4);
end.setDate(31);
alert(end)
}
<input type="button" value="Test" onclick="checkDate()" />
This is the right heirarchy to set date.
Why are you adding 1 the day position (position 1)? I think that is your problem.
d.setDate(dspl[1] + 1);