I'm have a startDate and a endDate stored in a SQLite database and need to calculate the difference in minutes and seconds between the 2 datetimes using javascript.
For example:
startDate = 2012-10-07 11:01:13
endDate = 2012-10-07 12:42:13
I've had a good read though loads of similar questions on SO but could only find things relating to calculating this as part of a select.
Convert the strings to a JS Date Object, subtract the dates, and use some aritmethic to calculate hours/seconds from the result. Something like:
function convertMS(ms) {
var d, h, m, s, ts, tm, th;
s = ts = Math.floor(ms / 1000);
m = tm = Math.floor(s / 60);
s = s % 60;
h = th = Math.floor(m / 60);
m = m % 60;
d = Math.floor(h / 24);
h = h % 24;
return { d: d, h: h, m: m, s: s, tm: tm, th: th, ts: ts};
};
var start = new Date('2012-10-07 11:01:13'.split('-').join('/'))
,end = new Date('2012-10-07 12:42:13'.split('-').join('/'))
,dif = convertMS(end - start);
console.log(dif.h+':'+dif.m); //=> 1:41
console.log('total minutes dif: '+dif.tm); //=> total minutes dif: 101
console.log('total seconds dif: '+dif.ts); //=> total seconds dif: 6060
[edit based on comment]
'Manual' parsing of a date string in the provided format:
Date.tryParse = function(ds){
var arr = ds.match(/\d+/g)
,err = 'Expected at least yyyy'
,dat = arr.length && String(arr[0]).length === 4
? doParse.apply(null,arr) : err;
return dat;
function doParse(y,m,d,h,mi,s,ms){
var dat = new Date(+y,(+m-1)||0,+d||1,+h||0,+mi||0,+s||0,+ms||0);
return isNaN(dat) ? new Date : dat;
}
}
var start = Date.tryParse('2012-10-07 11:01:13'); //=> Sun Oct 07 2012 11:01:13
var test = Date.tryParse('2009'); //=> Sun Jan 01 2009 00:00:00
All the answers are generally correct with respect to converting the dates to milliseconds in epoch time, subtracting those, and converting the result back from milliseconds into your required units (although the specific implementations offered elsewhere do not currently give you exactly what you asked for -- i.e., just the number of minutes and seconds between your two datetimes).
However, please also note...
new Date('2012-10-07 12:42:13')
... that this is not a reliable way to construct the Date from your SQLite date strings.
When you feed a string into the constructor of a Date object, you are effectively calling Date.parse(). That behaves differently on different browsers.
Check this out:
> new Date('1-1-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('01-01-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('2012-1-1');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Looks pretty good, right? But that's on Chrome.
Now check out what happens in an up-to-date version of Firefox, with the exact same calls:
> new Date('1-1-2012');
Date {Invalid Date}
> new Date('01-01-2012');
Date {Invalid Date}
> new Date('2012-1-1');
Date {Invalid Date}
> new Date('2012-01-01');
Date {Sat Dec 31 2011 16:00:00 GMT-0800 (PST)}
Furthermore, look at this behavior, in both browsers:
> new Date('2012-01-01');
Sat Dec 31 2011 16:00:00 GMT-0800 (PST)
Simply prepending zeroes to the month and date digits causes a time warp! You have to set the time and a timezone (for me, PST) to make that go away:
> new Date('2012-01-01T00:00:00-08:00')
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Basically, dealing with date string parsing is a headache. You don't want to have to digest and account for specs like this, this, and this.
So, here's a better alternative -- pass the parts of your datetime as separate args to the constructor of the Date object. That will reliably create the date for you, so your subsequent comparisons are valid.
new Date(year, month, day [, hour, minute, second, millisecond])
Here's what that initialization could look like for your case:
// Extract month, day, year from SQLite format, 'trimming' whitespace.
var sqlLiteSampleStr = "2012-10-07 11:01:13";
var re = /^\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\s*$/;
var match = re.exec(sqlLiteSampleStr);
if (match) {
var year = parseInt(match[1]);
var month = parseInt(match[2]) - 1; // Zero-indexed months.
var date = parseInt(match[3]);
var hour = parseInt(match[4]);
var minute = parseInt(match[5]);
var second = parseInt(match[6]);
var date = new Date(year, month, date, hour, minute, second);
}
Note: be careful of timezone considerations. You don't seem to have any timezone data in that SQLite format snippet.
Update
#james-j clarified that he's looking for minutes and seconds specifically.
Here's a snippet to extract just minutes and seconds:
var msPerMin = 1000 * 60;
var min = Math.floor(timeInMs / msPerMin);
var timeInMs = timeInMs - (min * msPerMin);
var sec = Math.floor(timeInMs / 1000 );
Other answers are correct, however browsers do not consistently parse date strings (see below) so you should manually parse the strings. The format in the OP is not consistent with the format in ES5 either, and will not be correctly parsed by some browsers. A simple function to convert the OP format to a date that will work in all browsers is:
function stringToDate(s) {
s = s.split(/[-\/\. :]/);
return new Date(s[0], --s[1], s[2], s[3], s[4], s[5], 0)
}
There are some formats that are parsed by all browsers, however they are not standards compliant and if used, are dependent on all implementations continuing to support unspecified formats.
Edit
To tolerate malformed input (extra whitespace, different seperators, extra characters), match can be used instead of split:
function stringToDate(s) {
s = s.match(/\d+/g);
return new Date(s[0], --s[1], s[2], s[3], s[4], s[5], 0)
}
However, since the values are coming from a database and a format has been specified, the date strings should fit the format. Erroneous data should not be stored in the first place.
For completeness, here's a function to do what you want:
/* Return difference between two dates as minutes and seconds mm:ss.
* Input format is yyyy-mm-dd hh:mm:ss
* If strings don't converted to dates (incorrect format or invalid values),
* return undefined.
*/
function diffInMins(s0, s1) {
var diff;
// Convert strings to date ojbects
var d0 = stringToDate(s0);
var d1 = stringToDate(s1);
// Helper function to padd with leading zero
function z(n) {
return (n<10? '0' : '') + n;
}
// Check conversions
if (d0 && d1 && typeof d0 == 'object' && typeof d1 == 'object') {
// Return difference formatted as mm:ss
if (d0 && d1) {
diff = d1 - d0;
return z(diff/60000 | 0) + ':' + z(Math.round(diff%60000/1000));
}
}
}
JavaScript actually makes subtracting dates quite simple. Here's how it works:
// Create Date objects from the strings
startDate = new Date('2012-10-07 11:01:13');
endDate = new Date('2012-10-07 12:42:13');
// Subtract Date objects to return milliseconds between them
millisecondsBetween = (endDate - startDate);
// Convert to whatever you like
alert(millisecondsBetween/1000/60 + ' minutes');
Related
I'm trying to write a script to subtract 5 days from a defined date but seems not working, here's my code:
var End_Day = sheet.getRange(i + 2, 20).getValue();
Logger.log(End_Day);
var End_day_2 = new Date();
End_day_2.setDate(End_Day.getDate()-5);
Logger.log(End_day_2);
and the result is not just - 5 days:
11:18:47 AM Info Sat Jun 04 00:00:00 GMT+08:00 2022
11:18:47 AM Info Fri Apr 29 11:18:47 GMT+08:00 2022
I am quite confused why the date move from Jun to Apr.
Thanks for having a look
Try:
var End_Day = sheet.getRange(i + 2, 20).getValue();
var End_day_2 = new Date(End_Day.getTime() - (5 * (1000 * 60 * 60 * 24)))
Logger.log(End_Day);
Logger.log(End_day_2);
Function:
const endDay = sheet.getRange(i + 2, 20).getValue()
const endDay2 = DateFromDaysAgo(endDay, 5)
...
function DateFromDaysAgo(startDate, number) {
if (typeof startDate === `string`) { startDate = new Date(startDate) }
return new Date(startDate.getTime() - (number * (1000 * 60 * 60 * 24)))
}
You should learn more about Date.prototype.setDate().It only changes the day of the month of a given Date instance.
As the code you posted, the day of the month of End_Day is 4, End_day_2.setDate(4 - 5) equals to End_day_2.setDate(-1) and the month of End_day_2 is April according to the console result, because there're 30 days in April, setDate(-1) means setDate(29), so you got Apr 29 at the end. That's how it goes.
One right way to do is substracting 5 days worth of milliseconds.
function addDays(date, days){
const DAY_IN_MILLISECONDS = 24 * 60 * 60000;
return new Date(date.getTime() + days * DAY_IN_MILLISECONDS);
}
console.log(addDays(new Date(), -5).toString()); // 5 days ago
I am quite confused why the date move from Jun to Apr.
It's because you're setting date on today(End_day_2) and not on your predefined date(End_day).
Change
End_day_2.setDate(End_Day.getDate()-5);
to
End_Day.setDate(End_Day.getDate()-5);
console.info(End_Day);
If what's coming from the sheet is a string, you will have to convert the date string into a date object.
The other thing is you have to work in milliseconds as #vanowm says:
606024*5 = 432000 * 1000 = 432000000
so skipping the sheet entirely:
x = new Date
> Fri May 27 2022 11:24:01 GMT-0400 (Eastern Daylight Time)
y = new Date(x - 432000000)
> Sun May 22 2022 11:24:01 GMT-0400 (Eastern Daylight Time)
This will do the trick. Works with any date and can subtract any number of days
const subtractDays = (fromDate, numDays) => {
if (!(fromDate instanceof Date)) throw 'The first argument must be a date';
return new Date(new Date().setDate(fromDate.getDate() - +numDays));
};
Weekago
function weekago() {
let dt = new Date();
dt.setDate(dt.getDate()-7);
Logger.log(dt);
return dt;
}
Five days ago
function fiveago() {
let dt = new Date();
dt.setDate(dt.getDate()-5)
Logger.log(dt);
return dt;
}
Five days from a date in a spreadsheet cell
function fivefromadateinspreadsheet() {
const v = SpreadsheetApp.getActiveSheet().getRange("A1").getValue();
let dt = new Date(v);
dt.setDate(dt.getDate()-5);//Note that does not return a date it return the numbrer of milliseconds
Logger.log(dt);
return dt;
}
You can subtract 5 days from a defined date in Google App Script by using the Utilities.formatDate() method. Here's an example:
function subtractDays() {
var date = new Date();
var subtractDays = 5;
// Subtract 5 days from the current date
date.setDate(date.getDate() - subtractDays);
// Format the new date
var newDate = Utilities.formatDate(date, "UTC", "yyyy-MM-dd");
Logger.log(newDate);
}
In this example, we first create a Date object to represent the current date. Then, we subtract 5 days from the current date by using the setDate() method. Finally, we format the new date using the Utilities.formatDate() method and log it to the console using the Logger.log() method.
You can modify the subtractDays variable to subtract a different number of days from the date, or you can use a different date object to start with.
I am in GMT +2 timezone and Daylight saving time on.
My requirement is to ask user a date and convert it into UTC without DST consideration.
when I do console.log(new Date()),
it gives me "Wed Oct 26 2016 18:00:00 GMT+0300 (Turkey Daylight Time)"
I want to send server a UTC format date which server is going to save in Database.
var extractTime = new Date(timeof.edtime); //timeof.edtime contains date given by user.
var d = extractTime.getDate();
var m = extractTime.getMonth();
var y = extractTime.getFullYear();
var h = extractTime.getHours();
var mm = extractTime.getMinutes();
timeof.edtime = moment(new Date(y, m, d, h, mm)).utc().format("YYYY-MM-DD HH:mm");
After converting to utc, timeof.edtime is "2016-09-26 15:00" because it subtract 3 hours to go to GMT. (subtracted 2 hours of standard turkish time) (subtracted -1 of DST)
I want to subtract date to UTC by not considering DST and in our case my expectation is to get hour as "16:00" and not "15:00"
How to convert date to UTC without Daylight saving consideration.
any solution using moment js or jquery will be helpful.
I am testing on chrome.
by browsing through few link it says new Date() will give in standard time and doesn't consider DST consideration but this is not I observed and created plunk to reproduce new Date().toUTCString() consider DST as well, how to avoid subtraction of DST?
https://plnkr.co/edit/tjCOoJqXMHGzCD8B5LdL?p=preview
Inspired by this answer, you could make the time correction as follows:
function compensateDST(dt) {
var janOffset = new Date(dt.getFullYear(), 0, 1).getTimezoneOffset();
var julOffset = new Date(dt.getFullYear(), 6, 1).getTimezoneOffset();
var dstMinutes = dt.getTimezoneOffset() - Math.max(janOffset, julOffset);
dt = new Date(dt);
dt.setMinutes(dt.getMinutes() - dstMinutes);
return dt;
}
// Use your date here:
var extractTime = new Date('2016-10-26 18:00');
// Truncate to minute precision:
var extractTime = new Date(extractTime.getTime() - extractTime.getTime() % 60000)
console.log('Local time:', extractTime.toString());
console.log('UTC time before correction:', extractTime.toISOString());
// Compensate for the DST shift:
var extractTime = compensateDST(extractTime);
console.log('UTC time after correction:', extractTime.toISOString());
try this:
+180 is GMT+0300 (Turkey)
var x = new Date();
var newdate = new Date();
if((x.getTimezoneOffset()) != 180){
newdate = new Date(x.getTime() + (60000*(x.getTimezoneOffset()+180)));
}
console.log(newdate);
I tried many times to convert utc datetime to local datetime,and I have failed. My utc datetime format is
Fri Mar 8 23:12:27 UTC+0200 2013
Also my JavaScript code is
var time = Date(param_time);//param_time is /Date(1362866006646)/
And then time is being Sun Mar 10 00:21:54 UTC+0200 2013 I need to datetime as 2008-01-28T20:24:17Z because I will convert local datetime to pretty datetime.
http://ejohn.org/files/pretty.js
How can I do this ? I looked at many questions on stackoverflow but no one does it work. Thank you.
In order to format your Date correctly use toISOString():
var time = param_time.toISOString();
Note that param_time needs to be a valid Date object.
References
MDN: Date (sections: Syntax, Example: ISO 8601 formatted dates)
I rarely use javascript and all this date time conversion are mystery to me as well, javascript is a client side technology and all this "UTC" phrases means nothing (at least to me), as all the kind of getUTC...()/setUTC...() functions works in local time, the same is goes for all Date.to...String() functions, even the new Date() (that due to the docs) s'd be initialized in UTC, also give a local time.
However, if you have a (correct) date in UTC and wish to convert it to current (client side) local time, then you need getTimezoneOffset(), or shortly:
function UTCToLocalTime(d) {
var timeOffset = -((new Date()).getTimezoneOffset()/60);
d.setHours(d.getHours() + timeOffset);
return d;
}
var time = new Date(Date.parse('Fri Mar 8 23:12:27 UTC+0200 2013'));
alert(UTCToLocalTime(time)); // Sat Mar 9 01:12:27 UTC+0200 2013
//p.s. or...
function UTCToLocalTime2(d)
{
return new Date(d.toString().replace(/UTC.*/g,"") + d.getYear());
}
var timezone = "UTC+01:30";
var start = new Date();
if(timezone != "UTC"){
timezone = timezone.replace(/UTC/g,"");
znak = timezone.charAt(0);
timezone = timezone.replace(/[+|-]/g,"");
timezone = timezone.split(":");
//var start = new Date(start.toString() + " " + timezone);e.
//alert(start.toString());
if(znak == "+") start = new Date(start.getTime() + (timezone[0]*60*60000 + timezone[1] * 60000) );
if(znak == "-") start = new Date(start.getTime() - (timezone[0]*60*60000 + timezone[1] * 60000) );
}
var hours = start.getUTCHours();
var minutes = start.getUTCMinutes();
var seconds = start.getUTCSeconds();
var day = 10;
var month = 04;
var year = 2015;
var dateUtc = Date.UTC(year, month - 1, day + 1, 0, 0, 0);
> 1428710400000
var toDate = new Date(dateUtc);
> Fri Apr 10 2015 21:00:00 GMT-0300 (Hora oficial do Brasil)
I want to take a day of the year and convert to an actual date using the Date object. Example: day 257 of 1929, how can I go about doing this?
"I want to take a day of the year and convert to an actual date using the Date object."
After re-reading your question, it sounds like you have a year number, and an arbitrary day number (e.g. a number within 0..365 (or 366 for a leap year)), and you want to get a date from that.
For example:
dateFromDay(2010, 301); // "Thu Oct 28 2010", today ;)
dateFromDay(2010, 365); // "Fri Dec 31 2010"
If it's that, can be done easily:
function dateFromDay(year, day){
var date = new Date(year, 0); // initialize a date in `year-01-01`
return new Date(date.setDate(day)); // add the number of days
}
You could add also some validation, to ensure that the day number is withing the range of days in the year supplied.
The shortest possible way is to create a new date object with the given year, January as month and your day of the year as date:
const date = new Date(2017, 0, 365);
console.log(date.toLocaleDateString());
As for setDate the correct month gets calculated if the given date is larger than the month's length.
// You might need both parts of it-
Date.fromDayofYear= function(n, y){
if(!y) y= new Date().getFullYear();
var d= new Date(y, 0, 1);
return new Date(d.setMonth(0, n));
}
Date.prototype.dayofYear= function(){
var d= new Date(this.getFullYear(), 0, 0);
return Math.floor((this-d)/8.64e+7);
}
var d=new Date().dayofYear();
//
alert('day#'+d+' is '+Date.fromDayofYear(d).toLocaleDateString())
/* returned value: (String)
day#301 is Thursday, October 28, 2010
*/
Here is a function that takes a day number, and returns the date object
optionally, it takes a year in YYYY format for parameter 2. If you leave it off, it will default to current year.
var getDateFromDayNum = function(dayNum, year){
var date = new Date();
if(year){
date.setFullYear(year);
}
date.setMonth(0);
date.setDate(0);
var timeOfFirst = date.getTime(); // this is the time in milliseconds of 1/1/YYYY
var dayMilli = 1000 * 60 * 60 * 24;
var dayNumMilli = dayNum * dayMilli;
date.setTime(timeOfFirst + dayNumMilli);
return date;
}
OUTPUT
// OUTPUT OF DAY 232 of year 1995
var pastDate = getDateFromDayNum(232,1995)
console.log("PAST DATE: " , pastDate);
PAST DATE: Sun Aug 20 1995 09:47:18 GMT-0400 (EDT)
Here's my implementation, which supports fractional days. The concept is simple: get the unix timestamp of midnight on the first day of the year, then multiply the desired day by the number of milliseconds in a day.
/**
* Converts day of the year to a unix timestamp
* #param {Number} dayOfYear 1-365, with support for floats
* #param {Number} year (optional) 2 or 4 digit year representation. Defaults to
* current year.
* #return {Number} Unix timestamp (ms precision)
*/
function dayOfYearToTimestamp(dayOfYear, year) {
year = year || (new Date()).getFullYear();
var dayMS = 1000 * 60 * 60 * 24;
// Note the Z, forcing this to UTC time. Without this it would be a local time, which would have to be further adjusted to account for timezone.
var yearStart = new Date('1/1/' + year + ' 0:0:0 Z');
return yearStart + ((dayOfYear - 1) * dayMS);
}
// usage
// 2015-01-01T00:00:00.000Z
console.log(new Date(dayOfYearToTimestamp(1, 2015)));
// support for fractional day (for satellite TLE propagation, etc)
// 2015-06-29T12:19:03.437Z
console.log(new Date(dayOfYearToTimestamp(180.51323423, 2015)).toISOString);
If I understand your question correctly, you can do that from the Date constructor like this
new Date(year, month, day, hours, minutes, seconds, milliseconds)
All arguments as integers
You have a few options;
If you're using a standard format, you can do something like:
new Date(dateStr);
If you'd rather be safe about it, you could do:
var date, timestamp;
try {
timestamp = Date.parse(dateStr);
} catch(e) {}
if(timestamp)
date = new Date(timestamp);
or simply,
new Date(Date.parse(dateStr));
Or, if you have an arbitrary format, split the string/parse it into units, and do:
new Date(year, month - 1, day)
Example of the last:
var dateStr = '28/10/2010'; // uncommon US short date
var dateArr = dateStr.split('/');
var dateObj = new Date(dateArr[2], parseInt(dateArr[1]) - 1, dateArr[0]);
this also works ..
function to2(x) { return ("0"+x).slice(-2); }
function formatDate(d){
return d.getFullYear()+"-"+to2(d.getMonth()+1)+"-"+to2(d.getDate());
}
document.write(formatDate(new Date(2016,0,257)));
prints "2016-09-13"
which is correct as 2016 is a leaap year. (see calendars here: http://disc.sci.gsfc.nasa.gov/julian_calendar.html )
If you always want a UTC date:
function getDateFromDayOfYear (year, day) {
return new Date(Date.UTC(year, 0, day))
}
console.log(getDateFromDayOfYear(2020, 1)) // 2020-01-01T00:00:00.000Z
console.log(getDateFromDayOfYear(2020, 305)) // 2020-10-31T00:00:00.000Z
console.log(getDateFromDayOfYear(2020, 366)) // 2020-12-31T00:00:00.000Z
I have a 2 different date formats. 1) dd/mm/yyyy 2) dd-mm-yyyy
I want to compare these 2 date formats in Javascript or Actionscript.
Is it possible?
In Javascript:
x = new Date("12/12/1999")
Sun Dec 12 1999 00:00:00 GMT-0500 (Eastern Standard Time)
y = new Date("12-13-1999")
Mon Dec 13 1999 00:00:00 GMT-0500 (Eastern Standard Time)
x == y
false
x < y
true
Hope this helps!
The easy way in AS3 with your date in String format and if you are not interesting in the Date object itself :
var date1Str:String="10/01/2010";
var date2Str:String="10-01-2010";
var equal:Boolean=date2Str.split("-").join("/")==date1Str;
trace(equal);
If you are interesting into the date object so in AS3:
var date1Str:String = "10/01/2010";
var date2Str:String = "10-01-2010";
var date1Arr:Array = date1Str.split("/");
var date2Arr:Array = date2Str.split("-");
var date1:Date = new Date(date1Arr[2], date1Arr[1] - 1, date1Arr[0]);
var date2:Date = new Date(date2Arr[2], date2Arr[1] - 1, date2Arr[0]);
var equal:Boolean = date1.getTime() == date2.getTime();
trace(equal);
You could convert the date strings to Date instances and compare them, I guess.
function parseDate(ds) {
var rv = null;
ds.replace(/(\d\d?)[-/](\d\d?)[-/](\d\d\d\d)/, function(_, dd, mm, yyyy) {
rv = new Date(parseInt(yyyy, 10), parseInt(mm, 10) - 1, parseInt(dd, 10));
});
return rv;
}
// ...
if (parseDate(d1).getTime() === parseDate(d2).getTime()) {
// ...
}
If you wanted to get fancy you could add code to cope with 2-digit years.
[edit] wow #Pete here I am a grown man and somehow I managed to avoidletting the native Date object parse date strings for me all this time :-)