Can not compare two ISO format dates using Javascript - javascript

I am comparing two dates using javascript but always its returning the wrong result. I am explaining my code below.
dateLessThan(from: string, to: string) {
console.log(from,to);
var d1 = new Date(from);
var d2 = new Date(to);
console.log('converted time',d1,d2);
if (from > to) {
return false;
} else {
return true;
}
}
here in my second console message I am getting converted time Fri Jan 24 2020 00:00:00 GMT+0530 (India Standard Time) Wed Jan 01 2020 00:00:00 GMT+0530 (India Standard Time) but its always returns true. Here I need to compare both dates.

Here is a quick-and-dirty solution. Please note that this will not work if you attempt to compare two dates in two different timezones. It assumes that each date is in the same timezone.
function dateLessThan(from, to) {
//console.log(from,to);
var d1 = new Date(from);
var d2 = new Date(to);
//console.log('converted time',d1,d2);
/* This is your code.
if (from > to) {
return false;
} else {
return true;
}
*/
// Here is the easy way to do it with the strings.
return d1.toISOString() < d2.toISOString();
}
console.log('Should be true: ' + dateLessThan('2011-01-01', '2013-01-01'));
console.log('Should be false: ' + dateLessThan('2014-01-01', '2013-01-01'));

Related

How to compare timeStamp whe i can't seem to bring them to a common format using GAS?

So, on form submit, I got a timestamp, which looks like this:
"values":["2/18/2022 14:11:25"]
I then need to compare it with the one on the spreadsheet, so that I can set a number to an adjacent column.
Then, I'm using the code below, but I'm facing an error on ```Utilities.formatDate()````
The code:
function onSubmit(e) {
Logger.log("%s", JSON.stringify(e));
const timeStamp = e.values[0]
const formRespSheet = e.source.getSheetByName('Form Responses 1')
var maxNumber = Math.max.apply(null, formRespSheet.getRange(2, 14, formRespSheet.getLastRow(), 1).getValues());
maxNumber = maxNumber + 1
Utilities.sleep(1000);//Tried it
const allTimeStamps = formRespSheet.getRange(2, 1, formRespSheet.getLastRow(), 1).getValues();
for (let a = 0; a < allTimeStamps.length; a++) {
let sheetTimeStamp = allTimeStamps[a]
sheetTimeStamp = Utilities.formatDate(sheetTimeStamp, Session.getTimeZone(), "MM/dd/yyyy HH:mm:ss")
if (sheetTimeStamp.valueOf() == timeStamp.valueOf()) {
const row = a + 1
formRespSheet.getRange(row, 14).setValue(maxNumber)
}
}
}
The error says:
The parameters (number[],String,String) don't match the method signature for Utilities.formatDate.
Thanks for your help.
Google Spreadsheet has a Date object that works very well for comparion. I always, and don't understand why everyone doesn't, set the number format of a cell or cells to Date. That way I can compare dates, subtract dates, etc. etc. Now, I know the time interers but a simple function can alleviate that problem, I have a spreadsheet that has two Dates that have the same date but they have different times. So I can compare if they are the same day.
function test() {
try {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var range = sheet.getRange("B1:B2");
var values = range.getValues();
function removeTime( value ) {
var temp = value[0];
value[0] = new Date(temp.getFullYear(),temp.getMonth(),temp.getDate());
};
console.log( new Date(values[0][0]) );
console.log( new Date(values[1][0]) );
console.log(values[0][0].valueOf() === values[1][0].valueOf());
values.forEach( removeTime );
console.log( new Date(values[0][0]) );
console.log( new Date(values[1][0]) );
console.log(values[0][0].valueOf() === values[1][0].valueOf());
}
catch(err) {
console.log(err);
}
}
9:15:47 AM Notice Execution started
9:15:47 AM Info Fri Feb 18 2022 11:53:45 GMT-0500 (Eastern Standard Time)
9:15:47 AM Info Fri Feb 18 2022 11:54:16 GMT-0500 (Eastern Standard Time)
9:15:47 AM Info false
9:15:47 AM Info Fri Feb 18 2022 00:00:00 GMT-0500 (Eastern Standard Time)
9:15:47 AM Info Fri Feb 18 2022 00:00:00 GMT-0500 (Eastern Standard Time)
9:15:47 AM Info true
9:15:48 AM Notice Execution completed
sheetTimeStamp = Utilities.formatDate(sheetTimeStamp, Session.getTimeZone(), "MM/dd/yyyy HH:mm:ss")
change into:
sheetTimeStamp = Utilities.formatDate(new Date(sheetTimeStamp), Session.getTimeZone(), "MM/dd/yyyy HH:mm:ss")
it should work

Format/parse different Date formats correctly

I receive Date in 3 formats from different APIs
UTC format: 2014-01-01T00:00:00.000Z (String)
GMTformat: Thu, 29 Nov 2018 17:30:56 GMT (String)
unixTimeStamp: 1558606726 (number)
Also the UTC format sometimes might not have Z in the end so the normal parsing will give a time difference.
function formatDate(dateString) {
var dateTime, utcFormatRegex, zeroHourOffsetRegex;
// Some APIs return a Date in standard ISO UTC format may not have Z at the end
utcFormatRegex = /^\d{4}-\d{2}-\d{2}T.*$/;
zeroHourOffsetRegex = /^.*Z$/;
if (utcFormatRegex.test(dateString) && !zeroHourOffsetRegex.test(dateString)) {
dateString+='Z';
}
dateTime = new Date(dateString);
}
Given that there are parsing functions for all of the different formats, i need a function that determines which parsing function we should be using based on a regex and parse it accordingly. If regex is not the ideal solution then how can i approach this?
What I'm getting at is there should probably be a more robust solution than 'if there isn't a Z then add one' to get it to parse through the single date time parser. What if we get another date time format that doesn't play nicely with a Z on the end? We'll be making multiple changes at that point in time.
Using a regular expression is OK, but you need to test strictly for the formats you're expecting. If you get something you don't expect, throw an error. It's one of the failings of current built–in parsers is that there's no way to specify strict parsing, e.g. where a format is supplied and the parser throws an error if the input string doesn't match.
There are libraries that can help, a search will reveal quite a few.
But if you only have to support the 3 formats in the OP, something like the following may suit:
/* Return a Date where the input may be:
** string: ISO 8601 timestamp that should be treated as UTC
** whether it has a trailing Z or not
** string: Timestamp in the format (using moment.js tokens):
** ddd, DD MMM YYYY HH:mm:ss GMT
** nunber: UNIX time value, seconds since 1970-01-01 UTC
*/
function toDate(value) {
// Parse the string & fail early if it fails
let d = new Date(value);
// Throw error if couldn't parse value
if (isNaN(d.getTime())) {
throw 'Invalid timestamp: ' + value;
}
// Otherwise, do the work
let days = 'Sun Mon Tue Wed Thu Fri Sat'.split(' ');
let months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
// Test for time value first as that's the easiest
if (typeof value == 'number' && !isNaN(value)) {
return new Date(value * 1000);
// Test for ISO 8601 next
} else if (/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ?$/.test(value)) {
return new Date(/Z$/.test(value)? value : value + 'Z');
// Test for random format
} else if (/^[a-z]{3}, \d?\d [a-z]{3} \d{4} \d\d:\d\d:\d\d GMT$/i.test(value)) {
let b = value.split(/ |:/);
if (days.includes(b[0].substr(0,3)) && months.includes(b[2])) {
let x = new Date(Date.UTC(
b[3], // year
months.indexOf(b[2]), // month, zero indexed
b[1], // day
b[4], b[5], b[6] // hh:mm:ss
));
// Check value was a valid date, only need to check some parts
if (x.getUTCFullYear() == b[3] &&
x.getUTCDate() == b[1] &&
x.getUTCHours() == b[4] &&
x.getUTCSeconds() == b[6]) {
return x;
} else {
throw 'Invalid timestamp: ' + value;
}
}
// Throw error as must be unknown format
} else {
throw 'Unknown format: ' + value;
}
}
// Minimal testing
var isoString0 = '2014-01-01T00:00:00.000Z',
isoString1 = '2014-01-01T00:00:00.000', // no Z, parse as UTC anyway
randomString = 'Thu, 29 Nov 2018 17:30:56 GMT',
unixTimeValue = 1558606726, // Assume seconds
invalidDate0 = '2018-02-29T00:00:00.000Z', // no 29 Feb in 2018, fail built-in parse
invalidDate1 = 'Thu, 29 Feb 2018 17:30:56 GMT', // no 29 Feb in 2018, fail manual parse
invalidFormat = '6/6/2019'; // Unknown format
[isoString0, isoString1, randomString, unixTimeValue, invalidDate0,
invalidDate1, invalidFormat].forEach(s => {
var result;
try {
result = toDate(s);
console.log(s + ' =>\n' + result.toISOString());
} catch (e) {
console.log(e);
}
});

JavaScript - Assigning Array Index to Return Value not working

I am trying to assign a return value to an element in an array, and for some reason it is overwriting both elements in the array to the same value instead of just the second element.
The datepicker I'm using for this can be found here, for reference.
http://www.eyecon.ro/datepicker/
function AddDays(date, days)
{
var newDate = new Date(date.setTime( date.getTime() + days * 86400000 ));
return newDate;
}
$('#nights').on('change', function(){
var $dp = $('#date');
var t = $dp.DatePickerGetDate();
console.log(t); // Output 1
t[1] = AddDays(t[0], $(this).val());
console.log(t); // Output 2
});
Output 1 : [Mon Jan 02 2017 00:00:00 GMT-0600 (Central Standard Time), Sun Jan 08 2017 23:59:59 GMT-0600 (Central Standard Time)]
Output 2 : [Mon Jan 09 2017 00:00:00 GMT-0600 (Central Standard Time), Mon Jan 09 2017 00:00:00 GMT-0600 (Central Standard Time)]
As you can see, when I try to assign the second element t[1] to equal the return of AddDays(t[0], $(this).val()) both dates get set the same exact date. However, the second element is supposed to be equal to the first element plus the number of days specified.
I also verified that the element $(this).val() is not zero. In my case that is in fact returning 7 when I run console.log($(this).val()); right before the assignment of t[1].
What am I doing wrong here?
Your function modifies the date that is passed in when you call setTime. You can remove the call to setTime to solve your problem.
function addDays(date, days) {
return new Date(date.getTime() + (days * 86400000));
}
Or make a brand new date object and call setDate or setTime on the copy.
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}

JavaScript: Comparing two dates no output

I would like to compare the given date in the below format in JaveScript. I have tried the following,
Thu May 19 2016 00:00:00 GMT+0530 (India Standard Time)
Thu May 20 2016 00:00:00 GMT+0530 (India Standard Time)
var ExpiryDate = userAccount.ExpiryDate();
var datetoday = new Date();
var Expired = (DateTime.Compare(ExpiryDate, datetoday) == -1 ) ? true : false;
//if expiry date is less than today date then var expired should be true
But didn't worked. I could not compare those two dates. It results in un handled exception. Is there any other way to do this date comparison in JaveScript ?
I have referred the following answers in SO but they are in different date format. So that I have raised this question,
javascript compare two dates and throw an alert
Javascript comparing two dates has wrong result
Compare two dates in JavaScript
Javascript compare two dates to get a difference
Any suggestion would be helpful.
var date = new Date();
//# => Fri May 20 2016 16:09:43 GMT+0530 (India Standard Time)
var date2 = new Date();
date2.setDate(date.getDate() - 1);
//# => Thu May 19 2016 16:09:43 GMT+0530 (India Standard Time)
date > date2 //# => true
use getTime()
var date1 = (new Date("20 May 2016")).getTime();
var date2 = (new Date("19 May 2016")).getTime();
date1>date2
You will find some good method here

How to compare two dates (MonthName YearNumber) in javascript

This functionality is working fine in Chrome... But not IE or FF.
I am trying to validate two fields that take the value of MonthName YearNumber (see screenshot).
I am using Date.parse() to get miliseconds, then compare if Start Date <= End Date.
function IsStartEndDtError(StartDt, EndDt) {
//convert dates to miliseconds to compare if one is greater than other
var StartDtMili = Date.parse(StartDt);
var EndDtMili = Date.parse(EndDt);
if (StartDtMili <= EndDtMili) {
return false;
}
else {
return true;
}
}
What appears in Firebug:
Since the format your date is in isn't universally supported you can try a library like Date.js:
Date.parse("November 2012")
// returns: Thu Nov 01 2012 00:00:00 GMT+0000 (GMT)
If you don't want another library you can manually replace the month names with numbers and create a new date string.
Ecmascript does not seem to support full month names, if you look at "Section 15.9.1.15 Date Time String Format" in the spec.
In Firefox:
new Date("November 2012")
// Invalid Date
new Date("2012-11")
// Thu Nov 01 2012 00:00:00 GMT+0000 (GMT)
The second date format should be standardized across browsers, the first isn't.
11 1999, November 1999 are not parsable formats. You either need to use a date library that is more flexible with its input formats, or process your input and identify the parts in it:
function IsStartEndDtError(StartDt, EndDt) {
var months = {
January: 0,
February: 1,
...
};
//convert dates to miliseconds to compare if one is greater than other
var StartDtMili = (new Date(StartDt.split(" ")[1], month[StartDt.split(" ")[0]])).getTime();
var EndDtMili = (new Date(EndDt.split(" ")[1], month[EndDt.split(" ")[0]])).getTime();
if (StartDtMili <= EndDtMili) {
return false;
}
else {
return true;
}
}

Categories

Resources