
function validDateTime( date_input, format ) {

// - day and month might be 1 or 2 chars long
// - the separator must be the - sign
// - function checks the followings also:
//   (1000 <= year <= 9999, 1 <= month <=12, 1 <= days <= days_in_month
//
// - valid examples:    2002-01-2,  2002-1-1, 1951-12-31, 2000-02-29
// - invalid examples:  2002-02-29, 2000-0-1, 200-0-1,    2000-abc

  // create a validation regexp

  formatcompiled = '^' + format + '$' ;
  formatcompiled = formatcompiled.replace( 'YYYY', '([0-9]{4})' );
  formatcompiled = formatcompiled.replace( 'YY', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 'MM', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 'M', '([0-9]{1,2})' );
  formatcompiled = formatcompiled.replace( 'DD', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 'D', '([0-9]{1,2})' );
  formatcompiled = formatcompiled.replace( 'hh', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 'h', '([0-9]{1,2})' );
  formatcompiled = formatcompiled.replace( 'mm', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 'm', '([0-9]{1,2})' );
  formatcompiled = formatcompiled.replace( 'ss', '([0-9]{2})' );
  formatcompiled = formatcompiled.replace( 's', '([0-9]{1,2})' );
  regexp = new RegExp( formatcompiled );
  result = regexp.exec( date_input );

  if ( !result ) 
    // format itself failed
    return false;

  // if syntax is ok, the check the date
  // semantically

  // find element indexes and make a match with 
  // the regexp indexes

  indexes = Array(
    new Array( format.indexOf( 'YYYY' ), 'year' ),
    new Array( format.indexOf( 'M' ), 'month' ),
    new Array( format.indexOf( 'D' ), 'days' ),
    new Array( format.indexOf( 'h' ), 'hour' ),
    new Array( format.indexOf( 'm' ), 'min' ),
    new Array( format.indexOf( 's' ), 'sec' )
  );

  indexes.sort( indexcompare );

  regexindex = new Array();
  counter    = 1;

  for ( i in indexes )
    if ( indexes[ i ][ 0 ] != -1 ) {
      regexindex[ indexes[ i ][ 1 ] ] = counter;
      counter++;
    }

  // at last... we know the regexp-indexes of 
  // the date components (eg 'YYYY' is Regex.$1 )
  // and so on

  year  = result[ regexindex[ 'year'  ] ];
  month = result[ regexindex[ 'month' ] ];
  days  = result[ regexindex[ 'days'  ] ];
  hour  = result[ regexindex[ 'hour'  ] ];
  min   = result[ regexindex[ 'min'   ] ];
  sec   = result[ regexindex[ 'sec'   ] ];

  daysOfMonth = new Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
  if ( ( year != undefined ) && ( ( year % 4 ) == 0 ) )
    daysOfMonth[1] = 29;

  if ( 
       ( ( month != undefined ) && ( ( month <= 0 ) || ( month > 12 ) ) ) ||
       ( ( days != undefined )  && ( ( days <= 0 )  || ( days > 31 ) ) )  ||
       ( ( month && ( days > daysOfMonth [ month - 1 ] ) ) ) ||
       ( ( hour != undefined )  && ( ( hour < 0 )   || ( hour > 23 ) ) )  ||
       ( ( min != undefined )   && ( ( min < 0 )    || ( min > 59 ) ) )   ||
       ( ( sec != undefined )   && ( ( sec < 0 )    || ( sec > 59 ) ) )
     )
    return false;

  return true;

}

function indexcompare( item1, item2 ) {

  if ( item1[ 0 ] < item2[ 0 ] )
    return -1;

  if ( item1[ 0 ] > item2[ 0 ] )
    return 1;

  return 0;

}
