// вспомогательный объект для сравнения дат в заданном формате, например так - dd.mm.yyyy, или так - yy.dd.mm
var Dates = {
format : "", // формат сравниваемых дат
formatPattern : /^(dd|mm|yy|yyyy)(\.|\-)(?!\1)(dd|mm|yy|yyyy)\2(?!\1)(?!\3)(dd|mm|yy|yyyy)$/gi, formatAssoc : { 1 : 0, 3 : 1, 4 : 2 }, // порядок соответствия индексов формата
position : { year : 0, month : 1, day : 2 }, // порядок сравнения частей дат (год, месяц, день)
separator : "", // разделитель (. или -)
status : { less : -1, equal : 0, larger : 1 }, // статусные биты
compare : function( date1, date2, format ) // основной метод: сравнение дат по заданному формату
{
// получение сравниваемых дат
var date1 = date1,
date2 = date2;
// сохранение заданного формата
this.setFormat( format );
// сравнение дат с первоначальной проверкой заданного формата на валидность использования.
// сравнение идет по изначально определенным индесам заданного формата
if ( this.checkFormat() )
{
// разделение дат по разделителю формата на части (год, месяц, день)
date1 = date1.split( this.separator );
date2 = date2.split( this.separator );
// сравнение дат по годам:
if ( date1[ this.position.year ] > date2[ this.position.year ] )
{
return this.status.larger;
}
if ( date1[ this.position.year ] < date2[ this.position.year ] )
{
return this.status.less;
}
if ( date1[ this.position.year ] = date2[ this.position.year ] )
{
// сравнение дат по месяцам:
if ( date1[ this.position.month ] > date2[ this.position.month ] )
{
return this.status.larger;
}
if ( date1[ this.position.month ] < date2[ this.position.month ] )
{
return this.status.less;
}
if ( date1[ this.position.month ] = date2[ this.position.month ] )
{
// сравнение дат по дням:
if ( date1[ this.position.day ] > date2[ this.position.day ] )
{
return this.status.larger;
}
if ( date1[ this.position.day ] < date2[ this.position.day ] )
{
return this.status.less;
}
if ( date1[ this.position.day ] = date2[ this.position.day ] )
{
return this.status.equal;
}
}
}
}
// при отрицательном результате проверки формата на валидность
else
{
return false;
}
},
setFormat : function( format ) // сохранение формата
{
this.format = format;
},
checkFormat : function() // проверка заданного формата на валидность дольнейшего использования
{
// проверка формата по шаблону
var checkResult = this.formatPattern.exec( this.format );
// положительная проверка
if ( checkResult != null )
{
// распределение индексов формата по порядку сравнения частей дат (год, месяц, день)
for ( var index in checkResult )
{
// по годам
if ( checkResult[index] == 'yy' || checkResult[index] == 'yyyy' )
{
this.position.year = this.formatAssoc[index];
}
// по месяцам
if ( checkResult[index] == 'mm' )
{
this.position.month = this.formatAssoc[index];
}
// по дням
if ( checkResult[index] == 'dd' )
{
this.position.day = this.formatAssoc[index];
}
}
// установка разделителя для частей дат
this.separator = checkResult[2];
// сброс ресурса
delete checkResult;
// сброс внутреннего индекса шаблона проверки
this.formatPattern.lastIndex = 0;
return true;
}
// отрицательная проверка
else
{
return false;
}
}
};
Обратите на одну особенность в проверке формата по шаблону в методе checkFormat :
var checkResult = this.formatPattern.exec( this.format );
Каждый второй вызов данного метода будет приводить к неоднозначности и связано это будет со спецификой поиска совпадений: будет возвращаться null. Этого в нашем случае не требуется, чтобы этого избежать введен сброс внутреннего индекса шаблона проверки ():
this.formatPattern.lastIndex = 0;
Желаю Всем удачи в нашем нелегком деле :)