As you were told, it is common to use moment.js to abstract that layer of logic. However, it can also be resolved by adapting your dates to a format that complies with ISO-8601
var fecha1='01/12/2018',
fecha2='2018-12-01';
console.log('fecha 1 se evalúa como', new Date(fecha1).toISOString().split('T')[0]);
console.log('fecha 2 se evalúa como', new Date(fecha2).toISOString().split('T')[0]);
Why in the first case transposes the month with the day? Well, that's the format in English. And precisely because of that ambivalence is a bad idea to use it in your code.
If you are certain that all your dates have the form dd/MM/YYYY
you can transform them by doing a normalization function:
function normalizaFecha(fecha_str) {
if(/\d{2}\/\d{2}\/\d{4}/.test(fecha_str)) {
return fecha_str.split('/').reverse().join('-');
}
return fecha_str;
}
And with that you can make a comparison of the type:
if(normalizaFecha(Objeto2.inicio) > normalizaFecha(Objeto1.fin)) {
throw new Error('Fechas se superponen');
}
Edit: If you are using a calendar plugin for the user to choose their date or enter it in a text field and, again, you know it comes in the DD / format MM / YYYY You can use the function that I showed you. Using moment.js you could use:
moment('01/06/2016', 'DD/MM/YYYY')
To instruct you to interpret the date with the Latin format.
In your case you have
param[1]['params'].array.forEach(element => {
if(userStart > element.startdatevalidity && userFinish > element.enddatevalidity
|| userStart < element.startdatevalidity && userFinish < element.enddatevalidity
&& userStart > element.enddatevalidity
){
console.log('good');
}else{
console.log('=(');
}
});
In that code I think there are missing parentheses to isolate the conditions ( it is better to use defensive pages said Eric S. Raymond almost 30 years ago)
I think it's easier to focus on the reverse:
- If the start date is contained in the range - > error
- If the end date is contained in the range - > error
- If the range contains the entered range - > error
- If the entered range contains the range - > error
The third condition is not necessary to check it because it falls within the first.
Abstracting this to one purpose:
function validaRango(nuevoRango, rangoExistente) {
let iniNuevo = nuevoRango.startdatevalidity,
finNuevo = nuevoRango.enddatevalidity,
iniExistente = rangoExistente.startdatevalidity,
finExistente = rangoExistente.enddatevalidity;
if (iniNuevo > iniExistente && iniNuevo < finExistente ) {
return false; // fecha inicio se superpone
}
if (finNuevo > iniExistente && finNuevo < finExistente ) {
return false; // fecha fin se superpone
}
if (iniNuevo < iniExistente && finNuevo > finExistente) {
return false; // nuevo rango contiene al rango ya ocupado
}
return true;
}
If your values for startdatevalidity
and enddatevalidity
you know that they come in DD/MM/YY
format then use the auxiliary function that I passed to you:
function normalizaFecha(fecha_str) {
if(/\d{2}\/\d{2}\/\d{4}/.test(fecha_str)) {
return fecha_str.split('/').reverse().join('-');
}
return fecha_str;
}
function validaRango(nuevoRango, rangoExistente) {
let iniNuevo = normalizaFecha(nuevoRango.startdatevalidity),
finNuevo = normalizaFecha(nuevoRango.enddatevalidity),
iniExistente = normalizaFecha(rangoExistente.startdatevalidity),
finExistente = normalizaFecha(rangoExistente.enddatevalidity);
if (iniNuevo > iniExistente && iniNuevo < finExistente ) {
return false; // fecha inicio se superpone
}
if (finNuevo > iniExistente && finNuevo < finExistente ) {
return false; // fecha fin se superpone
}
if (iniNuevo < iniExistente && finNuevo > finExistente) {
return false; // nuevo rango contiene al rango ya ocupado
}
return true;
}
And in the loop you use:
param[1]['params'].array.forEach(element => {
if(validaRango(newConfig, element)) {
console.log('good');
}else{
console.log('=(');
}
});
Bonus track to use moment.js with Angular / Typescript
recent versions of moment.js come with definition of types if you want to use typescript with all its validations:
# instalas la librería
npm i moment
And in your component of AngularJS you do:
import * as moment from 'moment';
Then you can for example create a function that converts a string with the format DD/MM/YYYY
to an object of type moment.Moment
dateToMoment(date_str: string): moment.Moment {
return moment(date_str, 'DD/MM/YYYY');
}
Either one that receives an object of type moment.Moment
and returns it as a string:
momentToString(momentObj: moment.Moment): string {
return momentObj.format();
}
Actually if you want to go from a string DD/MM/YYYY
to a YYYY-MM-DD
you do not need to use the type moment.Moment
since the function normalizaFecha
would be simply:
normalizaFecha(date_str: string): string {
return moment(date_str, 'DD/MM/YYYY').format();
}
But it serves to illustrate the type of data that Typescript would expect from a moment object.