Does anybody know of a simple way of taking a date (e.g. Today) and going back X days, X months and X years?
I have tried that:
var date = new Date();
$("#searchDateFrom").val((date.getMonth() -1 ) + '/' + (date.getDate() - 6) + '/' + (date.getFullYear() - 1));
But I got a negative date, for example today the output was:
3/-3/2015
Any advise?
Thanks.
You are simply reducing the values from a number. So substracting 6 from 3 (date) will return -3 only.
You need to individually add/remove unit of time in date object
var date = new Date();
date.setDate( date.getDate() - 6 );
date.setFullYear( date.getFullYear() - 1 );
$("#searchDateFrom").val((date.getMonth() ) + '/' + (date.getDate()) + '/' + (date.getFullYear()));
As others have said you're subtracting from the numeric values returned from methods like date.getDate(), you need to reset those values on your date variable. I've created a method below that will do this for you. It creates a date using new Date() which will initialize with the current date, then sets the date, month, and year according to the values passed in. For example, if you want to go back 6 days then pass in -6 like so var newdate = createDate(-6,0,0). If you don't want to set a value pass in a zero (or you could set default values). The method will return the new date for you (tested in Chrome and Firefox).
function createDate(days, months, years) {
var date = new Date();
date.setDate(date.getDate() + days);
date.setMonth(date.getMonth() + months);
date.setFullYear(date.getFullYear() + years);
return date;
}
2021 Update:
MomentJS has been replaced/improved with LuxonJS, a much more up-to-date and newer version. You can find it here: https://moment.github.io/luxon/#/
I'll leave the old post for now, since it could sitll help others.
Old post:
I'd recommend using the MomentJS libraries. They make all interactions with Dates a lot simpler.
If you use Moment, your code would be as simple as this:
var today = moment();
var nextMonth = today.add('month', 1);
// note that both variables `today` and `nextMonth` refer to
// the next month at this point, because `add` mutates in-place
You can find MomentJS here: http://momentjs.com/
UPDATE:
In JavaScript, the Date.getDate() function returns the current day of the month from 1-31. You are subtracting 6 from this number, and it is currently the 3rd of the month. This brings the value to -3.
This is a pure-function which takes a passed-in starting date, building on Phil's answer:
function deltaDate(input, days, months, years) {
return new Date(
input.getFullYear() + years,
input.getMonth() + months,
Math.min(
input.getDate() + days,
new Date(input.getFullYear() + years, input.getMonth() + months + 1, 0).getDate()
)
);
}
e.g. writes the date one month ago to the console log:
console.log(deltaDate(new Date(), 0, -1, 0));
e.g. subtracts a month from March 30, 2020:
console.log(deltaDate(new Date(2020, 2, 30), 0, -1, 0)); // Feb 29, 2020
Note that this works even if you go past the end of the month or year.
Update: As the example above shows, this has been updated to handle variances in the number of days in a month.
I implemented a function similar to the momentjs method subtract.
- If you use Javascript
function addDate(dt, amount, dateType) {
switch (dateType) {
case 'days':
return dt.setDate(dt.getDate() + amount) && dt;
case 'weeks':
return dt.setDate(dt.getDate() + (7 * amount)) && dt;
case 'months':
return dt.setMonth(dt.getMonth() + amount) && dt;
case 'years':
return dt.setFullYear( dt.getFullYear() + amount) && dt;
}
}
example:
let dt = new Date();
dt = addDate(dt, -1, 'months');// use -1 to subtract
- If you use Typescript:
export enum dateAmountType {
DAYS,
WEEKS,
MONTHS,
YEARS,
}
export function addDate(dt: Date, amount: number, dateType: dateAmountType): Date {
switch (dateType) {
case dateAmountType.DAYS:
return dt.setDate(dt.getDate() + amount) && dt;
case dateAmountType.WEEKS:
return dt.setDate(dt.getDate() + (7 * amount)) && dt;
case dateAmountType.MONTHS:
return dt.setMonth(dt.getMonth() + amount) && dt;
case dateAmountType.YEARS:
return dt.setFullYear( dt.getFullYear() + amount) && dt;
}
}
example:
let dt = new Date();
dt = addDate(dt, -1, 'months'); // use -1 to subtract
Optional (unit-tests)
I also made some unit-tests for this function using Jasmine:
it('addDate() should works properly', () => {
for (const test of [
{ amount: 1, dateType: dateAmountType.DAYS, expect: '2020-04-13'},
{ amount: -1, dateType: dateAmountType.DAYS, expect: '2020-04-11'},
{ amount: 1, dateType: dateAmountType.WEEKS, expect: '2020-04-19'},
{ amount: -1, dateType: dateAmountType.WEEKS, expect: '2020-04-05'},
{ amount: 1, dateType: dateAmountType.MONTHS, expect: '2020-05-12'},
{ amount: -1, dateType: dateAmountType.MONTHS, expect: '2020-03-12'},
{ amount: 1, dateType: dateAmountType.YEARS, expect: '2021-04-12'},
{ amount: -1, dateType: dateAmountType.YEARS, expect: '2019-04-12'},
]) {
expect(formatDate(addDate(new Date('2020-04-12'), test.amount, test.dateType))).toBe(test.expect);
}
});
To use this test you need this function:
// get format date as 'YYYY-MM-DD'
export function formatDate(date: Date): string {
const d = new Date(date);
let month = '' + (d.getMonth() + 1);
let day = '' + d.getDate();
const year = d.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
return [year, month, day].join('-');
}
Use the moment.js library for time and date management.
import moment = require('moment');
const now = moment();
now.subtract(7, 'seconds'); // 7 seconds ago
now.subtract(7, 'days'); // 7 days and 7 seconds ago
now.subtract(7, 'months'); // 7 months, 7 days and 7 seconds ago
now.subtract(7, 'years'); // 7 years, 7 months, 7 days and 7 seconds ago
// because `now` has been mutated, it no longer represents the current time
The oneliner to get for instance the date of yesterday would be:
const yesterday = ((date) => date.setDate(date.getDate() - 1) && date)(new Date());
It will define an arrow function which receives the new Date() as a parameter (date). The reason to make an arrow function is that the new Date object will be used multiple times. First to retrieve the current days (getDate), then to set the days (setDate) and also to return it as a result. So it will return the mutated date, not the original date.
Now this arrow function is defined and will be called immediately with the new Date() in order to return the date of yesterday.
I have a simpler answer, which works perfectly for days; for months, it's +-2 days:
let today=new Date();
const days_to_subtract=30;
let new_date= new Date(today.valueOf()-(days_to_subtract*24*60*60*1000));
You get the idea - for months, multiply by 30; but that will be +-2 days.
This does not answer the question fully, but for anyone who is able to calculate the number of days by which they would like to offset an initial date then the following method will work:
myDate.setUTCDate(myDate.getUTCDate() + offsetDays);
offsetDays can be positive or negative and the result will be correct for any given initial date with any given offset.
Vanilla JS Date saves the time as milliseconds from Epoch time (1970), so all we need to do is subtract in milliseconds.
if we want to subtract 10 days we would subtract 1000(ms) * 60(s) * 60(m) * 24(h) * 10(d)
A simple Vanilla function to subtract from a date (notice the years exception):
subtractFromDate(new Date(), { hours: 15 }) // now - 15 hours
subtractFromDate(new Date(), { days: 15 }) // now - 15 days
subtractFromDate(new Date(), { years: 15 }) // now - 15 years
const subtractFromDate = (
date,
{ years, days, hours, minutes, seconds, milliseconds } = {}
) => {
const millisecondsOffset = milliseconds ?? 0
const secondsOffset = seconds ? 1000 * seconds : 0
const minutesOffset = minutes ? 1000 * 60 * minutes : 0
const hoursOffset = hours ? 1000 * 60 * 60 * hours : 0
const daysOffset = days ? 1000 * 60 * 60 * 24 * days : 0
const dateOffset =
millisecondsOffset +
secondsOffset +
minutesOffset +
hoursOffset +
daysOffset
let newDate = date
if (years) newDate = date.setFullYear(date.getFullYear() - years)
newDate = new Date(newDate - dateOffset)
return newDate
}
Related
Does anybody know of a simple way of taking a date (e.g. Today) and going back X days, X months and X years?
I have tried that:
var date = new Date();
$("#searchDateFrom").val((date.getMonth() -1 ) + '/' + (date.getDate() - 6) + '/' + (date.getFullYear() - 1));
But I got a negative date, for example today the output was:
3/-3/2015
Any advise?
Thanks.
You are simply reducing the values from a number. So substracting 6 from 3 (date) will return -3 only.
You need to individually add/remove unit of time in date object
var date = new Date();
date.setDate( date.getDate() - 6 );
date.setFullYear( date.getFullYear() - 1 );
$("#searchDateFrom").val((date.getMonth() ) + '/' + (date.getDate()) + '/' + (date.getFullYear()));
As others have said you're subtracting from the numeric values returned from methods like date.getDate(), you need to reset those values on your date variable. I've created a method below that will do this for you. It creates a date using new Date() which will initialize with the current date, then sets the date, month, and year according to the values passed in. For example, if you want to go back 6 days then pass in -6 like so var newdate = createDate(-6,0,0). If you don't want to set a value pass in a zero (or you could set default values). The method will return the new date for you (tested in Chrome and Firefox).
function createDate(days, months, years) {
var date = new Date();
date.setDate(date.getDate() + days);
date.setMonth(date.getMonth() + months);
date.setFullYear(date.getFullYear() + years);
return date;
}
2021 Update:
MomentJS has been replaced/improved with LuxonJS, a much more up-to-date and newer version. You can find it here: https://moment.github.io/luxon/#/
I'll leave the old post for now, since it could sitll help others.
Old post:
I'd recommend using the MomentJS libraries. They make all interactions with Dates a lot simpler.
If you use Moment, your code would be as simple as this:
var today = moment();
var nextMonth = today.add('month', 1);
// note that both variables `today` and `nextMonth` refer to
// the next month at this point, because `add` mutates in-place
You can find MomentJS here: http://momentjs.com/
UPDATE:
In JavaScript, the Date.getDate() function returns the current day of the month from 1-31. You are subtracting 6 from this number, and it is currently the 3rd of the month. This brings the value to -3.
This is a pure-function which takes a passed-in starting date, building on Phil's answer:
function deltaDate(input, days, months, years) {
return new Date(
input.getFullYear() + years,
input.getMonth() + months,
Math.min(
input.getDate() + days,
new Date(input.getFullYear() + years, input.getMonth() + months + 1, 0).getDate()
)
);
}
e.g. writes the date one month ago to the console log:
console.log(deltaDate(new Date(), 0, -1, 0));
e.g. subtracts a month from March 30, 2020:
console.log(deltaDate(new Date(2020, 2, 30), 0, -1, 0)); // Feb 29, 2020
Note that this works even if you go past the end of the month or year.
Update: As the example above shows, this has been updated to handle variances in the number of days in a month.
I implemented a function similar to the momentjs method subtract.
- If you use Javascript
function addDate(dt, amount, dateType) {
switch (dateType) {
case 'days':
return dt.setDate(dt.getDate() + amount) && dt;
case 'weeks':
return dt.setDate(dt.getDate() + (7 * amount)) && dt;
case 'months':
return dt.setMonth(dt.getMonth() + amount) && dt;
case 'years':
return dt.setFullYear( dt.getFullYear() + amount) && dt;
}
}
example:
let dt = new Date();
dt = addDate(dt, -1, 'months');// use -1 to subtract
- If you use Typescript:
export enum dateAmountType {
DAYS,
WEEKS,
MONTHS,
YEARS,
}
export function addDate(dt: Date, amount: number, dateType: dateAmountType): Date {
switch (dateType) {
case dateAmountType.DAYS:
return dt.setDate(dt.getDate() + amount) && dt;
case dateAmountType.WEEKS:
return dt.setDate(dt.getDate() + (7 * amount)) && dt;
case dateAmountType.MONTHS:
return dt.setMonth(dt.getMonth() + amount) && dt;
case dateAmountType.YEARS:
return dt.setFullYear( dt.getFullYear() + amount) && dt;
}
}
example:
let dt = new Date();
dt = addDate(dt, -1, 'months'); // use -1 to subtract
Optional (unit-tests)
I also made some unit-tests for this function using Jasmine:
it('addDate() should works properly', () => {
for (const test of [
{ amount: 1, dateType: dateAmountType.DAYS, expect: '2020-04-13'},
{ amount: -1, dateType: dateAmountType.DAYS, expect: '2020-04-11'},
{ amount: 1, dateType: dateAmountType.WEEKS, expect: '2020-04-19'},
{ amount: -1, dateType: dateAmountType.WEEKS, expect: '2020-04-05'},
{ amount: 1, dateType: dateAmountType.MONTHS, expect: '2020-05-12'},
{ amount: -1, dateType: dateAmountType.MONTHS, expect: '2020-03-12'},
{ amount: 1, dateType: dateAmountType.YEARS, expect: '2021-04-12'},
{ amount: -1, dateType: dateAmountType.YEARS, expect: '2019-04-12'},
]) {
expect(formatDate(addDate(new Date('2020-04-12'), test.amount, test.dateType))).toBe(test.expect);
}
});
To use this test you need this function:
// get format date as 'YYYY-MM-DD'
export function formatDate(date: Date): string {
const d = new Date(date);
let month = '' + (d.getMonth() + 1);
let day = '' + d.getDate();
const year = d.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
return [year, month, day].join('-');
}
Use the moment.js library for time and date management.
import moment = require('moment');
const now = moment();
now.subtract(7, 'seconds'); // 7 seconds ago
now.subtract(7, 'days'); // 7 days and 7 seconds ago
now.subtract(7, 'months'); // 7 months, 7 days and 7 seconds ago
now.subtract(7, 'years'); // 7 years, 7 months, 7 days and 7 seconds ago
// because `now` has been mutated, it no longer represents the current time
The oneliner to get for instance the date of yesterday would be:
const yesterday = ((date) => date.setDate(date.getDate() - 1) && date)(new Date());
It will define an arrow function which receives the new Date() as a parameter (date). The reason to make an arrow function is that the new Date object will be used multiple times. First to retrieve the current days (getDate), then to set the days (setDate) and also to return it as a result. So it will return the mutated date, not the original date.
Now this arrow function is defined and will be called immediately with the new Date() in order to return the date of yesterday.
I have a simpler answer, which works perfectly for days; for months, it's +-2 days:
let today=new Date();
const days_to_subtract=30;
let new_date= new Date(today.valueOf()-(days_to_subtract*24*60*60*1000));
You get the idea - for months, multiply by 30; but that will be +-2 days.
This does not answer the question fully, but for anyone who is able to calculate the number of days by which they would like to offset an initial date then the following method will work:
myDate.setUTCDate(myDate.getUTCDate() + offsetDays);
offsetDays can be positive or negative and the result will be correct for any given initial date with any given offset.
Vanilla JS Date saves the time as milliseconds from Epoch time (1970), so all we need to do is subtract in milliseconds.
if we want to subtract 10 days we would subtract 1000(ms) * 60(s) * 60(m) * 24(h) * 10(d)
A simple Vanilla function to subtract from a date (notice the years exception):
subtractFromDate(new Date(), { hours: 15 }) // now - 15 hours
subtractFromDate(new Date(), { days: 15 }) // now - 15 days
subtractFromDate(new Date(), { years: 15 }) // now - 15 years
const subtractFromDate = (
date,
{ years, days, hours, minutes, seconds, milliseconds } = {}
) => {
const millisecondsOffset = milliseconds ?? 0
const secondsOffset = seconds ? 1000 * seconds : 0
const minutesOffset = minutes ? 1000 * 60 * minutes : 0
const hoursOffset = hours ? 1000 * 60 * 60 * hours : 0
const daysOffset = days ? 1000 * 60 * 60 * 24 * days : 0
const dateOffset =
millisecondsOffset +
secondsOffset +
minutesOffset +
hoursOffset +
daysOffset
let newDate = date
if (years) newDate = date.setFullYear(date.getFullYear() - years)
newDate = new Date(newDate - dateOffset)
return newDate
}
I have some code, that is doing pretty much all i need it to do. Its calculating 3 days in the future, excluding dates, and then displaying my "estimated dispatch date"
The date, however displays in full date and time, instead of just date.
Day Month Date Year 12:02:57 GMT+0100 (British Summer Time)
Can anyone help with the code below, so that it excludes local time and only displays the future date, excluding weekend, DD/MM/YYYY or, in the below format;
Monday 20th June
Thanks in advance!
function addDates(startDate,noOfDaysToAdd){
var count = 0;
while(count < noOfDaysToAdd){
endDate = new Date(startDate.setDate(startDate.getDate() + 1));
if(endDate.getDay() != 0 && endDate.getDay() != 6){
//Date.getDay() gives weekday starting from 0(Sunday) to 6(Saturday)
count++;
}
}
return startDate;
}
var today = new Date();
var daysToAdd = 3;
document.write ('Estimated Dispatch Date: ' + addDates(today,daysToAdd));
You can use the toDateString method to display just the date portion of your Date object, but you will need to use a few other methods for full control over the format of your date string...
You can display just the date, month and year parts of your local date and time with a few extra lines of code using the getDate, getMonth, and getFullYear methods to help with the formatting. You could try passing specific formatting parameters to toLocaleString, but this may display different results in different browsers. For example, the code below outputs a date in the format dd/mm/yyyy in Chrome but that output is not guaranteed across browsers.
new Date().toLocaleString('en-GB', {year: 'numeric', month: 'numeric', day: 'numeric'})
Not sure I am following how you want to handle weekend dates, so the below handles the date formatting that you want in the formatDate function separately from the addDays function where it just handles weekend dates by rolling the date forward to a Monday if the initially calculated date lands on a Saturday or Sunday.
// format input date to dd/mm/yyyy
const formatDate = (date) => {
const d = date.getDate(); // day of the month
const m = date.getMonth(); // month index from 0 (Jan) to 11 (Dec)
const yyyy = date.getFullYear(); // 4 digit year
const dd = (d < 10 ? '0' : '') + d; // format date to 2 digit
const mm = (m + 1 < 10 ? '0' : '') + (m + 1); // convert index to month and format 2 digit
return `${dd}/${mm}/${yyyy}`;
};
// add input days to today and adjust for weekend output
const addDays = (today, days) => {
const now = today.getTime() // now in UTC milliseconds
const ms = 24 * 60 * 60000; // milliseconds in one day
const date = new Date((days * ms) + now); // today plus input days
const day = date.getDay(); // weekday index from 0 (Sun) to 6 (Sat)
// adjust weekend results to next weekday
if (day === 0 || day === 6) {
let adj = day === 0 ? 1 : 2;
return new Date(((days + adj) * ms) + now);
}
return date;
};
document.write('Estimated Dispatch Date: ' + formatDate(addDays(new Date(), 3)));
I really need your help,
Let's say my demarcation start date is: December 19, 2016 as defined by the variable x
How can I write a JavaScript function, such that it will check the present date against x and the present date against what the recurrence date will be (14) days from x as defined by the variable y.
var y = recurrence is every 14 days, thereafter from the date (x) with no end date specified (unlimited)
Ex.
function() {
if (present date == x) { alert(true) }
if (present date == y) { alert(true) }
}
You could get the number of days difference between your start date and the current date then check if that number is a multiple of 14.
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.floor((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}
var demarcationdate = new Date("2016-12-19"),
today = new Date(),
days = daysBetween(demarcationdate,today),
daystill = 14 - days%14,
rec = days%14==0,
d = new Date();
d.setDate(today.getDate() + daystill);
var nextDate = (d.getDate() + "/" + (d.getMonth() + 1) + "/" + d.getFullYear());
console.log("Days diff = "+days+". Recurs today = "+rec+". Next in "+daystill+" days ("+nextDate.toString()+").");
jsFiddle
If Date.now() == 1482181410856, 14 days from now will be 1482181410856 + (14 * 24 * 60 * 60 * 1000) == 1483391010856.
let y = new Date(Date.now() + (14 * 24 * 60 * 60 * 1000));
console.log(y.toUTCString()); // "Mon, 02 Jan 2017 21:03:30 GMT"
Assuming you really want to compare precise dates, i.e. to the milliseconds, then:
var present_date = new Date();
if(present_date.getTime() === x.getTime()) alert("Today is the same date as x");
else {
var y = new Date(x.getTime());
y.setDate(y.getDate() + 14); // add 14 days
if(present_date.getTime() === y.getTime()) alert("Today is the same date as y");
}
But most of the time we want to compare dates as full days, not milliseconds, so you'd have to compare ranges instead (from midnight to 11:59PM)... In that case, I recommend using a library to make your life easier - like moment.js for instance...
Hope this helps!
This is probably a duplicate of Add +1 to current date.
If you have a start date, say 20 December, 2016, you can calculate 14 days after that by simply adding 14 days to the date. You can then check if today's date is either of those dates, e.g.
// Create a Date for 20 December, 2016 with time 00:00:00
var startDate = new Date(2016,11,20);
// Create a Date for the start + 14 days with time 00:00:00
var startPlus14 = new Date(startDate);
startPlus14.setDate(startPlus14.getDate() + 14);
// Get today and set the time to 00:00:00.000
var today = new Date();
today.setHours(0,0,0,0);
if (+today == +startDate) {
console.log('Today is the start date');
} else if (+today == +startPlus14) {
console.log('Today is 14 days after the start date');
} else {
console.log('Today is neither the start nor 14 days after the start');
}
I'm trying to return the number of weeks between two dates using JavaScript.
So I have the following variables:
var date = new Date();
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
if(day < 10) { day= '0' + day; }
if(month < 10) { month = '0' + month; }
var dateToday = day + '/' + month + '/' + year;
var dateEndPlacement = '22/06/2014';
I've also prefixed the days and months with 0 if they are less than 10. Not sure if this is the correct way to do this... so alternative ideas would be welcomed.
And then I pass these two dates to the following function:
function calculateWeeksBetween(date1, date2) {
// The number of milliseconds in one week
var ONE_WEEK = 1000 * 60 * 60 * 24 * 7;
// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();
// Calculate the difference in milliseconds
var difference_ms = Math.abs(date1_ms - date2_ms);
// Convert back to weeks and return hole weeks
return Math.floor(difference_ms / ONE_WEEK);
}
However I get the error:
Uncaught TypeError: Object 04/04/2014 has no method 'getTime'
Any ideas what I am doing wrong?
For those that are asking/gonna ask, I'm calling the function like this:
calculateWeeksBetween(dateToday, dateEndPlacement);
I would recommend using moment.js for this kind of thing.
But if you want to do it in pure javascript here is how I would do it:
function weeksBetween(d1, d2) {
return Math.round((d2 - d1) / (7 * 24 * 60 * 60 * 1000));
}
Then call with
weeksBetween(new Date(), new Date(2014, 6, 22));
You are storing your dates as strings ('22/06/2014'). getTime is a method of Date. You need to create Date objects for the dates, and pass those into the function.
var dateToday = new Date(year, month - 1, day);
var dateEndPlacement = new Date(2014, 5, 22);
calculateWeeksBetween(dateToday, dateEndPlacement);
As #Mosho notes, you can also subtract the dates directly, without using getTime.
If you need actual weeks between to dates, and not the number of seven days between them:
const week = 7 * 24 * 60 * 60 * 1000;
const day = 24 * 60 * 60 * 1000;
function startOfWeek(dt) {
const weekday = dt.getDay();
return new Date(dt.getTime() - Math.abs(0 - weekday) * day);
}
function weeksBetween(d1, d2) {
return Math.ceil((startOfWeek(d2) - startOfWeek(d1)) / week);
}
You can use moment itself have all the functionality I mentioned the below code which could work perfectly
var a = moment(a, 'DD-MM-YYYY');
var b = moment(b, 'DD-MM-YYYY');
days=b.diff(a, 'week');
don't forget to use moment js CDN
subtract dates (which, unformatted, are the number of seconds elapsed since 1 January 1970 00:00:00) , divide by 604,800,000 (milliseconds per week).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
You should convert dateToday and dateEndPlacement to Date type.
Please read Converting string to date in js
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Is there an easy way of taking a olain JavaScript Date (e.g. today) and going back X days?
So, for example, if I want to calculate the date 5 days before today.
Try something like this:
var d = new Date();
d.setDate(d.getDate()-5);
Note that this modifies the date object and returns the time value of the updated date.
var d = new Date();
document.write('Today is: ' + d.toLocaleString());
d.setDate(d.getDate() - 5);
document.write('<br>5 days ago was: ' + d.toLocaleString());
var dateOffset = (24*60*60*1000) * 5; //5 days
var myDate = new Date();
myDate.setTime(myDate.getTime() - dateOffset);
If you're performing lots of headachy date manipulation throughout your web application, DateJS will make your life much easier:
http://simonwillison.net/2007/Dec/3/datejs/
It goes something like this:
var d = new Date(); // today!
var x = 5; // go back 5 days!
d.setDate(d.getDate() - x);
I noticed that the getDays+ X doesn't work over day/month boundaries. Using getTime works as long as your date is not before 1970.
var todayDate = new Date(), weekDate = new Date();
weekDate.setTime(todayDate.getTime()-(7*24*3600000));
If you want it all on one line instead.
5 days from today
//past
var fiveDaysAgo = new Date(new Date().setDate(new Date().getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(new Date().getDate() + 5));
5 days from a specific date
var pastDate = new Date('2019-12-12T00:00:00');
//past
var fiveDaysAgo = new Date(new Date().setDate(pastDate.getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(pastDate.getDate() + 5));
I wrote a function you can use.
function AddOrSubractDays(startingDate, number, add) {
if (add) {
return new Date(new Date().setDate(startingDate.getDate() + number));
} else {
return new Date(new Date().setDate(startingDate.getDate() - number));
}
}
console.log('Today : ' + new Date());
console.log('Future : ' + AddOrSubractDays(new Date(), 5, true));
console.log('Past : ' + AddOrSubractDays(new Date(), 5, false));
I find a problem with the getDate()/setDate() method is that it too easily turns everything into milliseconds, and the syntax is sometimes hard for me to follow.
Instead I like to work off the fact that 1 day = 86,400,000 milliseconds.
So, for your particular question:
today = new Date()
days = 86400000 //number of milliseconds in a day
fiveDaysAgo = new Date(today - (5*days))
Works like a charm.
I use this method all the time for doing rolling 30/60/365 day calculations.
You can easily extrapolate this to create units of time for months, years, etc.
get moment.js. All the cool kids use it. It has more formatting options, etc. Where
var n = 5;
var dateMnsFive = moment(<your date>).subtract(n , 'day');
Optional! Convert to JS Date obj for Angular binding.
var date = new Date(dateMnsFive.toISOString());
Optional! Format
var date = dateMnsFive.format("YYYY-MM-DD");
A few of the existing solutions were close, but not quite exactly what I wanted. This function works with both positive or negative values and handles boundary cases.
function addDays(date, days) {
return new Date(
date.getFullYear(),
date.getMonth(),
date.getDate() + days,
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
);
}
Without using the second variable, you can replace 7 for with your back x days:
let d=new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))
I made this prototype for Date so that I could pass negative values to subtract days and positive values to add days.
if(!Date.prototype.adjustDate){
Date.prototype.adjustDate = function(days){
var date;
days = days || 0;
if(days === 0){
date = new Date( this.getTime() );
} else if(days > 0) {
date = new Date( this.getTime() );
date.setDate(date.getDate() + days);
} else {
date = new Date(
this.getFullYear(),
this.getMonth(),
this.getDate() - Math.abs(days),
this.getHours(),
this.getMinutes(),
this.getSeconds(),
this.getMilliseconds()
);
}
this.setTime(date.getTime());
return this;
};
}
So, to use it i can simply write:
var date_subtract = new Date().adjustDate(-4),
date_add = new Date().adjustDate(4);
I like doing the maths in milliseconds. So use Date.now()
var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds
and if you like it formatted
new Date(newDate).toString(); // or .toUTCString or .toISOString ...
NOTE: Date.now() doesn't work in older browsers (eg IE8 I think). Polyfill here.
UPDATE June 2015
#socketpair pointed out my sloppiness. As s/he says "Some day in year have 23 hours, and some 25 due to timezone rules".
To expand on that, the answer above will have daylightsaving inaccuracies in the case where you want to calculate the LOCAL day 5 days ago in a timezone with daylightsaving changes and you
assume (wrongly) that Date.now() gives you the current LOCAL now time, or
use .toString() which returns the local date and therefore is incompatible with the Date.now() base date in UTC.
However, it works if you're doing your math all in UTC, eg
A. You want the UTC date 5 days ago from NOW (UTC)
var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds UTC
new Date(newDate).toUTCString(); // or .toISOString(), BUT NOT toString
B. You start with a UTC base date other than "now", using Date.UTC()
newDate = new Date(Date.UTC(2015, 3, 1)).getTime() + -5*24*3600000;
new Date(newDate).toUTCString(); // or .toISOString BUT NOT toString
split your date into parts, then return a new Date with the adjusted values
function DateAdd(date, type, amount){
var y = date.getFullYear(),
m = date.getMonth(),
d = date.getDate();
if(type === 'y'){
y += amount;
};
if(type === 'm'){
m += amount;
};
if(type === 'd'){
d += amount;
};
return new Date(y, m, d);
}
Remember that the months are zero based, but the days are not. ie new Date(2009, 1, 1) == 01 February 2009, new Date(2009, 1, 0) == 31 January 2009;
Some people suggested using moment.js to make your life easier when handling dates in js. Time has passed since those answers and it is noteworthy, that the authors of moment.js now discourage its use. Mainly due to its size and lack of tree-shaking-support.
If you want to go the library route, use an alternative like Luxon. It is significantly smaller (because of its clever use of the Intl object and support for tree-shaking) and just as versatile as moment.js.
To go back 5 days from today in Luxon, you would do:
import { DateTime } from 'luxon'
DateTime.now().minus({ days: 5 });
function addDays (date, daysToAdd) {
var _24HoursInMilliseconds = 86400000;
return new Date(date.getTime() + daysToAdd * _24HoursInMilliseconds);
};
var now = new Date();
var yesterday = addDays(now, - 1);
var tomorrow = addDays(now, 1);
See the following code, subtract the days from the current date. Also, set the month according to substracted date.
var today = new Date();
var substract_no_of_days = 25;
today.setTime(today.getTime() - substract_no_of_days* 24 * 60 * 60 * 1000);
var substracted_date = (today.getMonth()+1) + "/" +today.getDate() + "/" + today.getFullYear();
alert(substracted_date);
I have created a function for date manipulation. you can add or subtract any number of days, hours, minutes.
function dateManipulation(date, days, hrs, mins, operator) {
date = new Date(date);
if (operator == "-") {
var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
var newDate = new Date(date.getTime() - durationInMs);
} else {
var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
var newDate = new Date(date.getTime() + durationInMs);
}
return newDate;
}
Now, call this function by passing parameters. For example, here is a function call for getting date before 3 days from today.
var today = new Date();
var newDate = dateManipulation(today, 3, 0, 0, "-");
Use MomentJS.
function getXDaysBeforeDate(referenceDate, x) {
return moment(referenceDate).subtract(x , 'day').format('MMMM Do YYYY, h:mm:ss a');
}
var yourDate = new Date(); // let's say today
var valueOfX = 7; // let's say 7 days before
console.log(getXDaysBeforeDate(yourDate, valueOfX));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
The top answers led to a bug in my code where on the first of the month it would set a future date in the current month. Here is what I did,
curDate = new Date(); // Took current date as an example
prvDate = new Date(0); // Date set to epoch 0
prvDate.setUTCMilliseconds((curDate - (5 * 24 * 60 * 60 * 1000))); //Set epoch time
I like the following because it is one line. Not perfect with DST changes but usually good enough for my needs.
var fiveDaysAgo = new Date(new Date() - (1000*60*60*24*5));
Using Modern JavaScript function syntax
const getDaysPastDate = (daysBefore, date = new Date) => new Date(date - (1000 * 60 * 60 * 24 * daysBefore));
console.log(getDaysPastDate(1)); // yesterday
A easy way to manage dates is use Moment.js
You can use add. Example
var startdate = "20.03.2014";
var new_date = moment(startdate, "DD.MM.YYYY");
new_date.add(5, 'days'); //Add 5 days to start date
alert(new_date);
Docs http://momentjs.com/docs/#/manipulating/add/
for me all the combinations worked fine with below code snipplet ,
the snippet is for Angular-2 implementation ,
if you need to add days , pass positive numberofDays , if you need to substract pass negative numberofDays
function addSubstractDays(date: Date, numberofDays: number): Date {
let d = new Date(date);
return new Date(
d.getFullYear(),
d.getMonth(),
(d.getDate() + numberofDays)
);
}
I get good mileage out of date.js:
http://www.datejs.com/
d = new Date();
d.add(-10).days(); // subtract 10 days
Nice!
Website includes this beauty:
Datejs doesn’t just parse strings, it slices them cleanly in two
If you want to both subtract a number of days and format your date in a human readable format, you should consider creating a custom DateHelper object that looks something like this :
var DateHelper = {
addDays : function(aDate, numberOfDays) {
aDate.setDate(aDate.getDate() + numberOfDays); // Add numberOfDays
return aDate; // Return the date
},
format : function format(date) {
return [
("0" + date.getDate()).slice(-2), // Get day and pad it with zeroes
("0" + (date.getMonth()+1)).slice(-2), // Get month and pad it with zeroes
date.getFullYear() // Get full year
].join('/'); // Glue the pieces together
}
}
// With this helper, you can now just use one line of readable code to :
// ---------------------------------------------------------------------
// 1. Get the current date
// 2. Subtract 5 days
// 3. Format it
// 4. Output it
// ---------------------------------------------------------------------
document.body.innerHTML = DateHelper.format(DateHelper.addDays(new Date(), -5));
(see also this Fiddle)
To calculate relative time stamps with a more precise difference than whole days, you can use Date.getTime() and Date.setTime() to work with integers representing the number of milliseconds since a certain epoch—namely, January 1, 1970. For example, if you want to know when it’s 17 hours after right now:
const msSinceEpoch = (new Date()).getTime();
const fortyEightHoursLater = new Date(msSinceEpoch + 48 * 60 * 60 * 1000).toLocaleString();
const fortyEightHoursEarlier = new Date(msSinceEpoch - 48 * 60 * 60 * 1000).toLocaleString();
const fiveDaysAgo = new Date(msSinceEpoch - 120 * 60 * 60 * 1000).toLocaleString();
console.log({msSinceEpoch, fortyEightHoursLater, fortyEightHoursEarlier, fiveDaysAgo})
reference
function daysSinceGivenDate (date) {
const dateInSeconds = Math.floor((new Date().valueOf() - date.valueOf()) / 1000);
const oneDayInSeconds = 86400;
return Math.floor(dateInSeconds / oneDayInSeconds); // casted to int
};
console.log(daysSinceGivenDate(new Date())); // 0
console.log(daysSinceGivenDate(new Date("January 1, 2022 03:24:00"))); // relative...
First arg is the date to start with and second is how mush day you want to increase or reduce to the date
example (1)- pass -1 to reduce date by one day
example (2)- pass 1 to increase date by one day
const EditDay = (date: Date, num: number): Date => {
return new Date(date.getTime() + num * 24 * 60 * 60 * 1000)
}
When setting the date, the date converts to milliseconds, so you need to convert it back to a date:
This method also take into consideration, new year change etc.
function addDays( date, days ) {
var dateInMs = date.setDate(date.getDate() - days);
return new Date(dateInMs);
}
var date_from = new Date();
var date_to = addDays( new Date(), parseInt(days) );
You can using Javascript.
var CurrDate = new Date(); // Current Date
var numberOfDays = 5;
var days = CurrDate.setDate(CurrDate.getDate() + numberOfDays);
alert(days); // It will print 5 days before today
For PHP,
$date = date('Y-m-d', strtotime("-5 days")); // it shows 5 days before today.
echo $date;
Hope it will help you.
I converted into millisecond and deducted days else month and year won't change and logical
var numberOfDays = 10;//number of days need to deducted or added
var date = "01-01-2018"// date need to change
var dt = new Date(parseInt(date.substring(6), 10), // Year
parseInt(date.substring(3,5), 10) - 1, // Month (0-11)
parseInt(date.substring(0,2), 10));
var new_dt = dt.setMilliseconds(dt.getMilliseconds() - numberOfDays*24*60*60*1000);
new_dt = new Date(new_dt);
var changed_date = new_dt.getDate()+"-"+(new_dt.getMonth()+1)+"-"+new_dt.getFullYear();
Hope helps