Sort an array of strings that are dates JavaScript - javascript

I've tried using underscorejs, min and max methods but they can't handle strings. From what i've read and learnt anyway, since I get infinite back from both.
My array looks like : dateData = ["26/06/2016", "04/06/2016", "13/05/2016", "20/07/2016"]
How can I grab the last and the first date in these?
I tried using sort also that looks like : _.chain(dateData).sort().first().value() but I get back the last item in the array rather then the last date in the array.

var dateData = ["26/06/2016", "04/06/2016", "13/05/2016", "20/07/2016"];
function dateToNum(d) {
// Convert date "26/06/2016" to 20160626
d = d.split("/"); return Number(d[2]+d[1]+d[0]);
}
dateData.sort(function(a,b){
return dateToNum(a) - dateToNum(b);
});
console.log( dateData );
To retrieve the first, last date:
var firstDate = dateData[0];
var lastDate = dateData[dateData.length -1];
Basically, if you first convert all your 26/06/2016 to a date Number like 20160626 you can .sort() those numbers instead.
so you're basically sorting:
20140626
20140604
20140513
20140720
resulting in:
[
"13/05/2016",
"04/06/2016",
"26/06/2016",
"20/07/2016"
]

If we can format the dateStrings in a particular format, then sorting them as strings also sorts them as dates e.g. YYYY-MM-DD.
You can use localeCompare to compare strings.You can use following code to sort the dates:
dateData = ["26/06/2016", "04/06/2016", "13/05/2016", "20/07/2016"]
dateData.sort(function(a, b){
var A = a.split("/");
var B = b.split("/");
var strA = [ A[2], A[1], A[0] ].join("/");
var strB = [ B[2], B[1], B[0] ].join("/");
return strA.localeCompare( strB );
});
console.log( dateData );
Once sorted, you can get the min and max dates as:
var minDate = dateData[0];
var maxDate = dateData[ dateData.length - 1 ];

The getTime() method returns the numeric value corresponding to the
time for the specified date according to universal time. Date.getTime()
dateData = ["26/06/2016", "04/06/2016", "13/05/2016", "20/07/2016"]
.map(a=>a.split('/').reverse().join('/'))
.sort((a,b)=>new Date(a).getTime() - new Date(b).getTime());
console.log(dateData);

A number people have already touched on this, but you need to convert the date strings to something that can be compared in the sort function. The one thing I haven't seen shared is how to get the first and last dates. This should do the trick:
//original date array
var dateData = ["04/06/2016", "13/05/2016", "20/07/2016","26/06/2016"];
//map through the original array and convert the dates to js date objects
var formattedDates = dateData.map(function(date){
var splitDate = date.split("/")
return new Date(splitDate[2],splitDate[1]-1,splitDate[0])
})
//sort the dates
formattedDates.sort(function(a,b){
// Turn your strings into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(a) - new Date(b);
});
//Now you can get the first and last dates:
var firstDate = formattedDates[0]
var lastDate = formattedDates[formattedDates.length-1];
//log to check:
console.log('first date: ', firstDate)
console.log('last date: ', lastDate)

One way I know to do this is using the .sort() function for a string. https://msdn.microsoft.com/en-us/library/4b4fbfhk(v=vs.94).aspx
You would have to change your array into YYYY-MM-DD
then you could have the following code
var dateData = ["2016/06/26", "2016/06/04", "2016/05/13", "2016/07/20"];
dateData.sort();
var first = dateData[0];
var last = dateData[dateData.length-1];
where first is the earliest date and last is the latest date

To be easier for the subsequest operations, change the format to be like this: YYYY/MM/DD.
This way regular sorting will get you the min and max properly, and you won't need further parsing.
Helper function to sort would be like this:
for(var i=0;i<dateData.length;++i)
{
var split = dateData[i].split("/");
dateData[i] = split.reverse().join("/");
}

Roko's answer worked for me, and +1. And Jose had a similar thought to me, +1...
...There's an easier and more robust way: .valueOf()
converting date string to number:
const dateAsNumber = new Date(dateAsString).valueOf()
JS has a built in method/function for calculating the number of milliseconds that have passed since a date; that's .valueOf(), which can be called on a Date object. So, turn your date string into a Date object (with "new Date()" with the date string as the argument), and then convert to milliseconds.
After that, the normal .sort() works fine. As shown below, for your convenience:
const arrayOfDateStrings = ["5/01/2012", "10/01/2020", "10/01/2019", "11/30/2016", "10/01/2021", "02/01/2020"];
const sortedArray = arrayOfDateStrings.sort((a,b)=>new Date(a).valueOf() - new Date(b).valueOf());
console.log(sortedArray);
Or Moment.js can be used instead of the built-in Date object/functions, that works in a very similar way.

Related

Compare Dates in Array of MongoDB Object with different formats

I am using a datepicker in my frontend which sends a date using an AJAX Request.
Now this date is in the format - 'YYYY-MM-DD'. I have an array of dates which I have to compare this date with and pick out which are equal. This array is from a Mongo DB collection where I have TimeZone included in the field as well, for example - "2020-06-03T00:00:00.000Z"
My Slot Json Object
{
date: [
2020-06-03T00:00:00.000Z,
2020-06-05T00:00:00.000Z,
2020-06-07T00:00:00.000Z
],
__v: 0
}
I have to loop over each date in the date array and compare it with the date I get from frontend.
Let's say user input date is
let userInput = '2020-06-03';
And now I have to compare it with the date array
How do I ensure that the following comparision leads me to get a true value for
'2020-06-03' and '2020-06-03T00:00:00.000Z'
I am looking at a solution which is appropriate when looping over all these array elements.
assuming, that your date array always is at 00:00:00 o'clock, i'd suggest something like this:
const dates = [
'2020-06-03T00:00:00.000Z',
'2020-06-05T00:00:00.000Z',
'2020-06-07T00:00:00.000Z'
];
let userInput = '2020-06-03';
function findDates(date) {
const searchDate = Date.parse(date);
const foundDates = [];
dates.forEach(date => {
const tempDate = Date.parse(date);
if (tempDate === searchDate) {
foundDates.push(date);
}
});
return foundDates;
}
console.log(findDates(userInput));
if there's more to consider, please say so
Have the format of date strings(input) and the array of dates be properly specified for parsing. Then you could straight away use the isSame() to check if the dates are equal
let input = "2020-06-03";
let arr = [
"2020-06-03T00:00:00.000Z",
"2020-06-05T00:00:00.000Z",
"2020-06-07T00:00:00.000Z"
];
let result = arr.map(item =>
moment(item, "YYYY-MM-DD hh:mm:ss zz").isSame(input, "YYYY-MM-DD")
);
console.log(result);
<script src="https://momentjs.com/downloads/moment.js"></script>

lodash - order dates with skipping year value

var dates = ['2017-02-01', '2017-01-01', '2016-02-03', '2018-02-02', '2014-12-25'];
var orderedDates = dates.sort(); // ['2017-01-01', '2017-02-01', '2018-02-02', '2016-02-03', '2014-12-25']
I have collection of dates(moment objects) from different year. I need to sort this dates only by 'ddMM' format (like skip years).
Is there any way to do this?
create copy of dates array, set same year for all dates - not seem like good solution.
for sorting use lodash .orderBy
You should use the 'MMDD' format and not 'DDMM'.
And it is not necessary to convert it back to a moment, since it is just to sort the array.
var orderedDates = _.orderBy(dates, e => moment(e).format('MMDD'));
You can use orderBy with an array of functions that specify your desired order (where the functions get the date and month from the moment object):
const date = (s) => moment(s, 'YYYY-MM-DD');
const dates = [date('2017-02-01'), date('2017-01-01'), date('2016-02-03'), date('2018-02-02'), date('2014-12-25')];
const result = _.orderBy(dates, [m => m.date(), m => m.month()]);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Javascript - Convert string to date and compare dates

I have date from the date picker which I am accessing as -
var transdate = $j("input[name='enterdate']").val();
resulting in transdate = "6/22/2015"
I need to test if the entered date is between two dates which are defined as
startdate = '2015-02-01' and enddate = '2015-07-30'
How do I convert the transdate in yyyy-mm-dd format in the following code -
if ((new Date('transdate')>= startdate ) && (new Date('transdate') <= enddate )) {
alert("correct date entered");
}
Moment.js is a small handy library for dates that makes this easy.
moment('6/22/2015', 'M/D/YYYY')
.isBetween('2015-02-01', '2015-07-30'); // => true
Note that only the first (US format) date string needed an explicit format string supplied.
Moment can be useful for the parsing alone, eg. even if not using isBetween:
var transdate = moment('6/22/2015', 'M/D/YYYY').toDate();
var startdate = moment('2015-02-01').toDate();
var enddate = moment('2015-07-30').toDate();
transdate >= startdate && transdate <= enddate // => true
The string is not in the only format defined to be handled by the Date object. That means you have to parse it (with regular expressions or String#split or whatever), or use a library like MomentJS that will parse it for you. Once you've parsed the dates, you can compare them with < or >, etc.
Do not rely on Date to parse strings it's not defined to parse. You will run into implementations or locales where it doesn't work.
"6/22/2015" is trivial to parse with a regular expression:
var rex = /^(\d+)\/(\d+)\/(\d+)$/;
var match = rex.exec(transdate);
var dt = match ? new Date(+match[3], +match[1] - 1, +match[2]) : null;
That uses the Date constructor that accepts the parts of the date as individual numeric arguments (year, month, day). The + converts strings to numbers. The [x] are capture groups from the regex. You have to subtract one from the month because months start with 0 in JavaScript.
Similar questions have been asked many, many times but I can't seem to find a duplicate. Given the unreliability of the Date constructor to parse strings, the simplest solution is to parse the string yourself:
function parseMDY(s) {
var b = s.split(/\D/);
return new Date(b[2], b[0]-1, b[1]);
}
Here is the JSFIDDLE of you output.
Moment.js will give you good flexibility in coding.
Dont forget to add jquery and moment.js in your html
var transdate="6/22/2014";
var convertStringToValidDate = new Date(transdate);
$(document).ready(function(){
$("#selectedDate").text(transdate);
$("#validDate").text(convertStringToValidDate);
converttoformat = moment(convertStringToValidDate).format("YYYY-MM-DD");
$("#converttoyyyymmdd").text(converttoformat);
if(moment(converttoformat).isBetween('2015-02-01', '2015-07-30')){
$("#result").text("Date lies in between");
}
else{
$("#result").text("Date is out of scope");
}
});

Format string with date by javascript to another format

I have string in this format:
var date = "2012-02-12";
I would like return the date in this format:
12.2.2012
What is the easiest way for this?
I was trying
var date = new Date( "2012-02-12" ).format("dd.m.yy");
but its returning error undefined is not a function.
var string = '2012-02-12';
var string = string.replace(/-/g, ".");
This will convert 2012-02-12 to 2012.02.12
You just need to reformat the string, so in browsers that support ES5 Array methods:
'2012-02-12'.split('-').reverse().map(function(v){return Number(v)}).join('.') // 12.2.2012
However, you might want a function that is a little more efficient and works in even very old environments:
function reformatDate(s) {
var b = s.split('-');
return b[2] + '.' + Number(b[1]) + '.' + Number(b[0]);
}
console.log(reformatDate('2012-02-12')); // 12.2.2012
If you don't care about converting '02' to '2', then:
'2012-02-12'.split('-').reverse().join('.'); // 12.02.2012
will do the job. However, that format will be understood by most people as 12 February but some as 2 December whereas the first format is unambiguously the former.
so it seem the shortest way is this:
var protocolDate = protocolDate.substr(8,2)+"."+
protocolDate.substr(5,2)+"."+
protocolDate.substr(0,4);
Isn't it a little bit counerproductive and frustrating that you can't use native javascript function for that?

Calculating Date difference and matching it with array

Is there any way in JavaScript that I can check if date is between 2 dates?
I have an array like
var unavailableDates = ["5-7-2011","6-7-2011","7-7-2011","15-7-2011","16-7-2011","17-7-2011" ];
and now I have 2 dates like 1-7-2011 and 10-7-2011. I want to see if any value from unavailableDates falls between these date. If it falls it should return alert.
Can someone help me on this? I am in process of learning more about JavaScript and jQuery. I am not able to code it the way I understood the problem.
Here you have the solution
var unavailableDates = ["5-7-2011","6-7-2011","7-7-2011","15-7-2011","16-7-2011","17-7-2011" ];
function str2date(sdate){ //This function gets a string and return a Date object
var parts = sdate.split("-");
return new Date(parts[2], parseInt(parts[1], 10)-1, parts[0]);
}
var stamp1 = str2date("1-7-2011").getTime(); //First date. getTime() converts it to an integer
var stamp2 = str2date("10-7-2011").getTime(); //Second date
for(var i=0; i<unavailableDates.length; i++){
var curStamp = str2date(unavailableDates[i]).getTime();
if(curStamp >= stamp1 && curStamp <= stamp2) //Check if it falls in range
alert(unavailableDates[i] + " falls in range");
}
Hope this helps. Cheers
Date object in JavaScript allows compare operation, you only required to have proper Date objects. Create Date objects from your bounds and array members and compare them in a loop.
More information about Date object could be found there: http://www.w3schools.com/js/js_obj_date.asp

Categories