I've searched for a while and couldn't find anyone even touching on this subject.
I have a price of $900 slowly approach $1500 between the dates of April 1st and August 1st. That's about $5 per day, and the formula would be:
ROUND(1500 - (600 * ((DEADLINE - TODAY) / (DEADLINE - START)))
But how do I express that in terms of javascript and HTML so that I can write it out in a sentence like "Today you'll have to pay $920."
This is where I'm at so far, but I can't figure out how to zero today's date to achieve the correct calculation:
<div id="foo"></div>
<script type="text/javascript">
function getDayDiff(a, b) {
return (a - b) / 8.64e7;
}
function getPayAmount(DEADLINE, TODAY, START) {
return Math.round(1500 - (600 * getDayDiff(DEADLINE, TODAY) / getDayDiff(DEADLINE, START)));
}
document.getElementById("foo").innerHTML = "Today you'll have to pay $" + getPayAmount(new Date(2021, 08, 1), new Date(), new Date(2021, 4, 1));
</script>
First calculate days (since unix time), using getTime() (which will give milliseconds) and use the same formula.
const days = (date) => Math.ceil(date.getTime() / (24 * 60 * 60 * 1000));
const DEADLINE = days(new Date("2021-08-01"));
const START = days(new Date("2021-04-01"));
const TODAY = days(new Date());
const res = Math.round(1500 - 600 * ((DEADLINE - TODAY) / (DEADLINE - START)));
console.log(res);
document.querySelector('.adbox.adred').append(`Today's Rate ${res}`)
This is how you can do it in Javascript:
function getDayDiff(a, b) {
return (a - b) / 8.64e7;
}
function getPayAmount(DEADLINE, TODAY, START) {
return Math.round(1500 - (600 * getDayDiff(DEADLINE, TODAY) / getDayDiff(DEADLINE, START)));
}
document.getElementById("foo").innerHTML = "Today you'll have to pay $" + getPayAmount(new Date(2021, 12, 31), new Date(2021, 4, 3), new Date(2021, 1, 1));
<div id="foo"></div>
Explanation:
8.64e7 is the number of milliseconds in a day
date differences are computed in milliseconds
ROUND is Math.round
EDIT
I have seen this try in the edited question:
<div id="foo"></div>
<script type="text/javascript">
function getDayDiff(a, b) {
return (a - b) / 8.64e7;
}
function getPayAmount(DEADLINE, TODAY, START) {
return Math.round(1500 - (600 * getDayDiff(DEADLINE, TODAY) / getDayDiff(DEADLINE, START)));
}
document.getElementById("foo").innerHTML = "Today you'll have to pay $" + getPayAmount(new Date(2021, 08, 1), new Date(2021, 4, 6), new Date(2021, 4, 1));
</script>
One can create an object and zero the hours, like this:
var today = new Date();
today.setHours(0, 0, 0);
document.getElementById("foo").innerHTML = "Today you'll have to pay $" + getPayAmount(new Date(2021, 08, 1, 0, 0, 0), today, new Date(2021, 4, 1, 0, 0, 0));
This could certainly be cleaned up for efficiency, but I wanted to show you how it could work using each of the variables.
// To set two dates to two variables
let date1 = new Date("04/01/2020");
let date2 = new Date("08/01/2020");
// To calculate the time difference of two dates
let Difference_In_Time = date2.getTime() - date1.getTime();
// To calculate the no. of days between two dates
let Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24);
//Set your two price points
let price1 = 900;
let price2 = 1500;
//Calculate price delta
let Difference_In_Price = price2 - price1;
//Divide the price delta and the days delta. Setting the value to a two decimal place fixed value.
let Price_Over_Period = (Difference_In_Price / Difference_In_Days).toFixed(2);
document.write(Price_Over_Period);
You can see the code in action here: https://jsfiddle.net/ugzn2y7s/
I used the starting, end and today's dates to find the rate of the pay,
Then I added the rate to the starting amount to find how much should have been paid today
const today = new Date();
const startDate = new Date('April 1, 2021');
const endDate = new Date('August 1, 2021');
const deadline = (endDate - startDate) / (1000 * 60 * 60 * 24);
const daysDiff = (today - startDate) / (1000 * 60 * 60 * 24);
const rate = Math.round((1500 - 900) / deadline);
document.body.innerText = `You should have paid $${Math.round((daysDiff * rate) + 900)} by today`;
This question already has answers here:
Difference between dates in JavaScript
(8 answers)
How can I add 1 day to current date?
(10 answers)
Closed 5 years ago.
I'd like to count from a date to another one using a while loop and count the day + 1 till it comes to the final date.
So as example:
var start = new Date(2011, 08, 15);
var end = new Date(2017, 09, 28);
var expired = false;
while (!expired) {
// very first iteration would count day + 1 so it will be 2011-08-16
// and so on till 2017-09-28
// check if end date and set expired to true, finished while loop
}
alert("Finished!");
I don't know how to do this (other anwers didn't help). Any ideas?
You can use .getDate() and .setDate() methods, in start.setDate(start.getDate() + 1) to increment the date by one day, this is how should be your code:
while (!expired) {
start.setDate(start.getDate() + 1);
// and so on till 2017-09-28
if(dateDiffInDays(start, end) == 0) {
expired = true;
}
count++;
}
console.log(count);
alert("Finished!");
Demo:
// A useful function to get dates diff in days gotten from: https://stackoverflow.com/a/15289883/3669624
function dateDiffInDays(a, b) {
var _MS_PER_DAY = 1000 * 60 * 60 * 24;
var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}
var start = new Date(2011, 08, 15);
var end = new Date(2017, 09, 28);
var expired = false;
var count =0;
while (!expired) {
start.setDate(start.getDate() + 1);
// and so on till 2017-09-28
if(dateDiffInDays(start, end) == 0) {
expired = true;
}
count++;
}
console.log(count);
alert("Finished!");
The start date will be increased by one day in each iteration until it reachs the same day as the end date, and finally in the end count variable will hold the days between these two days.
You can use getTime() method.
Convert dates into milliseconds using getTime().
Add 86400 seconds (total seconds per day) to start per loop iteration.
Wait until alert (loop is done).
NOTE
new Date(2011, 08, 15) is 15 September 2011, instead of August.
new Date(2017, 09, 28) is 28 October 2017, instead of September.
See this as reference or checkout the code snippet below.
var start = new Date(2011, 08, 15).getTime(); // convert time into milliseconds
var end = new Date(2017, 09, 28).getTime(); // convert time into milliseconds
var expired = false;
var count = 0;
/* NOT 15 AUGUST 2011 */
console.log(new Date(2011, 08, 15).toString());
console.log(new Date(2017, 09, 28).toString());
/* NOT 28 SEPTEMBER 2017 */
while (!expired) {
start += 24*60*60; // One day has 24 hours * 60 minutes * 60 seconds = 86400 seconds
count++;
if (start >= end) expired = true;
}
alert(`Days In Between: ${count} days`);
Use getDate method
var start = new Date(2011, 08, 15);
var end = new Date(2017, 09, 28);
var expired = false;
var count = 0;
while (!expired) {
count++;
if(start.getYear() == end.getYear() && start.getMonth() == end.getMonth() && start.getDate() == end.getDate()){
expired = true;
}
start.setDate(start.getDate()+1);
}
console.log(count);
alert("Finished!");
How do I get the current weeknumber of the year, like PHP's date('W')?
It should be the ISO-8601 week number of year, weeks starting on Monday.
You should be able to get what you want here: http://www.merlyn.demon.co.uk/js-date6.htm#YWD.
A better link on the same site is: Working with weeks.
Edit
Here is some code based on the links provided and that posted eariler by Dommer. It has been lightly tested against results at http://www.merlyn.demon.co.uk/js-date6.htm#YWD. Please test thoroughly, no guarantee provided.
Edit 2017
There was an issue with dates during the period that daylight saving was observed and years where 1 Jan was Friday. Fixed by using all UTC methods. The following returns identical results to Moment.js.
/* For a given date, get the ISO week number
*
* Based on information at:
*
* THIS PAGE (DOMAIN EVEN) DOESN'T EXIST ANYMORE UNFORTUNATELY
* http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
*
* Algorithm is to find nearest thursday, it's year
* is the year of the week number. Then get weeks
* between that date and the first day of that year.
*
* Note that dates in one year can be weeks of previous
* or next year, overlap is up to 3 days.
*
* e.g. 2014/12/29 is Monday in week 1 of 2015
* 2012/1/1 is Sunday in week 52 of 2011
*/
function getWeekNumber(d) {
// Copy date so don't modify original
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
// Get first day of year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
// Calculate full weeks to nearest Thursday
var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
// Return array of year and week number
return [d.getUTCFullYear(), weekNo];
}
var result = getWeekNumber(new Date());
document.write('It\'s currently week ' + result[1] + ' of ' + result[0]);
Hours are zeroed when creating the "UTC" date.
Minimized, prototype version (returns only week-number):
Date.prototype.getWeekNumber = function(){
var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};
document.write('The current ISO week number is ' + new Date().getWeekNumber());
Test section
In this section, you can enter any date in YYYY-MM-DD format and check that this code gives the same week number as Moment.js ISO week number (tested over 50 years from 2000 to 2050).
Date.prototype.getWeekNumber = function(){
var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};
function checkWeek() {
var s = document.getElementById('dString').value;
var m = moment(s, 'YYYY-MM-DD');
document.getElementById('momentWeek').value = m.format('W');
document.getElementById('answerWeek').value = m.toDate().getWeekNumber();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Enter date YYYY-MM-DD: <input id="dString" value="2021-02-22">
<button onclick="checkWeek(this)">Check week number</button><br>
Moment: <input id="momentWeek" readonly><br>
Answer: <input id="answerWeek" readonly>
You can use momentjs library also:
moment().format('W')
Not ISO-8601 week number but if the search engine pointed you here anyway.
As said above but without a class:
let now = new Date();
let onejan = new Date(now.getFullYear(), 0, 1);
let week = Math.ceil((((now.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7);
console.log(week);
Accordily http://javascript.about.com/library/blweekyear.htm
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(), 0, 1);
var millisecsInDay = 86400000;
return Math.ceil((((this - onejan) / millisecsInDay) + onejan.getDay() + 1) / 7);
};
let d = new Date(2020,11,30);
for (let i=0; i<14; i++) {
console.log(`${d.toDateString()} is week ${d.getWeek()}`);
d.setDate(d.getDate() + 1);
}
Jacob Wright's Date.format() library implements date formatting in the style of PHP's date() function and supports the ISO-8601 week number:
new Date().format('W');
It may be a bit overkill for just a week number, but it does support PHP style formatting and is quite handy if you'll be doing a lot of this.
The code below calculates the correct ISO 8601 week number. It matches PHP's date("W") for every week between 1/1/1970 and 1/1/2100.
/**
* Get the ISO week date week number
*/
Date.prototype.getWeek = function () {
// Create a copy of this date object
var target = new Date(this.valueOf());
// ISO week date weeks start on Monday, so correct the day number
var dayNr = (this.getDay() + 6) % 7;
// ISO 8601 states that week 1 is the week with the first Thursday of that year
// Set the target date to the Thursday in the target week
target.setDate(target.getDate() - dayNr + 3);
// Store the millisecond value of the target date
var firstThursday = target.valueOf();
// Set the target to the first Thursday of the year
// First, set the target to January 1st
target.setMonth(0, 1);
// Not a Thursday? Correct the date to the next Thursday
if (target.getDay() !== 4) {
target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
}
// The week number is the number of weeks between the first Thursday of the year
// and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
return 1 + Math.ceil((firstThursday - target) / 604800000);
}
Source: Taco van den Broek
If you're not into extending prototypes, then here's a function:
function getWeek(date) {
if (!(date instanceof Date)) date = new Date();
// ISO week date weeks start on Monday, so correct the day number
var nDay = (date.getDay() + 6) % 7;
// ISO 8601 states that week 1 is the week with the first Thursday of that year
// Set the target date to the Thursday in the target week
date.setDate(date.getDate() - nDay + 3);
// Store the millisecond value of the target date
var n1stThursday = date.valueOf();
// Set the target to the first Thursday of the year
// First, set the target to January 1st
date.setMonth(0, 1);
// Not a Thursday? Correct the date to the next Thursday
if (date.getDay() !== 4) {
date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7);
}
// The week number is the number of weeks between the first Thursday of the year
// and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
return 1 + Math.ceil((n1stThursday - date) / 604800000);
}
Sample usage:
getWeek(); // Returns 37 (or whatever the current week is)
getWeek(new Date('Jan 2, 2011')); // Returns 52
getWeek(new Date('Jan 1, 2016')); // Returns 53
getWeek(new Date('Jan 4, 2016')); // Returns 1
getWeekOfYear: function(date) {
var target = new Date(date.valueOf()),
dayNumber = (date.getUTCDay() + 6) % 7,
firstThursday;
target.setUTCDate(target.getUTCDate() - dayNumber + 3);
firstThursday = target.valueOf();
target.setUTCMonth(0, 1);
if (target.getUTCDay() !== 4) {
target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7);
}
return Math.ceil((firstThursday - target) / (7 * 24 * 3600 * 1000)) + 1;
}
Following code is timezone-independent (UTC dates used) and works according to the https://en.wikipedia.org/wiki/ISO_8601
Get the weeknumber of any given Date
function week(year,month,day) {
function serial(days) { return 86400000*days; }
function dateserial(year,month,day) { return (new Date(year,month-1,day).valueOf()); }
function weekday(date) { return (new Date(date)).getDay()+1; }
function yearserial(date) { return (new Date(date)).getFullYear(); }
var date = year instanceof Date ? year.valueOf() : typeof year === "string" ? new Date(year).valueOf() : dateserial(year,month,day),
date2 = dateserial(yearserial(date - serial(weekday(date-serial(1))) + serial(4)),1,3);
return ~~((date - date2 + serial(weekday(date2) + 5))/ serial(7));
}
Example
console.log(
week(2016, 06, 11),//23
week(2015, 9, 26),//39
week(2016, 1, 1),//53
week(2016, 1, 4),//1
week(new Date(2016, 0, 4)),//1
week("11 january 2016")//2
);
I found useful the Java SE's SimpleDateFormat class described on Oracle's specification:
http://goo.gl/7MbCh5. In my case in Google Apps Script it worked like this:
function getWeekNumber() {
var weekNum = parseInt(Utilities.formatDate(new Date(), "GMT", "w"));
Logger.log(weekNum);
}
For example in a spreadsheet macro you can retrieve the actual timezone of the file:
function getWeekNumber() {
var weekNum = parseInt(Utilities.formatDate(new Date(), SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone(), "w"));
Logger.log(weekNum);
}
This adds "getWeek" method to Date.prototype which returns number of week from the beginning of the year. The argument defines which day of the week to consider the first. If no argument passed, first day is assumed Sunday.
/**
* Get week number in the year.
* #param {Integer} [weekStart=0] First day of the week. 0-based. 0 for Sunday, 6 for Saturday.
* #return {Integer} 0-based number of week.
*/
Date.prototype.getWeek = function(weekStart) {
var januaryFirst = new Date(this.getFullYear(), 0, 1);
if(weekStart !== undefined && (typeof weekStart !== 'number' || weekStart % 1 !== 0 || weekStart < 0 || weekStart > 6)) {
throw new Error('Wrong argument. Must be an integer between 0 and 6.');
}
weekStart = weekStart || 0;
return Math.floor((((this - januaryFirst) / 86400000) + januaryFirst.getDay() - weekStart) / 7);
};
If you are already in an Angular project you could use $filter('date').
For example:
var myDate = new Date();
var myWeek = $filter('date')(myDate, 'ww');
The code snippet which works pretty well for me is this one:
var yearStart = +new Date(d.getFullYear(), 0, 1);
var today = +new Date(d.getFullYear(),d.getMonth(),d.getDate());
var dayOfYear = ((today - yearStart + 1) / 86400000);
return Math.ceil(dayOfYear / 7).toString();
Note:
d is my Date for which I want the current week number.
The + converts the Dates into numbers (working with TypeScript).
With Luxon (https://github.com/moment/luxon) :
import { DateTime } from 'luxon';
const week: number = DateTime.fromJSDate(new Date()).weekNumber;
This week number thing has been a real pain in the a**. Most trivial solutions around the web didn't really work for me as they worked most of the time but all of them broke at some point, especially when year changed and last week of the year was suddenly next year's first week etc. Even Angular's date filter showed incorrect data (it was the 1st week of next year, Angular gave week 53).
Note: The examples are designed to work with European weeks (Mon first)!
getWeek()
Date.prototype.getWeek = function(){
// current week's Thursday
var curWeek = new Date(this.getTime());
curWeek.setDay(4);
// current year's first week's Thursday
var firstWeek = new Date(curWeek.getFullYear(), 0, 4);
firstWeek.setDay(4);
return (curWeek.getDayIndex() - firstWeek.getDayIndex()) / 7 + 1;
};
setDay()
/**
* Make a setDay() prototype for Date
* Sets week day for the date
*/
Date.prototype.setDay = function(day){
// Get day and make Sunday to 7
var weekDay = this.getDay() || 7;
var distance = day - weekDay;
this.setDate(this.getDate() + distance);
return this;
}
getDayIndex()
/*
* Returns index of given date (from Jan 1st)
*/
Date.prototype.getDayIndex = function(){
var start = new Date(this.getFullYear(), 0, 0);
var diff = this - start;
var oneDay = 86400000;
return Math.floor(diff / oneDay);
};
I have tested this and it seems to be working very well but if you notice a flaw in it, please let me know.
Here is my implementation for calculating the week number in JavaScript. corrected for summer and winter time offsets as well.
I used the definition of the week from this article: ISO 8601
Weeks are from mondays to sunday, and january 4th is always in the first week of the year.
// add get week prototype functions
// weeks always start from monday to sunday
// january 4th is always in the first week of the year
Date.prototype.getWeek = function () {
year = this.getFullYear();
var currentDotw = this.getWeekDay();
if (this.getMonth() == 11 && this.getDate() - currentDotw > 28) {
// if true, the week is part of next year
return this.getWeekForYear(year + 1);
}
if (this.getMonth() == 0 && this.getDate() + 6 - currentDotw < 4) {
// if true, the week is part of previous year
return this.getWeekForYear(year - 1);
}
return this.getWeekForYear(year);
}
// returns a zero based day, where monday = 0
// all weeks start with monday
Date.prototype.getWeekDay = function () {
return (this.getDay() + 6) % 7;
}
// corrected for summer/winter time
Date.prototype.getWeekForYear = function (year) {
var currentDotw = this.getWeekDay();
var fourjan = new Date(year, 0, 4);
var firstDotw = fourjan.getWeekDay();
var dayTotal = this.getDaysDifferenceCorrected(fourjan) // the difference in days between the two dates.
// correct for the days of the week
dayTotal += firstDotw; // the difference between the current date and the first monday of the first week,
dayTotal -= currentDotw; // the difference between the first monday and the current week's monday
// day total should be a multiple of 7 now
var weeknumber = dayTotal / 7 + 1; // add one since it gives a zero based week number.
return weeknumber;
}
// corrected for timezones and offset
Date.prototype.getDaysDifferenceCorrected = function (other) {
var millisecondsDifference = (this - other);
// correct for offset difference. offsets are in minutes, the difference is in milliseconds
millisecondsDifference += (other.getTimezoneOffset()- this.getTimezoneOffset()) * 60000;
// return day total. 1 day is 86400000 milliseconds, floor the value to return only full days
return Math.floor(millisecondsDifference / 86400000);
}
for testing i used the following JavaScript tests in Qunit
var runweekcompare = function(result, expected) {
equal(result, expected,'Week nr expected value: ' + expected + ' Actual value: ' + result);
}
test('first week number test', function () {
expect(5);
var temp = new Date(2016, 0, 4); // is the monday of the first week of the year
runweekcompare(temp.getWeek(), 1);
var temp = new Date(2016, 0, 4, 23, 50); // is the monday of the first week of the year
runweekcompare(temp.getWeek(), 1);
var temp = new Date(2016, 0, 10, 23, 50); // is the sunday of the first week of the year
runweekcompare(temp.getWeek(), 1);
var temp = new Date(2016, 0, 11, 23, 50); // is the second week of the year
runweekcompare(temp.getWeek(), 2);
var temp = new Date(2016, 1, 29, 23, 50); // is the 9th week of the year
runweekcompare(temp.getWeek(), 9);
});
test('first day is part of last years last week', function () {
expect(2);
var temp = new Date(2016, 0, 1, 23, 50); // is the first last week of the previous year
runweekcompare(temp.getWeek(), 53);
var temp = new Date(2011, 0, 2, 23, 50); // is the first last week of the previous year
runweekcompare(temp.getWeek(), 52);
});
test('last day is part of next years first week', function () {
var temp = new Date(2013, 11, 30); // is part of the first week of 2014
runweekcompare(temp.getWeek(), 1);
});
test('summer winter time change', function () {
expect(2);
var temp = new Date(2000, 2, 26);
runweekcompare(temp.getWeek(), 12);
var temp = new Date(2000, 2, 27);
runweekcompare(temp.getWeek(), 13);
});
test('full 20 year test', function () {
//expect(20 * 12 * 28 * 2);
for (i = 2000; i < 2020; i++) {
for (month = 0; month < 12; month++) {
for (day = 1; day < 29 ; day++) {
var temp = new Date(i, month, day);
var expectedweek = temp.getWeek();
var temp2 = new Date(i, month, day, 23, 50);
var resultweek = temp.getWeek();
equal(expectedweek, Math.round(expectedweek), 'week number whole number expected ' + Math.round(expectedweek) + ' resulted week nr ' + expectedweek);
equal(resultweek, expectedweek, 'Week nr expected value: ' + expectedweek + ' Actual value: ' + resultweek + ' for year ' + i + ' month ' + month + ' day ' + day);
}
}
}
});
Here is a slight adaptation for Typescript that will also return the dates for the week start and week end. I think it's common to have to display those in a user interface, since people don't usually remember week numbers.
function getWeekNumber(d: Date) {
// Copy date so don't modify original
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Set to nearest Thursday: current date + 4 - current day number Make
// Sunday's day number 7
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
// Get first day of year
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
// Calculate full weeks to nearest Thursday
const weekNo = Math.ceil(
((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7
);
const weekStartDate = new Date(d.getTime());
weekStartDate.setUTCDate(weekStartDate.getUTCDate() - 3);
const weekEndDate = new Date(d.getTime());
weekEndDate.setUTCDate(weekEndDate.getUTCDate() + 3);
return [d.getUTCFullYear(), weekNo, weekStartDate, weekEndDate] as const;
}
This is my typescript implementation which I tested against some dates. This implementation allows you to set the first day of the week to any day.
//sunday = 0, monday = 1, ...
static getWeekNumber(date: Date, firstDay = 1): number {
const d = new Date(date.getTime());
d.setHours(0, 0, 0, 0);
//Set to first day of the week since it is the same weeknumber
while(d.getDay() != firstDay){
d.setDate(d.getDate() - 1);
}
const dayOfYear = this.getDayOfYear(d);
let weken = Math.floor(dayOfYear/7);
// add an extra week if 4 or more days are in this year.
const daysBefore = ((dayOfYear % 7) - 1);
if(daysBefore >= 4){
weken += 1;
}
//if the last 3 days onf the year,it is the first week
const t = new Date(d.getTime());
t.setDate(t.getDate() + 3);
if(t.getFullYear() > d.getFullYear()){
return 1;
}
weken += 1;
return weken;
}
private static getDayOfYear(date: Date){
const start = new Date(date.getFullYear(), 0, 0);
const diff = (date.getTime() - start.getTime()) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000);
const oneDay = 1000 * 60 * 60 * 24;
const day = Math.floor(diff / oneDay);
return day;
}
Tests:
describe('getWeeknumber', () => {
it('should be ok for 0 sunday', () => {
expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 0)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 0)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 0)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 0)).toBe(2);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 0)).toBe(2);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 0)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 0)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 0)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 0)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 0)).toBe(1);
});
it('should be ok for monday 1 default', () => {
expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 1)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 1)).toBe(52);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 1)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 1)).toBe(1);
expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 1)).toBe(2);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 1)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 1)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 1)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 1)).toBe(53);
expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 1)).toBe(1);
});
});
I tried a lot to get the shortest code to get the weeknumber ISO-conform.
Date.prototype.getWeek=function(){
var date=new Date(this);
date.setHours(0,0,0,0);
return Math.round(((date.setDate(this.getDate()+2-(this.getDay()||7))-date.setMonth(0,4))/8.64e7+3+(date.getDay()||7))/7)+"/"+date.getFullYear();}
The variable date is necessary to avoid to alter the original this. I used the return values of setDate() and setMonth() to dispense with getTime() to save code length and I used an expontial number for milliseconds of a day instead of a multiplication of single elements or a number with five zeros. this is Date or Number of milliseconds, return value is String e.g. "49/2017".
Another library-based option: use d3-time-format:
const formatter = d3.timeFormat('%U');
const weekNum = formatter(new Date());
Shortest workaround for Angular2+ DatePipe, adjusted for ISO-8601:
import {DatePipe} from "#angular/common";
public rightWeekNum: number = 0;
constructor(private datePipe: DatePipe) { }
calcWeekOfTheYear(dateInput: Date) {
let falseWeekNum = parseInt(this.datePipe.transform(dateInput, 'ww'));
this.rightWeekNum = (dateInput.getDay() == 0) ? falseWeekNumber-1 : falseWeekNumber;
}
Inspired from RobG's answer.
What I wanted is the day of the week of a given date. So my answer is simply based on the day of the week Sunday. But you can choose the other day (i.e. Monday, Tuesday...);
First I find the Sunday in a given date and then calculate the week.
function getStartWeekDate(d = null) {
const now = d || new Date();
now.setHours(0, 0, 0, 0);
const sunday = new Date(now);
sunday.setDate(sunday.getDate() - sunday.getDay());
return sunday;
}
function getWeek(date) {
const sunday = getStartWeekDate(date);
const yearStart = new Date(Date.UTC(2021, 0, 1));
const weekNo = Math.ceil((((sunday - yearStart) / 86400000) + 1) / 7);
return weekNo;
}
// tests
for (let i = 0; i < 7; i++) {
let m = 14 + i;
let x = getWeek(new Date(2021, 2, m));
console.log('week num: ' + x, x + ' == ' + 11, x == 11, m);
}
for (let i = 0; i < 7; i++) {
let m = 21 + i;
let x = getWeek(new Date(2021, 2, m));
console.log('week num: ' + x, x + ' == ' + 12, x == 12, 'date day: ' + m);
}
for (let i = 0; i < 4; i++) {
let m = 28 + i;
let x = getWeek(new Date(2021, 2, m));
console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m);
}
for (let i = 0; i < 3; i++) {
let m = 1 + i;
let x = getWeek(new Date(2021, 3, m));
console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m);
}
for (let i = 0; i < 7; i++) {
let m = 4 + i;
let x = getWeek(new Date(2021, 3, m));
console.log('week num: ' + x, x + ' == ' + 14, x == 14, 'date day: ' + m);
}
now = new Date();
today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
firstOfYear = new Date(now.getFullYear(), 0, 1);
numOfWeek = Math.ceil((((today - firstOfYear) / 86400000)-1)/7);
function getWeek(param) {
let onejan = new Date(param.getFullYear(), 0, 1);
return Math.ceil((((param.getTime() - onejan.getTime()) / 86400000) + onejan.getDay()) / 7);
}