How to find the difference between two dates?
By using the Date object and its milliseconds value, differences can be calculated:
var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var d = (b-a); // Difference in milliseconds.
You can get the number of seconds (as a integer/whole number) by dividing the milliseconds by 1000 to convert it to seconds then converting the result to an integer (this removes the fractional part representing the milliseconds):
var seconds = parseInt((b-a)/1000);
You could then get whole minutes by dividing seconds by 60 and converting it to an integer, then hours by dividing minutes by 60 and converting it to an integer, then longer time units in the same way. From this, a function to get the maximum whole amount of a time unit in the value of a lower unit and the remainder lower unit can be created:
function get_whole_values(base_value, time_fractions) {
time_data = [base_value];
for (i = 0; i < time_fractions.length; i++) {
time_data.push(parseInt(time_data[i]/time_fractions[i]));
time_data[i] = time_data[i] % time_fractions[i];
}; return time_data;
};
// Input parameters below: base value of 72000 milliseconds, time fractions are
// 1000 (amount of milliseconds in a second) and 60 (amount of seconds in a minute).
console.log(get_whole_values(72000, [1000, 60]));
// -> [0,12,1] # 0 whole milliseconds, 12 whole seconds, 1 whole minute.
If you're wondering what the input parameters provided above for the second Date object are, see their names below:
new Date(<year>, <month>, <day>, <hours>, <minutes>, <seconds>, <milliseconds>);
As noted in the comments of this solution, you don't necessarily need to provide all these values unless they're necessary for the date you wish to represent.
I have found this and it works fine for me:
Calculating the Difference between Two Known Dates
Unfortunately, calculating a date interval such as days, weeks, or months between two known dates is not as easy because you can't just add Date objects together. In order to use a Date object in any sort of calculation, we must first retrieve the Date's internal millisecond value, which is stored as a large integer. The function to do that is Date.getTime(). Once both Dates have been converted, subtracting the later one from the earlier one returns the difference in milliseconds. The desired interval can then be determined by dividing that number by the corresponding number of milliseconds. For instance, to obtain the number of days for a given number of milliseconds, we would divide by 86,400,000, the number of milliseconds in a day (1000 x 60 seconds x 60 minutes x 24 hours):
Date.daysBetween = function( date1, date2 ) {
//Get 1 day in milliseconds
var one_day=1000*60*60*24;
// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();
// Calculate the difference in milliseconds
var difference_ms = date2_ms - date1_ms;
// Convert back to days and return
return Math.round(difference_ms/one_day);
}
//Set the two dates
var y2k = new Date(2000, 0, 1);
var Jan1st2010 = new Date(y2k.getFullYear() + 10, y2k.getMonth(), y2k.getDate());
var today= new Date();
//displays 726
console.log( 'Days since '
+ Jan1st2010.toLocaleDateString() + ': '
+ Date.daysBetween(Jan1st2010, today));
The rounding is optional, depending on whether you want partial days or not.
Reference
If you are looking for a difference expressed as a combination of years, months, and days, I would suggest this function:
function interval(date1, date2) {
if (date1 > date2) { // swap
var result = interval(date2, date1);
result.years = -result.years;
result.months = -result.months;
result.days = -result.days;
result.hours = -result.hours;
return result;
}
result = {
years: date2.getYear() - date1.getYear(),
months: date2.getMonth() - date1.getMonth(),
days: date2.getDate() - date1.getDate(),
hours: date2.getHours() - date1.getHours()
};
if (result.hours < 0) {
result.days--;
result.hours += 24;
}
if (result.days < 0) {
result.months--;
// days = days left in date1's month,
// plus days that have passed in date2's month
var copy1 = new Date(date1.getTime());
copy1.setDate(32);
result.days = 32-date1.getDate()-copy1.getDate()+date2.getDate();
}
if (result.months < 0) {
result.years--;
result.months+=12;
}
return result;
}
// Be aware that the month argument is zero-based (January = 0)
var date1 = new Date(2015, 4-1, 6);
var date2 = new Date(2015, 5-1, 9);
document.write(JSON.stringify(interval(date1, date2)));
This solution will treat leap years (29 February) and month length differences in a way we would naturally do (I think).
So for example, the interval between 28 February 2015 and 28 March 2015 will be considered exactly one month, not 28 days. If both those days are in 2016, the difference will still be exactly one month, not 29 days.
Dates with exactly the same month and day, but different year, will always have a difference of an exact number of years. So the difference between 2015-03-01 and 2016-03-01 will be exactly 1 year, not 1 year and 1 day (because of counting 365 days as 1 year).
// This is for first date
first = new Date(2010, 03, 08, 15, 30, 10); // Get the first date epoch object
document.write((first.getTime())/1000); // get the actual epoch values
second = new Date(2012, 03, 08, 15, 30, 10); // Get the second date epoch object
document.write((second.getTime())/1000); // get the actual epoch values
diff= second - first ;
one_day_epoch = 24*60*60 ; // calculating one epoch
if ( diff/ one_day_epoch > 365 ) // check if it is exceeding regular calendar year
{
alert( 'date is exceeding one year');
}
This answer, based on another one (link at end), is about the difference between two dates.
You can see how it works because it's simple, also it includes splitting the difference into
units of time (a function that I made) and converting to UTC to stop time zone problems.
function date_units_diff(a, b, unit_amounts) {
var split_to_whole_units = function (milliseconds, unit_amounts) {
// unit_amounts = list/array of amounts of milliseconds in a
// second, seconds in a minute, etc., for example "[1000, 60]".
time_data = [milliseconds];
for (i = 0; i < unit_amounts.length; i++) {
time_data.push(parseInt(time_data[i] / unit_amounts[i]));
time_data[i] = time_data[i] % unit_amounts[i];
}; return time_data.reverse();
}; if (unit_amounts == undefined) {
unit_amounts = [1000, 60, 60, 24];
};
var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a);
return split_to_whole_units(diff, unit_amounts);
}
// Example of use:
var d = date_units_diff(new Date(2010, 0, 1, 0, 0, 0, 0), new Date()).slice(0,-2);
document.write("In difference: 0 days, 1 hours, 2 minutes.".replace(
/0|1|2/g, function (x) {return String( d[Number(x)] );} ));
How my code above works
A date/time difference, as milliseconds, can be calculated using the Date object:
var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a); // The difference as milliseconds.
Then to work out the number of seconds in that difference, divide it by 1000 to convert
milliseconds to seconds, then change the result to an integer (whole number) to remove
the milliseconds (fraction part of that decimal): var seconds = parseInt(diff/1000).
Also, I could get longer units of time using the same process, for example:
- (whole) minutes, dividing seconds by 60 and changing the result to an integer,
- hours, dividing minutes by 60 and changing the result to an integer.
I created a function for doing that process of splitting the difference into
whole units of time, named split_to_whole_units, with this demo:
console.log(split_to_whole_units(72000, [1000, 60]));
// -> [1,12,0] # 1 (whole) minute, 12 seconds, 0 milliseconds.
This answer is based on this other one.
You can also use it
export function diffDateAndToString(small: Date, big: Date) {
// To calculate the time difference of two dates
const Difference_In_Time = big.getTime() - small.getTime()
// To calculate the no. of days between two dates
const Days = Difference_In_Time / (1000 * 3600 * 24)
const Mins = Difference_In_Time / (60 * 1000)
const Hours = Mins / 60
const diffDate = new Date(Difference_In_Time)
console.log({ date: small, now: big, diffDate, Difference_In_Days: Days, Difference_In_Mins: Mins, Difference_In_Hours: Hours })
var result = ''
if (Mins < 60) {
result = Mins + 'm'
} else if (Hours < 24) result = diffDate.getMinutes() + 'h'
else result = Days + 'd'
return { result, Days, Mins, Hours }
}
results in { result: '30d', Days: 30, Mins: 43200, Hours: 720 }
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf())
dat.setDate(dat.getDate() + days);
return dat;
}
function getDates(startDate, stopDate) {
var dateArray = new Array();
var currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(currentDate);
currentDate = currentDate.addDays(1);
}
return dateArray;
}
var dateArray = getDates(new Date(), (new Date().addDays(7)));
for (i = 0; i < dateArray.length; i ++ ) {
// alert (dateArray[i]);
date=('0'+dateArray[i].getDate()).slice(-2);
month=('0' +(dateArray[i].getMonth()+1)).slice(-2);
year=dateArray[i].getFullYear();
alert(date+"-"+month+"-"+year );
}
var DateDiff = function(type, start, end) {
let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;
var returns = -1;
switch(type){
case 'm': case 'mm': case 'month': case 'months':
returns = ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
break;
case 'y': case 'yy': case 'year': case 'years':
returns = years;
break;
case 'd': case 'dd': case 'day': case 'days':
returns = ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
break;
}
return returns;
}
Usage
var qtMonths = DateDiff('mm', new Date('2015-05-05'), new Date());
var qtYears = DateDiff('yy', new Date('2015-05-05'), new Date());
var qtDays = DateDiff('dd', new Date('2015-05-05'), new Date());
OR
var qtMonths = DateDiff('m', new Date('2015-05-05'), new Date()); // m || y || d
var qtMonths = DateDiff('month', new Date('2015-05-05'), new Date()); // month || year || day
var qtMonths = DateDiff('months', new Date('2015-05-05'), new Date()); // months || years || days
...
var DateDiff = function (type, start, end) {
let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;
if(['m', 'mm', 'month', 'months'].includes(type)/*ES6*/)
return ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
else if(['y', 'yy', 'year', 'years'].includes(type))
return years;
else if (['d', 'dd', 'day', 'days'].indexOf(type) !== -1/*EARLIER JAVASCRIPT VERSIONS*/)
return ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
else
return -1;
}
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
}
Background
I want to create a new date/time system based on an old French version with some modifications.
This involves converting UTC date/times to new quantities:
12 months => 10 months
52 weeks => 36.5 weeks
28/31 days per month => 36/37 days per month
24 hours => 20 hours
60 minutes => 100 minutes
60 seconds => 100 seconds
I've coded a clock in JavaScript as proof of concept, but unsure as to whether I have correctly calculated everything, additionally whether it's the best approach:
Code
1) getDecimalDate() calculates the day of the year, then works out which month it exists within a new calendar of 36 or 37 days per month. Then calculates the new date of the month.
function getDecimalDate(date) {
var oldDay = 1000 * 60 * 60 * 24,
startYear = new Date(Date.UTC(date.getUTCFullYear(), 0, 0)),
day = Math.floor((date - startYear) / oldDay),
num = 0,
month = 1;
if (day > 36) { num += 36; month = 2; }
if (day > 73) { num += 37; month = 3; }
if (day > 109) { num += 36; month = 4; }
if (day > 146) { num += 37; month = 5; }
if (day > 182) { num += 36; month = 6; }
if (day > 219) { num += 37; month = 7; }
if (day > 255) { num += 36; month = 8; }
if (day > 292) { num += 37; month = 9; }
if (day > 328) { num += 36; month = 10; }
return { day: day - num, month: month, year: date.getUTCFullYear(), num: num };
}
2) getDecimalTime() calculates the number of milliseconds since midnight, then changes it from old milliseconds per day to new totals, then calculates hours, mins etc
function getDecimalTime(date) {
var oldDay = 1000 * 60 * 60 * 24,
newDay = 1000 * 100 * 100 * 20,
startDay = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())),
delta = ((date - startDay) / oldDay) * newDay;
var hours = Math.floor(delta / 10000000) % 20;
delta -= hours * 10000000;
var minutes = Math.floor(delta / 100000) % 100;
delta -= minutes * 100000;
var seconds = Math.floor(delta / 1000) % 100;
delta -= seconds * 1000;
var milliseconds = Math.floor(delta) % 1000;
return { milliseconds: milliseconds, seconds: seconds, minutes: minutes, hours: hours };
}
You can see a working version here:
https://jsfiddle.net/kmturley/7mrwc3x3/9/
Results
Bear in mind i've made up day/month names using Latin (Nov = 9, die = day, dec = 10, mense = month)
String - Saturday December 3 => Novdie Decmense 10
Date - 03-12-2016 => 10-10-2016
Time - 22:47:52 => 18:98:43
Questions
Is the math correct?
Are there any issues with timezones? i've
tried converting all Date objects to UTC but JavaScript can be
tricky
Can I improve the code? the month selection seems like it
could be improved but I couldn't figure out a better way to count 36
and 37 day months. if (num % 36.5 === 1) wouldn't work?
Thanks!
Update - 7th December 2016 - new versions based on solution:
https://jsfiddle.net/kmturley/7mrwc3x3/10/
https://github.com/kmturley/decimal-time
Is the math correct?
You didn't say which months have 35 days and which have 36 so we have to accept that the if statements are correct. You don't show how date is created so it may or may not be OK. And you don't say what happens for leap years, this system seems to only have 365 days per year.
The following:
24 hours => 20 hours
60 minutes => 100 minutes
60 seconds => 100 seconds
doesn't seem correct. Do you actually mean:
1 day = 20 decimal hours
1 decimal hour = 100 decimal minutes
1 decimal minute = 100 decimal seconds
1 decimal second = 1000 decimal milliseconds
Your strategy of getting the time in ms and scaling to decimal ms seems fine, I'll just make the following comments.
In getDecimalTime it is simpler to calculate startDay by first copying date then setting its UTC hours to zero:
startDay = new Date(+date);
startDate.setUTCHours(0,0,0,0);
Then scale:
var diffMilliseconds = date - startDate;
var decimalMilliseconds = diffMilliseconds / 8.64e7 * 2.0e8;
so 1 standard millisecond = 2.314814814814815 decimal milliseconds
In the date function, the expression:
new Date(date.getUTCFullYear(), 0, 0)
will create a date for 31 December the previous year (i.e. date of 0), if you're after 1 January then it should be:
new Date(date.getUTCFullYear(), 0, 1);
So likely you're one day out. Otherwise, the code seems to be correct. For me, the get decimal time function would be simpler as:
function getDecimalTime(date) {
// Pad numbers < 10
function z(n){return (n<10?'0':'')+n;}
// Copy date so don't modify original
var dayStart = new Date(+date);
var diffMs = date - dayStart.setUTCHours(0,0,0,0);
// Scale to decimal milliseconds
var decMs = Math.round(diffMs / 8.64e7 * 2.0e8);
// Get decimal hours, etc.
var decHr = decMs / 1.0e7 | 0;
var decMin = decMs % 1.0e7 / 1.0e5 | 0;
var decSec = decMs % 1.0e5 / 1.0e3 | 0;
decMs = decMs % 1.0e3;
return z(decHr) + ':' + z(decMin) + ':' + z(decSec) + '.' + ('0' + z(decMs)).slice(-3);
}
// Helper to format the time part of date
// as UTC hh:mm:ss.sss
function formatUTCTime(date) {
function z(n){return (n<10?'0':'')+n;}
return z(date.getUTCHours()) + ':' +
z(date.getUTCMinutes()) + ':' +
z(date.getUTCSeconds()) + '.' +
('00' + date.getUTCMilliseconds()).slice(-3);
}
// Test 00:00:00.003 => 00:00:00.007
// i.e. 3ms * 2.31decms => 6.93decms
var d = new Date(Date.UTC(2016,0,1,0,0,0,3));
console.log(getDecimalTime(d));
// Test 12:00:00.000 => 10:00:00.000
// i.e. noon to decimal noon
var d = new Date(Date.UTC(2016,0,1,12,0,0,0));
console.log(getDecimalTime(d));
// Test current time
d = new Date();
console.log(formatUTCTime(d));
console.log(getDecimalTime(d));
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
}
Is there a way to check if a date is less than 1 hour ago like this?
// old date
var olddate = new Date("February 9, 2012, 12:15");
// current date
var currentdate = new Date();
if (olddate >= currentdate - 1 hour) {
alert("newer than 1 hour");
else {
alert("older than 1 hour");
}
Also, different question - is there a way to add hours to a date like this?
var olddate = new Date("February 9, 2012, 12:15") + 15 HOURS; // output: February 10, 2012, 3:15
Define
var ONE_HOUR = 60 * 60 * 1000; /* ms */
then you can do
((new Date) - myDate) < ONE_HOUR
To get one hour from a date, try
new Date(myDate.getTime() + ONE_HOUR)
Using some ES6 syntax:
const lessThanOneHourAgo = (date) => {
const HOUR = 1000 * 60 * 60;
const anHourAgo = Date.now() - HOUR;
return date > anHourAgo;
}
Using the Moment library:
const lessThanOneHourAgo = (date) => {
return moment(date).isAfter(moment().subtract(1, 'hours'));
}
Shorthand syntax with Moment:
const lessThanOneHourAgo = (date) => moment(date).isAfter(moment().subtract(1, 'hours'));
the moment library can really help express this. The trick is to take the date, add time, and see if it's before or after now:
lastSeenAgoLabel: function() {
var d = this.lastLogin();
if (! moment(d).isValid()) return 'danger'; // danger if not a date.
if (moment(d).add(10, 'minutes').isBefore(/*now*/)) return 'danger'; // danger if older than 10 mins
if (moment(d).add(5, 'minutes').isBefore(/*now*/)) return 'warning'; // warning if older than 5mins
return 'success'; // Looks good!
},
Using moment will be much easier in this case, You could try this:
let hours = moment().diff(moment(yourDateString), 'hours');
It will give you integer value like 1,2,5,0etc so you can easily use condition check like:
if(hours < 1) {
Also, one more thing is you can get more accurate result of the time difference (in decimals like 1.2,1.5,0.7etc) to get this kind of result use this syntax:
let hours = moment().diff(moment(yourDateString), 'hours', true);
Let me know if you have any further query
//for adding hours to a date
Date.prototype.addHours= function(hrs){
this.setHours(this.getHours()+hrs);
return this;
}
Call function like this:
//test alert(new Date().addHours(4));
You can do it as follows:
First find difference of two dates i-e in milliseconds
Convert milliseconds into minutes
If minutes are less than 60, then it means date is within hour else not within hour.
var date = new Date("2020-07-12 11:30:10");
var now = new Date();
var diffInMS = now - date;
var msInHour = Math.floor(diffInMS/1000/60);
if (msInHour < 60) {
console.log('Within hour');
} else {
console.log('Not within the hour');
}
Plain JavaScript solution with in 12 days and 12 days ago option
const timeAgo = ( inputDate ) => {
const date = ( inputDate instanceof Date) ? inputDate : new Date(inputDate);
const FORMATTER = new Intl.RelativeTimeFormat('en');
const RANGES = {
years : 3600 * 24 * 365,
months : 3600 * 24 * 30,
weeks : 3600 * 24 * 7,
days : 3600 * 24,
hours : 3600,
minutes : 60,
seconds : 1
};
const secondsElapsed = (date.getTime() - Date.now()) / 1000;
for (let key in RANGES) {
if ( RANGES[key] < Math.abs(secondsElapsed) ) {
const delta = secondsElapsed / RANGES[key];
return FORMATTER.format(Math.round(delta), key);
}
}
}
// OUTPUTS
console.log( timeAgo('2040-12-24') )
console.log( timeAgo('6 Sept, 2012') );
console.log( timeAgo('2022-05-27T17:45:01+0000') );
let d = new Date()
console.log( "Date will change: ", timeAgo( d.setHours(24,0,0,0) ) );
// d.setDate( d.getDate() - 0 );
d.setHours(-24,0,0,0); // (H,M,S,MS) | 24 hours format
console.log("Day started: " , timeAgo( d ) );
//try this:
// to compare two date's:
<Script Language=Javascript>
function CompareDates()
{
var str1 = document.getElementById("Fromdate").value;
var str2 = document.getElementById("Todate").value;
var dt1 = parseInt(str1.substring(0,2),10);
var mon1 = parseInt(str1.substring(3,5),10);
var yr1 = parseInt(str1.substring(6,10),10);
var dt2 = parseInt(str2.substring(0,2),10);
var mon2 = parseInt(str2.substring(3,5),10);
var yr2 = parseInt(str2.substring(6,10),10);
var date1 = new Date(yr1, mon1, dt1);
var date2 = new Date(yr2, mon2, dt2);
if(date2 < date1)
{
alert("To date cannot be greater than from date");
return false;
}
else
{
alert("Submitting ...");
}
}
</Script>
Hope it will work 4 u...
I am working on a project that requires a time in the future to be set using the Date object.
For example:
futureTime = new Date();
futureTime.setHours(futureTime.getHours()+2);
My questions is; once the future date is set, how can I round to the closest full hour and then set the futureTime var with it?
For example:
Given 8:55 => var futureTime = 9:00
Given 16:23 => var futureTime = 16:00
Any help would be appreciated!
Round the minutes and then clear the minutes:
var date = new Date(2011,1,1,4,55); // 4:55
roundMinutes(date); // 5:00
function roundMinutes(date) {
date.setHours(date.getHours() + Math.round(date.getMinutes()/60));
date.setMinutes(0, 0, 0); // Resets also seconds and milliseconds
return date;
}
The other answers ignore seconds and milliseconds components of the date.
The accepted answer has been updated to handle milliseconds, but it still does not handle daylight savings time properly.
I would do something like this:
function roundToHour(date) {
p = 60 * 60 * 1000; // milliseconds in an hour
return new Date(Math.round(date.getTime() / p ) * p);
}
var date = new Date(2011,1,1,4,55); // 4:55
roundToHour(date); // 5:00
date = new Date(2011,1,1,4,25); // 4:25
roundToHour(date); // 4:00
A slightly simpler way :
var d = new Date();
d.setMinutes (d.getMinutes() + 30);
d.setMinutes (0);
Another solution, which is no where near as graceful as IAbstractDownvoteFactory's
var d = new Date();
if(d.getMinutes() >= 30) {
d.setHours(d.getHours() + 1);
}
d.setMinutes(0);
Or you could mix the two for optimal size.
http://jsfiddle.net/HkEZ7/
function roundMinutes(date) {
return date.getMinutes() >= 30 ? date.getHours() + 1 : date.getHours();
}
As a matter of fact Javascript does this default which gives wrong time.
let dateutc="2022-02-17T07:20:00.000Z";
let bd = new Date(dateutc);
console.log(bd.getHours()); // gives me 8!!!!!
it is even wrong for my local time because I am GMT+2 so it should say 9.
moment.js also does it wrong so you need to be VERY carefull
Pass any cycle you want in milliseconds to get next cycle example 1 hours
function calculateNextCycle(interval) {
const timeStampCurrentOrOldDate = Date.now();
const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
const mod = Math.ceil(timeDiff / interval);
return new Date(timeStampStartOfDay + (mod * interval));
}
console.log(calculateNextCycle(1 * 60 * 60 * 1000)); // 1 hours in milliseconds