00001
00002
00003
00004
00005
00006
00007 #include "EngaugeAssert.h"
00008 #include "FormatDateTime.h"
00009 #include "Logger.h"
00010
00011 FormatDateTime::FormatDateTime()
00012 {
00013 loadFormatsFormat();
00014 loadFormatsParseAcceptable();
00015 loadFormatsParseIncomplete();
00016 }
00017
00018 bool FormatDateTime::ambiguityBetweenDateAndTime (CoordUnitsDate coordUnitsDate,
00019 CoordUnitsTime coordUnitsTime,
00020 const QString &string) const
00021 {
00022 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::ambiguityBetweenDateAndTime";
00023
00024 bool ambiguous = false;
00025
00026
00027 if (coordUnitsDate != COORD_UNITS_DATE_SKIP &&
00028 coordUnitsTime != COORD_UNITS_TIME_SKIP) {
00029
00030
00031 QStringList fields = string.trimmed().split(QRegExp ("[/- :]"));
00032
00033 if (fields.count() == 1) {
00034
00035
00036
00037 ambiguous = true;
00038 }
00039 }
00040
00041 return ambiguous;
00042 }
00043
00044 void FormatDateTime::dateTimeLookup (const FormatsDate &formatsDateAll,
00045 const FormatsTime &formatsTimeAll,
00046 CoordUnitsDate coordUnitsDate,
00047 CoordUnitsTime coordUnitsTime,
00048 const QString &string,
00049 bool useQDateTimeElseQRegExp,
00050 double &value,
00051 bool &success) const
00052 {
00053 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::dateTimeLookup";
00054
00055 success = false;
00056
00057 ENGAUGE_ASSERT (formatsDateAll.contains (coordUnitsDate));
00058 ENGAUGE_ASSERT (formatsTimeAll.contains (coordUnitsTime));
00059
00060 QStringList formatsDate = formatsDateAll [coordUnitsDate];
00061 QStringList formatsTime = formatsTimeAll [coordUnitsTime];
00062
00063
00064 QStringList::const_iterator itrDate, itrTime;
00065 bool iterating = true;
00066 for (itrDate = formatsDate.begin(); itrDate != formatsDate.end() && iterating; itrDate++) {
00067
00068 QString formatDate = *itrDate;
00069
00070 for (itrTime = formatsTime.begin(); itrTime != formatsTime.end() && iterating; itrTime++) {
00071
00072 QString formatTime = *itrTime;
00073
00074
00075 QString separator = (!formatDate.isEmpty() && !formatTime.isEmpty() ? " " : "");
00076
00077 QString formatDateTime = formatDate + separator + formatTime;
00078
00079 if (!formatDateTime.isEmpty()) {
00080
00081
00082 if (useQDateTimeElseQRegExp) {
00083
00084 QDateTime dt = QDateTime::fromString (string,
00085 formatDateTime);
00086
00087 if (dt.isValid() && !ambiguityBetweenDateAndTime (coordUnitsDate,
00088 coordUnitsTime,
00089 string)) {
00090
00091 success = true;
00092 value = dt.toTime_t();
00093 iterating = false;
00094
00095 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::dateTimeLookup"
00096 << " string=" << string.toLatin1().data()
00097 << " qDateTimeFormatMatched=" << formatDateTime.toLatin1().data()
00098 << " value=" << value
00099 << " stringQDateTime=" << dt.toString().toLatin1().data();
00100
00101 }
00102 } else {
00103
00104 QRegExp reg (formatDateTime);
00105 if (reg.exactMatch(string)) {
00106
00107 success = true;
00108 iterating = false;
00109
00110 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::dateTimeLookup"
00111 << " string=" << string.toLatin1().data()
00112 << " regExpMatched=" << formatDateTime.toLatin1().data();
00113
00114 }
00115 }
00116 }
00117 }
00118 }
00119 }
00120
00121 QString FormatDateTime::formatOutput (CoordUnitsDate coordUnitsDate,
00122 CoordUnitsTime coordUnitsTime,
00123 double value) const
00124 {
00125 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::formatOutput"
00126 << " value=" << value;
00127
00128 ENGAUGE_ASSERT (m_formatsDateFormat.contains (coordUnitsDate));
00129 ENGAUGE_ASSERT (m_formatsTimeFormat.contains (coordUnitsTime));
00130
00131 QString format = m_formatsDateFormat [coordUnitsDate] + " " + m_formatsTimeFormat [coordUnitsTime];
00132 format = format.trimmed();
00133
00134 QDateTime dt = QDateTime::fromTime_t (value);
00135
00136 return dt.toString (format);
00137 }
00138
00139 void FormatDateTime::loadFormatsFormat()
00140 {
00141 m_formatsDateFormat [COORD_UNITS_DATE_SKIP] = "";
00142 m_formatsDateFormat [COORD_UNITS_DATE_MONTH_DAY_YEAR] = "MM/dd/yyyy";
00143 m_formatsDateFormat [COORD_UNITS_DATE_DAY_MONTH_YEAR] = "dd/MM/yyyy";
00144 m_formatsDateFormat [COORD_UNITS_DATE_YEAR_MONTH_DAY] = "yyyy/MM/dd";
00145
00146 ENGAUGE_ASSERT (m_formatsDateFormat.count () == NUM_COORD_UNITS_DATE);
00147
00148 m_formatsTimeFormat [COORD_UNITS_TIME_SKIP] = "";
00149 m_formatsTimeFormat [COORD_UNITS_TIME_HOUR_MINUTE] = "hh/mm";
00150 m_formatsTimeFormat [COORD_UNITS_TIME_HOUR_MINUTE_SECOND] = "hh:mm:ss";
00151
00152 ENGAUGE_ASSERT (m_formatsTimeFormat.count () == NUM_COORD_UNITS_TIME);
00153 }
00154
00155 void FormatDateTime::loadFormatsParseAcceptable()
00156 {
00157 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::loadFormatsParseAcceptable";
00158
00159 QStringList skip, dayMonth, dayMonthYear, monthDay, monthDayYear, yearMonth, yearMonthDay;
00160
00161
00162
00163 skip << "";
00164
00165 dayMonth << "d/M"
00166 << "d-M"
00167 << "d/MM"
00168 << "d-MM"
00169 << "d/MMM"
00170 << "d-MMM"
00171 << "d/MMMM"
00172 << "d-MMMM"
00173 << "dd/M"
00174 << "dd-M"
00175 << "dd/M"
00176 << "dd-M"
00177 << "dd/MM"
00178 << "dd-MM"
00179 << "dd/MMM"
00180 << "dd-MMM"
00181 << "dd/MMMM"
00182 << "dd-MMMM";
00183 dayMonthYear << "d/M/yyyy"
00184 << "d-M-yyyy"
00185
00186 << "d/MM/yyyy"
00187 << "d-MM-yyyy"
00188 << "d/MMM/yyyy"
00189 << "d-MMM-yyyy"
00190 << "d MMM yyyy"
00191 << "d/MMMM/yyyy"
00192 << "d-MMMM-yyyy"
00193 << "d MMMM yyyy"
00194
00195 << "dd/MM/yyyy"
00196 << "dd-MM-yyyy"
00197 << "dd/MMM/yyyy"
00198 << "dd-MMM-yyyy"
00199 << "dd MMM yyyy"
00200 << "dd/MMMM/yyyy"
00201 << "dd-MMMM-yyyy"
00202 << "dd MMMM yyyy";
00203 monthDay << "M/d"
00204 << "M-d"
00205 << "M d"
00206 << "M/dd"
00207 << "M-dd"
00208 << "M dd"
00209 << "MM/d"
00210 << "MM-d"
00211 << "MM d"
00212 << "MM/dd"
00213 << "MM-dd"
00214 << "MM dd"
00215 << "MMM/d"
00216 << "MMM-d"
00217 << "MMM d"
00218 << "MMM/dd"
00219 << "MMM-dd"
00220 << "MMM dd"
00221 << "MMMM/d"
00222 << "MMMM-d"
00223 << "MMMM d"
00224 << "MMMM/dd"
00225 << "MMMM-dd"
00226 << "MMMM dd";
00227 monthDayYear << "M/d/yyyy"
00228 << "M-d-yyyy"
00229 << "M d yyyy"
00230 << "M/dd/yyyy"
00231 << "M-dd-yyyy"
00232 << "M dd yyyy"
00233 << "MM/d/yyyy"
00234 << "MM-d-yyyy"
00235 << "MM d yyyy"
00236 << "MM/dd/yyyy"
00237 << "MM-dd-yyyy"
00238 << "MM dd yyyy"
00239 << "MMM/d/yyyy"
00240 << "MMM-d-yyyy"
00241 << "MMM d yyyy"
00242 << "MMM/dd/yyyy"
00243 << "MMM-dd-yyyy"
00244 << "MMM dd yyyy"
00245 << "MMMM/d/yyyy"
00246 << "MMMM-d-yyyy"
00247 << "MMMM d"
00248 << "MMMM/dd"
00249 << "MMMM-dd"
00250 << "MMMM dd";
00251 yearMonth << "yyyy/M"
00252 << "yyyy-M"
00253 << "yyyy M"
00254 << "yyyy/MM"
00255 << "yyyy-MM"
00256 << "yyyy MM"
00257 << "yyyy/MMM"
00258 << "yyyy-MMM"
00259 << "yyyy MMM"
00260 << "yyyy/MMMM"
00261 << "yyyy-MMMM"
00262 << "yyyy MMMM";
00263 yearMonthDay << "yyyy/M/d"
00264 << "yyyy-M-d"
00265 << "yyyy M d"
00266 << "yyyy/M/dd"
00267 << "yyyy-M-dd"
00268 << "yyyy M dd"
00269 << "yyyy/MM/dd"
00270 << "yyyy-MM-dd"
00271 << "yyyy MM dd"
00272 << "yyyy/MMM/d"
00273 << "yyyy-MMM-d"
00274 << "yyyy MMM d"
00275 << "yyyy/MMM/dd"
00276 << "yyyy-MMM-dd"
00277 << "yyyy MMM dd"
00278 << "yyyy/MMMM/dd"
00279 << "yyyy-MMMM-dd"
00280 << "yyyy MMMM dd";
00281
00282
00283 m_formatsDateParseAcceptable [COORD_UNITS_DATE_SKIP] = skip + monthDay + monthDayYear + yearMonthDay;
00284 m_formatsDateParseAcceptable [COORD_UNITS_DATE_MONTH_DAY_YEAR] = skip + monthDay + monthDayYear + yearMonthDay;
00285 m_formatsDateParseAcceptable [COORD_UNITS_DATE_DAY_MONTH_YEAR] = skip + dayMonth + dayMonthYear + yearMonthDay;
00286 m_formatsDateParseAcceptable [COORD_UNITS_DATE_YEAR_MONTH_DAY] = skip + yearMonth + yearMonthDay;
00287
00288 ENGAUGE_ASSERT (m_formatsDateParseAcceptable.count () == NUM_COORD_UNITS_DATE);
00289
00290 QStringList hour, hourMinute, hourMinuteSecond, hourMinutePm, hourMinuteSecondPm;
00291
00292 hour << "hh";
00293 hourMinute << "hh:mm";
00294 hourMinuteSecond << "hh:mm:ss";
00295 hourMinutePm << "hh:mmA"
00296 << "hh:mm A"
00297 << "hh:mma"
00298 << "hh:mm a";
00299 hourMinuteSecondPm << "hh:mm:ssA"
00300 << "hh:mm:ss A"
00301 << "hh:mm:ssa"
00302 << "hh:mm:ss a";
00303
00304 m_formatsTimeParseAcceptable [COORD_UNITS_TIME_SKIP] = skip + hour + hourMinute + hourMinuteSecond + hourMinutePm + hourMinuteSecondPm;
00305 m_formatsTimeParseAcceptable [COORD_UNITS_TIME_HOUR_MINUTE] = skip + hour + hourMinute + hourMinutePm + hourMinuteSecond + hourMinuteSecondPm;
00306 m_formatsTimeParseAcceptable [COORD_UNITS_TIME_HOUR_MINUTE_SECOND] = skip + hour + hourMinute + hourMinutePm + hourMinuteSecond + hourMinuteSecondPm;
00307
00308 ENGAUGE_ASSERT (m_formatsTimeParseAcceptable.count () == NUM_COORD_UNITS_TIME);
00309 }
00310
00311 void FormatDateTime::loadFormatsParseIncomplete()
00312 {
00313 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::loadFormatsParseIncomplete";
00314
00315 QStringList skip, day, dayMonth, month, monthDay, monthDayYear, year, yearMonth, yearMonthDay;
00316
00317
00318
00319 skip << "";
00320
00321
00322
00323 day << "\\d{1,2}"
00324 << "\\d{1,2}/"
00325 << "\\d{1,2}-";
00326 dayMonth << "\\d{1,2}/\\d{1,2}"
00327 << "\\d{1,2}/\\d{1,2} "
00328 << "\\d{1,2}/\\d{1,2}/"
00329 << "\\d{1,2}-\\d{1,2}-"
00330 << "\\d{1,2}/[a-zA-Z]{1,12}/"
00331 << "\\d{1,2}-[a-zA-Z]{1,12}-"
00332 << "\\d{1,2} [a-zA-Z]{1,12} ";
00333 month << "\\d{1,2}"
00334 << "\\d{1,2}/"
00335 << "[a-zA-Z]{1,12}"
00336 << "[a-zA-Z]{1,12} ";
00337 monthDay << "\\d{1,2}/\\d{1,2}"
00338 << "\\d{1,2}/\\d{1,2} "
00339 << "\\d{1,2}/\\d{1,2}/"
00340 << "\\d{1,2} \\d{1,2}"
00341 << "\\d{1,2} \\d{1,2} "
00342 << "\\d{1,2}-\\d{1,2}-"
00343 << "[a-zA-Z]{1,12}"
00344 << "[a-zA-Z]{1,12} "
00345 << "[a-zA-Z]{1,12} \\d{1,2}"
00346 << "[a-zA-Z]{1,12} \\d{1,2} ";
00347 monthDayYear << "\\d{1,2}/\\d{1,2}/\\d{1,4}"
00348 << "\\d{1,2}/\\d{1,2}/\\d{1,4} "
00349 << "\\d{1,2}-\\d{1,2}-\\d{1,4}"
00350 << "\\d{1,2}-\\d{1,2}-\\d{1,4} "
00351 << "\\d{1,2} \\d{1,2} \\d{1,4}"
00352 << "\\d{1,2} \\d{1,2} \\d{1,4} ";
00353 year << "\\d{1,4}"
00354 << "\\d{1,4} "
00355 << "\\d{1,4}/"
00356 << "\\d{1,4}-";
00357 yearMonth << "\\d{4}/\\d{1,2}"
00358 << "\\d{4}/\\d{1,2} "
00359 << "\\d{4}/\\d{1,2}/"
00360 << "\\d{4}-\\d{1,2}"
00361 << "\\d{4}-\\d{1,2} "
00362 << "\\d{4}-\\d{1,2}-"
00363 << "\\d{4} \\d{1,2}"
00364 << "\\d{4} \\d{1,2} "
00365 << "\\d{4}/[a-zA-Z]{1,12}"
00366 << "\\d{4}/[a-zA-Z]{1,12} "
00367 << "\\d{4}/[a-zA-Z]{1,12}/"
00368 << "\\d{4}-[a-zA-Z]{1,12}"
00369 << "\\d{4}-[a-zA-Z]{1,12} "
00370 << "\\d{4}-[a-zA-Z]{1,12}-"
00371 << "\\d{4} [a-zA-Z]{1,12}"
00372 << "\\d{4} [a-zA-Z]{1,12} ";
00373 yearMonthDay << "\\d{4}/\\d{1,2}/\\d{1,2}"
00374 << "\\d{4}/\\d{1,2}-\\d{1,2}"
00375 << "\\d{4} \\d{1,2} \\d{1,2}"
00376 << "\\d{4}/[a-zA-Z]{1,12}/\\d{1,2}"
00377 << "\\d{4}-[a-zA-Z]{1,12}-\\d{1,2}";
00378
00379
00380
00381 m_formatsDateParseIncomplete [COORD_UNITS_DATE_SKIP] = skip + month + monthDay + monthDayYear + year + yearMonth + yearMonthDay;
00382 m_formatsDateParseIncomplete [COORD_UNITS_DATE_MONTH_DAY_YEAR] = skip + month + monthDay + monthDayYear + year + yearMonth + yearMonthDay;
00383 m_formatsDateParseIncomplete [COORD_UNITS_DATE_DAY_MONTH_YEAR] = skip + day + dayMonth + year + yearMonth + yearMonthDay;
00384 m_formatsDateParseIncomplete [COORD_UNITS_DATE_YEAR_MONTH_DAY] = skip + year + yearMonth + yearMonthDay;
00385
00386 ENGAUGE_ASSERT (m_formatsDateParseIncomplete.count () == NUM_COORD_UNITS_DATE);
00387
00388 QStringList hour, hourMinute, hourMinuteAmPm, hourMinuteSecond, hourMinuteSecondAmPm;
00389
00390 hour << "\\d{1,2}"
00391 << "\\d{1,2}:";
00392 hourMinute << "\\d{1,2}:\\d{1,2}"
00393 << "\\d{1,2}:\\d{1,2}:"
00394 << "\\d{1,2}:\\d{1,2} ";
00395 hourMinuteAmPm << "\\d{1,2}:\\d{1,2} [aApP]";
00396 hourMinuteSecond << "\\d{1,2}:\\d{1,2}:\\d{1,2}"
00397 << "\\d{1,2}:\\d{1,2}:\\d{1,2} ";
00398 hourMinuteSecondAmPm << "\\d{1,2}:\\d{1,2}:\\d{1,2} [aApP]";
00399
00400
00401 m_formatsTimeParseIncomplete [COORD_UNITS_TIME_SKIP] = skip +
00402 hour +
00403 hourMinute + hourMinuteAmPm +
00404 hourMinuteSecond + hourMinuteSecondAmPm;
00405 m_formatsTimeParseIncomplete [COORD_UNITS_TIME_HOUR_MINUTE] = skip +
00406 hour +
00407 hourMinute + hourMinuteAmPm +
00408 hourMinuteSecond + hourMinuteSecondAmPm;
00409 m_formatsTimeParseIncomplete [COORD_UNITS_TIME_HOUR_MINUTE_SECOND] = skip +
00410 hour +
00411 hourMinute + hourMinuteAmPm +
00412 hourMinuteSecond + hourMinuteSecondAmPm;
00413
00414 ENGAUGE_ASSERT (m_formatsTimeParseIncomplete.count () == NUM_COORD_UNITS_TIME);
00415 }
00416
00417 QValidator::State FormatDateTime::parseInput (CoordUnitsDate coordUnitsDate,
00418 CoordUnitsTime coordUnitsTime,
00419 const QString &stringUntrimmed,
00420 double &value) const
00421 {
00422 LOG4CPP_INFO_S ((*mainCat)) << "FormatDateTime::parseInput"
00423 << " date=" << coordUnitsDateToString (coordUnitsDate).toLatin1().data()
00424 << " time=" << coordUnitsTimeToString (coordUnitsTime).toLatin1().data()
00425 << " string=" << stringUntrimmed.toLatin1().data();
00426
00427 const bool USE_QREGEXP = true, DO_NOT_USE_QREGEXP = false;
00428
00429 const QString string = stringUntrimmed.trimmed();
00430
00431 QValidator::State state;
00432 if (string.isEmpty()) {
00433
00434 state = QValidator::Intermediate;
00435
00436 } else {
00437
00438 state = QValidator::Invalid;
00439
00440
00441 bool success = false;
00442 dateTimeLookup (m_formatsDateParseAcceptable,
00443 m_formatsTimeParseAcceptable,
00444 coordUnitsDate,
00445 coordUnitsTime,
00446 string,
00447 USE_QREGEXP,
00448 value,
00449 success);
00450 if (success) {
00451
00452 state = QValidator::Acceptable;
00453
00454 } else {
00455
00456
00457 dateTimeLookup (m_formatsDateParseIncomplete,
00458 m_formatsTimeParseIncomplete,
00459 coordUnitsDate,
00460 coordUnitsTime,
00461 string,
00462 DO_NOT_USE_QREGEXP,
00463 value,
00464 success);
00465 if (success) {
00466
00467 state = QValidator::Intermediate;
00468
00469 }
00470 }
00471 }
00472
00473 return state;
00474 }