Comparing Dates with different formats in Javascript - javascript

I'm attempting to compare 2 dates that have 2 different formats in Javascript.
The date from my database is 2013-04-21 (date1) and the date in the array prints out in the following format in my Chrome debugger: Sun Apr 21 2013 15:37:05 GMT-0400 (Eastern Daylight Time) (date2)
I'd like to compare only the date part and leave out the time: date1 == date2 is true.
How would I go about formatting the dates so I'd be able to compare them?
Any help is greatly appreciated.

y = date2.getFullYear();
m = date2.getMonth()+1;
m = (m<10)? ('0'+m) : m;
d = date2.getDate();
d2 = y+'-'+m+'-'+d;
if (date1 == d2) {
// do something
}

date1.toISOString().split("T")[0] == date2.toISOString().split("T")[0]

We have to go a little deeper here: we have to distinguishe between Strings storing date, and the Date object which can store dates and do computation with dates.
From your description i guess that date1 is acutally a string "2013-04-21" while date2 is already a Date object.
You could convert date1 to a date object:
date1AsObject = new Date("2013-04-21");
Then you could compute the difference between them:
diff = date2 - date1AsObject
the result will be in milliseconds.
or you could convert date2 to a string like
Crayon Violent suggested:
y = date2.getFullYear();
m = date2.getMonth()+1;
d = date2.getDate();
date2AsString = y+'-'+m+'-'+d;
then you can compare the two strings.

Related

How can I create a list of days between 2 dates? [duplicate]

I have two moment dates:
var fromDate = moment(new Date('1/1/2014'));
var toDate = moment(new Date('6/1/2014'));
Does moment provide a way to enumerate all of the dates between these two dates?
If not, is there any better solution other than to make a loop which increments the fromDate by 1 until it reaches the toDate?
Edit: Adding date enumeration method and problem
I've mocked up a method for enumerating the days between two dates, but I'm running into an issue.
var enumerateDaysBetweenDates = function(startDate, endDate) {
var dates = [];
startDate = startDate.add(1, 'days');
while(startDate.format('M/D/YYYY') !== endDate.format('M/D/YYYY')) {
console.log(startDate.toDate());
dates.push(startDate.toDate());
startDate = startDate.add(1, 'days');
}
return dates;
};
Take a look at the output when I run enumerateDaysBetweenDates( moment(new Date('1/1/2014')), moment(new Date('1/5/2014'));
Thu Jan 02 2014 00:00:00 GMT-0800 (PST)
Fri Jan 03 2014 00:00:00 GMT-0800 (PST)
Sat Jan 04 2014 00:00:00 GMT-0800 (PST)
[ Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
Sun Jan 05 2014 00:00:00 GMT-0800 (PST) ]
It's console.logging the right dates, but only the final date is being added to the array. How/why is this? This smells like some sort of variable reference issue - but I'm not seeing it.
.add() is a mutator method, so the assignment in this line is unnecessary:
startDate = startDate.add(1, 'days');
You can just do this, and have the same effect:
startDate.add(1, 'days');
While it's name would imply the creation of a new Date object, the toDate() method really just returns the existing internal Date object.
So, none of your method calls are creating new Date or moment object instances. Fix that by using .clone() to get a new instance:
startDate = startDate.clone().add(1, 'days');
Or better yet, wrap the values in a call to moment() as Mtz suggests in a comment, and it will clone the instance, if the value is a moment object, or it will parse the input to create a new moment instance.
startDate = moment(startDate).add(1, 'days');
I think a date enumerator method should not change either of the arguments passed in. I'd create a separate variable for enumerating. I'd also compare the dates directly, rather than comparing strings:
var enumerateDaysBetweenDates = function(startDate, endDate) {
var dates = [];
var currDate = moment(startDate).startOf('day');
var lastDate = moment(endDate).startOf('day');
while(currDate.add(1, 'days').diff(lastDate) < 0) {
console.log(currDate.toDate());
dates.push(currDate.clone().toDate());
}
return dates;
};
Got it for you:
var enumerateDaysBetweenDates = function(startDate, endDate) {
var now = startDate.clone(), dates = [];
while (now.isSameOrBefore(endDate)) {
dates.push(now.format('M/D/YYYY'));
now.add(1, 'days');
}
return dates;
};
Referencing now rather than startDate made all the difference.
If you're not after an inclusive search then change .isSameOrBefore to .isBefore
Fiddle: http://jsfiddle.net/KyleMuir/sRE76/118/
use moment and work with while loop, code will run in loop untill startDate is equal to endDate and push startDate and then increment it with 1 day so can get next date
function enumerateDaysBetweenDates (startDate, endDate){
let date = []
while(moment(startDate) <= moment(endDate)){
date.push(startDate);
startDate = moment(startDate).add(1, 'days').format("YYYY-MM-DD");
}
return date;
}
you can test it by calling function like this
let dateArr = enumerateDaysBetweenDates('2019-01-01', '2019-01-10');
Using moment library and for loop you can enumerate between two dates.
let startDate = moment('2020-06-21');
let endDate = moment('2020-07-15');
let date = [];
for (var m = moment(startDate); m.isBefore(endDate); m.add(1, 'days')) {
date.push(m.format('YYYY-MM-DD'));
}
console.log(date)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Momentjs doesn't provide this by itself but there is a plugin which offers it: moment-range.
Specifically, check out the Iteration docs.
As an extension of Kyle's answer - I've been trying to get this to work with Unix timestamps and after lots of trial and error I got it to work and thought I'd post it here in case anyone is seeking the same thing and needs it. See my code below:
fromDate = moment.unix(req.params.dateFrom).format('YYYY-MM-DD')
toDate = moment.unix(req.params.dateTo).format('YYYY-MM-DD')
// Returns an array of dates between the two dates
function enumerateDaysBetweenDates(startDate, endDate) {
startDate = moment(startDate);
endDate = moment(endDate);
var now = startDate, dates = [];
while (now.isBefore(endDate) || now.isSame(endDate)) {
dates.push(now.format('YYYY-MM-DD'));
now.add(1, 'days');
}
return dates;
};
Note that I convert it to Unix, then convert that value to moment again. This was the issue that I had, you need to make it a moment value again in order for this to work.
Example usage:
fromDate = '2017/03/11' // AFTER conversion from Unix
toDate = '2017/03/13' // AFTER conversion from Unix
console.log(enumerateDaysBetweenDates(fromDate, toDate));
Will return:
['2017/03/11', '2017/03/12', '2017/03/13']
Using ES6 notation
const from = moment('01/01/2014', 'DD/MM/YYYY')
const to = moment('06/01/2014', 'DD/MM/YYYY')
const nbDays = to.diff(from, 'days') + 1
const result = [...Array(nbDays).keys()]
.map(i => from.clone().add(i, 'd'))
console.log(result)
<script src="https://momentjs.com/downloads/moment.min.js"></script>
You can easily enumerate with moment.js Here is a more generic solution for days, weeks, months or years:
https://gist.github.com/gvko/76f0d7b4b61b18fabfe9c0cc24fc3d2a
Using moment library and for loop you can enumerate between two dates.
const moment = require('moment');
let startDate = moment('2021-12-24');
let endDate = moment('2022-1-4');
let date = [];
for (var m = moment(startDate); m.isSameOrBefore(endDate); m.add(1, 'days')) {
date.push(m.format('DD/MM/YYYY'));
}
console.log(date)

UTC date convert to local timezone

I have a date in UTC format.
"2016-10-12 05:03:51"
I made a function to convert UTC date to my local time.
function FormatDate(date)
{
var arr = date.split(/[- :T]/), // from your example var date = "2012-11-14T06:57:36+0000";
date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], 00);
var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
var offset = date.getTimezoneOffset() / 60;
var hours = date.getHours();
newDate.setHours(hours - offset);
return newDate;
}
My Local timezone is GMT +0530.
My code produced this output:
Tue Oct 11 2016 10:33:00 GMT+0530 (IST)
I converted the date with an online tool to get the correct date and time.
Wednesday, October 12, 2016 10:30 AM
My code matches the online tool on time but not on date.
How can I correct my code's output, preferably using moment.js?
UTC is a standard, not a format. I assume you mean your strings use a zero offset, i.e. "2016-10-12 05:03:51" is "2016-10-12 05:03:51+0000"
You are on the right track when parsing the string, but you can use UTC methods to to stop the host from adjusting the values for the system offset when creating the date.
function parseDateUTC(s){
var arr = s.split(/\D/);
return new Date(Date.UTC(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]));
}
console.log(parseDateUTC('2016-10-12 05:03:51').toLocaleString());
If you want to use moment.js, you can do something like the following. It forces moment to use UTC when parsing the string, then local to write it to output:
var d = moment.utc('2016-10-12 05:03:51','YYYY-MM-DD HH:mm:ss');
console.log(d.local().format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.0/moment.js"></script>
Since you have tagged moment, I'm assuming you are using moment.
In such cases, you should keep your approach consistent and not mix moment and date object.
var dateStr = '2016-10-12 05:03:51';
var timeZone = "+0530";
var date = moment.utc(dateStr).utcOffset(dateStr + timeZone)
console.log(date.toString())

Date and time based json element using javascript

I have a json response like this :
{
"NO_INSPECTION": "55",
"NO_SURAT": "00055",
"DATE_OF_DESCRIPTION": "2015-12-21 03:08:24"
}
How can I convert the data in "DATE_OF_DESCRIPTION" Into date and time. Date should be dd-mm-yyy format and time should be in HH:mm format. (A sample value of DATE_OF_DESCRIPTION is 2015-12-21 03:08:24)
I have tried new Date(response.DATE_OF_DESCRIPTION); but no success. How can I achieve this?
Without the use of other libraries and assuming the output will always be zero-padded and the same length, I would do this:
var response = {
DATE_OF_DESCRIPTION: "2015-12-21 03:08:24"
}
var raw = response.DATE_OF_DESCRIPTION;
var datePart = raw.split(' ')[0];
var timePart = raw.split(' ')[1];
var year = datePart.substring(0, 4);
var month = datePart.substring(5, 7);
var day = datePart.substring(8, 10);
var hours = timePart.substring(0, 2);
var minutes = timePart.substring(3, 5);
// NOTE: Month is 0 indexed
var date = new Date(year, month - 1, day);
var dateTime = new Date(year, month - 1, day, hours, minutes);
console.log(date);
console.log(dateTime);
This gives the output
Mon Dec 21 2015 00:00:00 GMT+1000 (E. Australia Standard Time)
Mon Dec 21 2015 03:08:00 GMT+1000 (E. Australia Standard Time)
(I'm from Australia, so your timezone will vary)
JavaScript has a fixed date format and you can change it, thus the Date object won't help you this time. As I see it, you want to split that date, so it's pretty easy if you provide it in this format "dd-mm-yyy HH:mm":
response.DATE_OF_DESCRIPTION = response.DATE_OF_DESCRIPTION.split(" "); // date and time are separated by an space
var date = response.DATE_OF_DESCRIPTION[0];
var time = response.DATE_OF_DESCRIPTION[1];
BTW, if you want to parse a date in a specified format, why don't you use any library for that? Many of them are almost as reliable and fast as native methods. Give them a try ;)
You could also format the date, so it fits the JS specs but, why reinvent the wheel? Libraries will do this for you and you'll get optimal cross-browser results!
I've googled "javascript date parsing library" and this is what I've found:
http://momentjs.com/ <--- I think that's what you're looking for!

What is the proper way to create a timestamp in javascript with date string?

I have date format returned as 05-Jan, 12-feb etc.. when i convert current date using date object in javascript . I did something like this
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth(),
curr_day = curr.getDay(),
today = new Date(curr_year, curr_month, curr_day, 0, 0, 0, 0);
console.log(today);
Here the today is returned as invalid date i needed the create a timestamp which should not include minutes secs and millisecs as zero for date comparison of month and date alone based on that i can categories .Is there way to dynamically create a date and compare those dates for given format.
And when i try to convert my date string using date object it returns year as 2001. how can i compare dates based upon current year.
For eg: in php i have used mktime to create a date dynamically from given date format and compare those results. Any suggestion would be helpful. Thanks.
You can leverage the native JS Date functionality to get human-readable date strings for time stamps.
var today = new Date();
console.log( today.toDateString() ); // Outputs "Mon Feb 04 2013"
Date comparison is also built in.
var yesterday = new Date();
yesterday.setDate( yesterday.getDate() - 1);
console.log( yesterday.toDateString() ); // Outputs "Sun Feb 03 2013"
console.log( yesterday < today ); //Outputs true
You can use the other built-in methods to fine-tune this comparison to be/not be sensitive to minutes/seconds, or to set all those to 0.
You said that you used mktime() in php, so what about this?
change to this :
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth()+1,
curr_day = curr.getDay(),
today = curr_month+'/'+curr_day+'/'+curr_year;
console.log(today);
(getMonth()+1 is because January is 0)
change the :
today = curr_month+'/'+curr_day+'/'+curr_year;
to whatever format you like.
I have found a way to convert the date into timestamp i have tried as #nbrooks implemented but .toDateString has built in date comparison which works for operator < and > but not for == operator to do that i have used Date.parse(); function to achieve it. Here it goes..
var curr = new Date(),
curr_year = curr.getFullYear(),
curr_month = curr.getMonth(),
curr_day = curr.getDate(),
today = new Date(curr_year, curr_month, curr_day, 0,0,0,0);
var dob = new Date('dob with month and date only'+curr_year);
if(Date.parse(dob) == Date.parse(today)){
//Birthdays....
}
This method can be used to create a timestamp for dynamically created date.Thanks for your suggestions.

Regarding JavaScript new Date() and Date.parse()

var exampleDate='23-12-2010 23:12:00';
I want to convert above string into a date and have tried a couple things:
var date = new Date(exampleDate); //returns invalid Date
var date1 = Date.parse(exampleDate); //returns NAN
This code is running fine in IE and Opera, but date is returning me an invalid Date and date1 is returning NAN in Firefox. What should I do?
The string in your example is not in any of the standard formats recognized by browsers. The ECMAScript specification requires browsers to be able to parse only one standard format:
The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
This format includes date-only forms:
YYYY
YYYY-MM
YYYY-MM-DD
It also includes time-only forms with an optional time zone offset appended:
THH:mm
THH:mm:ss
THH:mm:ss.sss
Also included are “date-times” which may be any combination of the above.
If the String does not conform to that format the function may fall back to any
implementation-specific heuristics or implementation-specific date formats. Unrecognizable Strings or dates
containing illegal element values in the format String shall cause Date.parse to return NaN.
So in your example, using 2010-12-23T23:12:00 is the only string guaranteed to work. In practice, most browsers also allow dates of the format DD Month YYYY or Month DD, YYYY, so strings like 23 Dec 2010 and Dec 23, 2010 could also work.
Above format is only supported in IE and Chrome.
so try with another formats. following are some formats and there supporting browsers.
<script type="text/javascript">
//var dateString = "03/20/2008"; // mm/dd/yyyy [IE, FF]
var dateString = "2008/03/20"; // yyyy/mm/dd [IE, FF]
// var dateString = "03-20-2008"; // mm-dd-yyyy [IE, Chrome]
// var dateString = "March 20, 2008"; // mmmm dd, yyyy [IE, FF]
// var dateString = "Mar 20, 2008"; // mmm dd, yyyy [IE, FF]
// Initalize the Date object by passing the date string variable
var myDate = new Date(dateString);
alert(myDate);
</script>
You could parse it manually with a regular expression then call the date constructor with the date elements, as such:
var parseDate = function(s) {
var re = /^(\d\d)-(\d\d)-(\d{4}) (\d\d):(\d\d):(\d\d)$/;
var m = re.exec(s);
return m ? new Date(m[3], m[2]-1, m[1], m[4], m[5], m[6]) : null;
};
var dateStr = '23-12-2010 23:12:00';
parseDate(dateStr).toString(); //=> Thu Dec 23 2010 23:12:00 GMT-0800
JavaScript should support conversion at least from the following dateStrings:
* yyyy/MM/dd
* MM/dd/yyyy
* MMMM dd, yyyy
* MMM dd, yyyy
Try with:
var exampleDate='12/23/2010 23:12:00';
var date = new Date(exampleDate);
Use datejs and this code:
var exampleDate='23-12-2010 23:12:00';
var myDate = Date.parseExact(exampleDate, 'dd-MM-yyyy hh:mm:ss');
myDate should be a correctly constructed Date object.
Just use in this format:
var exampleDate='2010-12-23 23:12:00';
#casablanca has a good answer but it's been 10+ years and this still has a lot of weight in Google so I thought I'd update with a new answer.
TL;DR
// Use an ISO or Unix time string to generate `Month DD, YYYY`
const newDate = new Date('23-12-2010')
const simpleDate = `${newDate.toLocaleString('en-us', { month: 'long' } )} ${newDate.getDate()}, ${newDate.getFullYear()}`
// yields: December, 23 2010 (if you want date suffix, read until the end)
Background: Dates come in a lot of formats, but you're mostly going to receive:
An ISO 8601 format date (YYYY-MM-DDTHH:mm:ss.sssZ) where Z is a UTC timezone offset. You might also get a subset of this (ie, YYYY-MM-DD)
Unix timestamp format date (1539734400), where the number is literally the total amount of milliseconds since the beginning of Unix time, Jan 1st 1970.
Basics: JS has a built-in Date prototype that accepts ISO 8601 and derivatives (of just time or just date). You can instantiate with new Date and return a date object OR you can use the Date.parse() method to return a Unix timestamp.
const dateObj = new Date('23-12-2010:23:12:00') // returns date object
const dateDateOnly = new Date('23-12-2010') // returns date object
const dateTimeOnly = new Date('23:12:00') // returns date object
const dateString = Date.parse('23-12-2010:23:12:00') // returns Unix timestamp string
You can also break the date into 7 parameters: the year, the month (starting from 0), the day, the hour, the minutes, seconds and milliseconds with the time zone offset - NOTE, I've used the multi-params approach only once in my career. Since I'm in Texas I get, UTC-5 (Central Time) when I run the following:
const dateByParam = new Date(2021, 2, 26, 13, 50, 13, 30) // Fri Mar 26 2021 13:50:13 GMT-0500 (Central Daylight Time)
New-ish Stuff toLocaleString: Typically, the return from the Date object is still pretty dense like our last example (Fri Mar 26 2021 13:50:13 GMT-0500 (Central Daylight Time) so additional methods have been added to help developers.
Typically with a date, I want something like March 21st, 2021 - the day and year have been easy to get for a long time:
// Assuming myDate is a JS Date object...
myDate.getDate() // date on the calendar, ie 22
myDate.getDay() // day of the week, where 0 means Sunday, 1 means monday, etc
myDate.getFullYear() // 4 digit year, ie, 2021
But I've always had to build a function to turn getDay into January, February, March, not anymore. toLocaleString() gives you some new superpowers. You can pass it two params, a string for region (ie, en-us) and an object with what you want back (ie, { month: 'long' }). This helps internationalize the response, if need be.
// Again, assuming myDate is a JS Date object...
myDate.toLocaleString('en-us', { month: 'long' } ) // March
Date Suffix I've still seen no built-in way to get the suffix for a date, like th, st, so I built this utility function that uses the modulus % operator to check the divisor of each day number and apply the right suffix (aimed at an American audience but might be the same elsewhere?).
/**
* setDateSuffix()
*
* Desc: Takes two digit date, adds 'st', 'nd', 'rd', etc
*
* #param { integer } num - a number date
*/
export const setDateSuffix = (num) => {
const j = num % 10,
k = num % 100
if (j === 1 && k !== 11) {
return num + "st";
}
if (j === 2 && k !== 12) {
return num + "nd";
}
if (j === 3 && k !== 13) {
return num + "rd";
}
return num + "th";
}
Altogether now.. Long winded way of getting here, but if I am given an ISO or Unix date and I want Month DDth, YYYY, this is what I run:
// setDateSuffix IS NOT PART OF BUILT-IN JS!
const newDate = new Date('23-12-2010')
const simpleDate = `${newDate.toLocaleString('en-us', { month: 'long' } )} ${setDateSuffix(newDate.getDate())}, ${newDate.getFullYear()}`
// yields: December 23rd, 2010
Note - all of this will likely change, hopefully for the better, when temporal becomes a reality in JS: https://github.com/tc39/proposal-temporal. Look forward to somebody's 2030 update of this post!

Categories

Resources