Moment.js, Get next [weekday] - javascript

Trying to get second coming Thursday (e.g.) using moment.js. Not this Thursday. The next one. The date in 2 Thursdays.
I have tried
moment().add(1, 'week').day(4)
which just fetches Thursday of the next week (only works if current weekday is before Thursday)
Any ideas?

"which just fetches Thursday of the next week (only works if current weekday is before Thursday)"
It's happening because .add(1, 'week') just adds 7 days and gets you the next week date and you are fetching 4th day of that week.
Below code will work for your case perfectly.
if(moment().weekday() < 4)
moment().add(1, 'week').day(4);
else
moment().add(2, 'week').day(4);

Not sure about using moment.js, but in plain js next Thursday is given by:
currentDate + (11 - d.getDay() % 7)
For the following Thursday, just add 7 days. Presumably if the current day is Thursday, want the Thursday in two weeks so:
var d = new Date();
console.log(d.toString());
// Shift to next Thursday
d.setDate(d.getDate() + ((11 - d.getDay()) % 7 || 7) + 7)
console.log(d.toString())
Or encapsulated in a function with some tests:
function nextThursdayWeek(d) {
d = d || new Date();
d.setDate(d.getDate() + ((11 - d.getDay()) % 7 || 7) + 7);
return d;
}
// Test data
[new Date(2017,2,6), // Mon 6 Mar 2017
new Date(2017,2,7), // Tue 7 Mar 2017
new Date(2017,2,8), // Wed 8 Mar 2017
new Date(2017,2,9), // Thu 9 Mar 2017
new Date(2017,2,10), // Fri 10 Mar 2017
new Date(2017,2,11), // Sat 11 Mar 2017
new Date(2017,2,12), // Sun 12 Mar 2017
new Date() // Today
].forEach(function (date) {
console.log(date.toString() + ' -> ' + nextThursdayWeek(date).toString());
});

Related

Getting Week Numbers of a Year where week number is starting from January 1st

I have the following code to get the week number when I rpovide a date
Date.prototype.getWeek = function () {
var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
d.setUTCDate(d.getUTCDate() - d.getUTCDay());
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
}
when I pass the date 2018-01-01 the weekNumber is given as 53 as january 1st of 2018 lay on the last week of 2017. How can I get the week number by making the year start at january 1st instead of making the the start day of each week is a sunday ?
You can calculate the number of whole weeks since Jan 1 using UTC date values to avoid daylight saving issues. Starting from 1ms before 1 Jan and using Math.ceil means 1 Jan is the first day of week 1.
The following is a slight refactoring of your code:
// Get week number based on start of 1 Jan
function getWeekNumber(date = new Date()) {
const msPerWeek = 5.828e8;
// Use UTC values to remove timezone issues
let d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
// Set epoch to 1 ms before 1 Jan
let e = new Date(Date.UTC(d.getUTCFullYear(), 0, 0, 23, 59, 59, 999));
// Return week number
return Math.ceil((d - e) / msPerWeek);
}
[new Date(2019,0,1), // Tue 1 Jan, week 1
new Date(2019,0,7), // Mon 7 Jan, week 1
new Date(2019,0,8), // Tue 8 Jan, week 2
new Date(2019,0,15), // Tue 15 Jan, week 3
new Date() // Today
].forEach( date => console.log(date.toDateString() + ': ' + getWeekNumber(date)));

Script to display date for coming bi-monthly Friday

Cut Off Date: the cut off date is set as the coming bimonthly Friday (eg cut off dates are Jun 14 and Jun 28. If the submission is done today(June26th), then cut off date is Jun 28. If the submission is done on Jun 29th, the cut off date would be Jul 12. Once it's July 13th the next cutoffdate would be July 26th. And so on, depending on when the user submits the form it will display the correct cutoffdate. I've looked around at a few other examples, but can't find one for what I want.
var currentDate = new Date(new Date().getTime())
document.getElementById('lastsubmission').value =
(currentDate.getDate()) + '/' + (currentDate.getMonth() + 1) + '/' +
currentDate.getFullYear() + '#' + currentDate.getHours() + ':' +
currentDate.getMinutes() + ':' + currentDate.getSeconds();
You seem to want to get the next Friday after a date that is either the second or fourth Fridays of a month. Something like:
Get the second Friday of the date's month
If it's before that, return the second Friday
If it's after then, get the fourth Friday of the month
If it's before then, return the fourth Friday
If it's after then, return the second Friday of next month
So you might need a function to get a particular Friday given a date, and some other code to do the rest of the logic, e.g.
// Given a Date, return the nth Friday of that month
function getNthFriday(date, n) {
// Get first Friday
let d = new Date(date);
d.setDate(1);
let day = d.getDay();
d.setDate(d.getDate() + 5 - (day > 5? -1 : day));
// Set to nth Friday
d.setDate(d.getDate() + (n-1)*7);
return d;
}
// Return the next Friday after date that is either the
// second or fourth Friday's of a month.
function getCutoffDate(date) {
// Get 2nd Friday
var friday = getNthFriday(date, 2);
// If before, return 2nd Friday
if (date < friday) {
return friday;
}
// Get 4th Friday
friday = getNthFriday(date, 4);
// If before, return 4th Friday
if (date < friday) {
return friday;
}
// Otherwise, return 2nd Friday of next month
friday = getNthFriday(new Date(date.getFullYear(), date.getMonth()+1, 1), 2);
return friday;
}
// Some tests
[
new Date(2019,4,30), // 30 May 2019 -> 14 Jun
new Date(2019,5, 1), // 2 Jun 2019 -> 14 Jun
new Date(2019,5,13), // 13 Jun 2019 -> 28 Jun
new Date(2019,5,23), // 23 Jun 2019 -> 14 Jun
new Date(2019,5,30) // 30 Jun 2019 -> 12 Jul
].forEach(d => {
console.log(getCutoffDate(d).toString());
});
A library might help with getting the nth Friday, and getting the first day of the next month.

Are there any JavaScript methods that can replicate the Oracle's ADD_MONTH() functionality

1) Oracle's example of ADD_MONTHS(date, 1):
SELECT ADD_MONTHS('30-Nov-15', 3) FROM dual;
February, 29 2016 00:00:00
2) JavaScript:
var date= new Date("Mon Nov 30 2015 00:00:00");
date.setMonth(date.getMonth() + 3);
Tue Mar 01 2016 00:00:00
Are there any JavaScript methods that can replicate the Oracle's ADD_MONTH() functionality ?
If you want to implement the same logik as in Oracle function - i.e. for "shorter" month you do not overflow in the next month, I guess you will need to do it yourself:
Pseudocode:
myDay = date.getDate(); // save the date
date.setMonth(date.getMonth() + 3); // add months
myNewDay = date.getDate();
while (myDay != myNewDay & myNewDay <= 3) {
myNewDay = myNewDay -1 // go back one day
date.setDate(myNewDay); // restore the
}
So if you end with the same day of the month after adding months you are ready.
If you get a different day of month, it will be 1,2 or 3 (the difference in month length);
go back day by day until you reach the end of the month.
This is my knowledge of the Oracle algorithm. HTH.
date.getMonth()
returns the previous months date instead of this months date. So to add to the correct date just do
date.setMonth(date.getMonth() + 2);

Get start and end day of week considering year starting in the middle of week [duplicate]

This question already has answers here:
How to get first and last day of the current week in JavaScript
(32 answers)
Closed 7 years ago.
I was using a function to return me the start and end day of a given week number from the year. Here is the function:
function getWeekRange(week){
var d = new Date("Jan 01, " + $scope.today.getFullYear() + " 01:00:00");
var w = d.getTime() + 604800000 * (week);
var d1 = new Date(w);
var d2 = new Date(w + 518400000);
return {
startDate: d1,
endDate: d2,
};
}
I set the year dynamically, and let's see an example where the year is 2015. Considering the week number starting by 0, if I use getWeekRange(0) I will receive the following result:
{
startDate: Thu Jan 01 2015 01:00:00 GMT-0200 (BRST),
endDate: Wed Jan 07 2015 01:00:00 GMT-0200 (BRST)
}
The problem is that this code does not consider the year of 2015 starting on a Thursday. The correct result for getWeekRange(0) should be:
{
startDate: Thu Jan 01 2015 01:00:00 GMT-0200 (BRST),
endDate: Sat Jan 03 2015 01:00:00 GMT-0200 (BRST)
}
and the result for getWeekRange(1) should be:
{
startDate: Sun Jan 04 2015 01:00:00 GMT-0200 (BRST),
endDate: Sat Jan 10 2015 01:00:00 GMT-0200 (BRST)
}
Does anyone have a clue?
-- EDIT --
My question is different from this one, because I don't have a given day of the year, I have only a week number of the year (from 0 to 51), and my case considers that the first week of the year is only a part of a full week, as mentioned by likeitlikeit.
I could find a simple solution for my question, since only the first week of my year could cause me problems. Here is the code:
function getWeekRange(week){
var d = new Date("Jan 01, " + $scope.today.getFullYear() + " 01:00:00");
var firstWeekDays = 7 - d.getDay();
var d1, d2;
if(week > 0) {
var w = d.getTime() + 604800000 * (week-1) + 24*60*60*1000 * firstWeekDays;
d1 = new Date(w);
d2 = new Date(w + 518400000);
} else {
d1 = d;
d2 = new Date(d1.getTime() + 24*60*60*1000 * (6 - d1.getDay()));
}
return {
startDate: d1,
endDate: d2,
};
}
There are 2 main diferences from the initial code.
For the week of the year I simply get the initial day of the year, and then based on the day of the week it starts I can find the end day of the week
For the other weeks, I sum 7*week-1 days to initial day (this sum does not consider the number of days of the first week), and also add firstWeekDays which is the number of days of first week (because it is not always 7 as the other weeks).
If anyone has a better solution, I will be glad to listen.
This answer shows how to get the first day of a week using getDate to calculate the offset from the current day.
Using this method, you can use getDate to determine which day of the week the first day of the year falls on. You can then subtract the last day of the week from this value to know how many days to add to your d2 in order to compute the date for Saturday by adjusting your date from the first day of the year + the offset in days till the end of the week for Jan 1.

Javascript: find beginning of Advent weeks each year

I have created the following code (which works) to print something different based on the weeks of a specified month:
<script language="javascript">
<!--
var advent;
mytime=new Date();
mymonth=mytime.getMonth()+1;
mydate=mytime.getDate();
if (mymonth==12 && (mydate >= 1 && mydate <= 6)){document.write("xxx");
}
if (mymonth==12 && (mydate >= 7 && mydate <= 13)){document.write("yyy");
}
if (mymonth==12 && (mydate >= 14 && mydate <= 20)){document.write("zzz");
}
if (mymonth==12 && (mydate >= 21 && mydate <= 30)){document.write("qqq");
}
//-->
</script>
But I need this to change for Advent each year and Advent changes based on when Christmas falls each year:
Advent starts on the Sunday four weeks before Christmas Day. There are
four Sundays in Advent, then Christmas Day. The date changes from year
to year, depending on which day of the week Christmas fall. Thus, in
2010, Advent began on 28 November. In 2011, it will occur on 27
November.
How do I calculate when the weeks of Advent begin each year?
Start with a Date that's exactly 3 weeks before Christmas Eve. Then, walk backwards until the day-of-week is Sunday:
function getAdvent(year) {
//in javascript months are zero-indexed. january is 0, december is 11
var d = new Date(new Date(year, 11, 24, 0, 0, 0, 0).getTime() - 3 * 7 * 24 * 60 * 60 * 1000);
while (d.getDay() != 0) {
d = new Date(d.getTime() - 24 * 60 * 60 * 1000);
}
return d;
}
getAdvent(2013);
// Sun Dec 01 2013 00:00:00 GMT-0600 (CST)
getAdvent(2012);
// Sun Dec 02 2012 00:00:00 GMT-0600 (CST)
getAdvent(2011);
// Sun Nov 27 2011 00:00:00 GMT-0600 (CST)
(2013 and 2012 were tested and verified against the calendar on http://usccb.org/. 2011 was verified against http://christianity.about.com/od/christmas/qt/adventdates2011.htm)
Here's what I was talking about in my comment:
function getAdvent(year) {
var date = new Date(year, 11, 25);
var sundays = 0;
while (sundays < 4) {
date.setDate(date.getDate() - 1);
if (date.getDay() === 0) {
sundays++;
}
}
return date;
}
DEMO: http://jsfiddle.net/eyUjX/1/
It starts on Christmas day, in the specific year. It goes into the past, day by day, checking for Sunday (where .getDate() returns 0). After 4 of them are encountered, the looping stops and that Date is returned.
So to get 2009's beginning of Advent, use: getAdvent(2009);. It returns a Date object, so you can still work with its methods.
As a reference of its methods: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date
You can get Advent Sunday by adding 3 days to the last Thursday in November, which seems simpler:
function getAdventDay(y){
var advent=new Date();
advent.setHours(0,0,0,0);
//set the year:
if(typeof y!='number')y=advent.getFullYear();
//get the last day of november:
advent.setFullYear(y,10,30);
//back up to the last thursday in November:
while(advent.getDay()!==4)advent.setDate(advent.getDate()-1);
//add 3 days to get Sunday:
advent.setDate(advent.getDate()+3);
return advent;
}
getAdventDay(2013)
/*
Sun Dec 01 2013 00:00:00 GMT-0500 (Eastern Standard Time)
*/
const getFirstAdvent=function(y){
const firstAdvent=new Date(y,11,3);
firstAdvent.setDate(firstAdvent.getDate()-firstAdvent.getDay());
return firstAdvent;
};
alert(getFirstAdvent(2020));
I love these challenges, here's how it can be done with recursion. First I find the fourth Sunday. Then I Just keep minusing 7 days until I have the other 3. The variables firstSunday, secondSunday, thirdSunday and fourthSunday - contains the dates.
EDIT: I believe I misunderstood, but the firstSunday variable Will be the date you are looking for.
Demo
Javascript
var year = 2011;//new Date().getFullYear();
var sevenDays = (24*60*60*1000) * 7;
var foundDate;
var findClosestSunday = function(date){
foundDate = date;
if (foundDate.getDay() != 0)
findClosestSunday(new Date(year,11,date.getDate()-1));
return foundDate;
}
var fourthSunday = findClosestSunday(new Date(year, 11, 23));
var thirdSunday = new Date(fourthSunday.getTime() - sevenDays);
var secondSunday = new Date(fourthSunday.getTime() - sevenDays *2);
var firstSunday = new Date(fourthSunday.getTime() - sevenDays *3);
console.log
(
firstSunday,
secondSunday,
thirdSunday,
fourthSunday
);
Javascript works with time in terms of milliseconds since epoch. There are 1000 * 60 * 60 *24 * 7 = 604800000 milliseconds in a week.
You can create a new date in Javascript that is offset from a know date doing this:
var weekTicks, christmas, week0, week1, week2, week3;
weekTicks = 604800000;
christmas = new Date(2013, 12, 25);
week0 = new Date(christmas - weekTicks);
week1 = new Date(week0 - weekTicks);
week2 = new Date(week1 - weekTicks);
week3 = new Date(week2 - weekTicks);
See how that works for you.
Also, the Date.getDay function will work to help you find which day of the month is the first Sunday.

Categories

Resources