|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - TDateTime - Операции с временем [вычитание, сложение] |
|
C/C++ - TDateTime - Операции с временем [вычитание, сложение]
|
Будем жить, Маэстро... Сообщения: 6694 |
Приветствую всех.
![]() Друзья, понадобилась ваша помощь, самостоятельно решить не могу, вернее, только частично. Пишу парсер логов AVZ. В программу добавил функцию поиска файлов, созданых в определённый промежуток времени - 30 дней с момента создания лога AVZ. В логе AVZ эта строка означает дату сканирования Переменная DataScan в ней хранится уже извлечённая дата В таком же формате времени записаны даты создания файлов. Переменная AnsiString str хранит передаваемую дату создания файла. Задача: Как правильно вычесть одну дату из другой? Если в логах AVZ формат даты может быть разным: 7/17/2010 10:33:29 PM - Месяц/День/Год - M/D/YYYY 20.03.2010 19:14:48 - День.Месяц.Год - DD.MM.YYYY 19.Jul.2010 19:14:48 - День.Месяц.Год 20.03.2010 19:14:48 - День-Месяц-Год - DD-MM-YYYY С последним форматом проблем нет, также можно заменить разделитель /, - на точку. Друг помог с форматом 19.Jul.2010 19:14:48 Функция SearchCreateToNMounth принимает два аргумента: 1-й дату, 2-й полное имя файла. Ошибку выдаёт такую ![]() Про операции проводимые с временем читал здесь и здесь Что я не так делаю? Если не трудно, подскажите как можно это сделать правильно? Спасибо. |
|
------- Отправлено: 14:55, 19-07-2010 |
![]() Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Можно сделать угадывалку (по типу угадывалки кодировки в Total Commander) примерно так:
#include <vector> using namespace std; class GuessDateFormat { public: enum state_t { state_ready, // угадал state_not_enough, // есть неоднозначности, не хватает примеров state_umbiguity // противоречивые примеры }; GuessDateFormat(); void add_sample(const char* date_str); state_t state() const; bool convert(const char* from, time_t& to); private: enum { like_nothing = 0x0000, // битовые поля "похоже на..." like_year = 0x0001, like_mon = 0x0002, like_mday = 0x0004, like_wday = 0x0008, like_hour = 0x0010, like_min = 0x0020, like_sec = 0x0040, like_pm = 0x0080, // pm/am like_amon = 0x0100, // месяц прописью like_date = like_year|like_mon|like_mday|like_amon, like_time = like_hour|like_min|like_sec, like_alpha = like_amon|like_pm, like_everything = 0x01ff, got_pm = 0x01, got_year2000 = 0x02, got_amon = 0x04 }; vector<short> _like_what; // каждый элемент показывает, на что похоже содержимое позиции short _its_clear, _expecting; // какие элементы точно выяснены void _suspecting_one(int); void _suspecting_pair(int); }; bool GuessDateFormat::convert(const char* from, time_t& to) { typedef struct tm tm_t; tm_t tm1 = {}; vector<short>::iterator first=_like_what.begin(), last=_like_what.end(); while ( *from && first!=last) { // найти первый подходящий символ while (!isalnum(*from) && *++from) {} if (*from) { switch ( *first) { case like_year : tm1.tm_year = atoi(from); break; case like_mon : tm1.tm_mday = atoi(from)-1; break; case like_mday : tm1.tm_mday = atoi(from); break; case like_hour : tm1.tm_hour = atoi(from); break; case like_min : tm1.tm_min = atoi(from); break; case like_sec : tm1.tm_sec = atoi(from); break; case like_pm : // думаем что PM после времени пишется. if (*from=='P') tm1.tm_hour += 12; break; case like_amon : // выбрать месяц из справочника break; } } while (isalnum(*from) && *++from) {} } to = mktime(&tm1); return true; } GuessDateFormat::state_t GuessDateFormat::state() const { for (vector<short>::iterator first=_like_what.begin(), last=_like_what.end(); first!=last; ++first) { short n = *first; if (!n) return state_umbiguity; while ( !(n & 1)) n>>=1; if (n & (~1)) return state_not_enough; } return state_ready; } void GuessDateFormat::_suspecting_one(int bitset) { _like_what.push_back(bitset & _expecting); _expecting = like_everything; } void GuessDateFormat::_suspecting_pair(int bitset) { if (!_like_what.empty()) *(_like_what.end()-1) &= bitset; _expecting = bitset; } bool GuessDateFormat::add_sample(const char* date_str) { // отмели простейший случай if (!date_str || !*date_str) return false; _expecting = like_everything; _its_clear = 0; do { short suspecting = _expecting; // пропустили пробелы while (*date_str && isspace(*date_str)) ++date_str; if ( !*date_str) break; if (isalpha(*date_str)) { suspecting &= like_alpha; if (date_str[1]=='M' && (date_str[0]=='A' || date_str[0]=='P')) { suspecting &= like_pm; _its_clear |= got_pm; } else { suspecting &= ~like_pm; _its_clear |= got_amon; } _suspecting_one(suspecting); } else if (isdigit(*date_str)) { suspecting &= ~like_alpha; // проверяем границы int value = atoi(date_str); do {++date_str;} while (*date_str && isdigit(*date_str)); if (12 < value) { suspecting &= ~like_mon; if (_its_clear & got_am) suspecting &= ~like_hour; if (23 < value) { suspecting &= ~like_hour; if (31 < value) { suspecting &= ~(like_mon|like_mday); if (59 < value) { suspecting &= like_year; _its_clear |= got_year2000; } } } } if ( (_its_clear & got_year2000) && value < 60) { suspecting &= ~like_year; } if (_its_clear & got_amon) { suspecting &= ~like_mon; } _suspecting_one(suspecting); } else { switch (*date_str) { case '/' : case '.' : case '-' : _suspecting_pair(like_date); break; case ':' : _suspecting_pair(like_time); break; } } } while (*date_str); } //---------------------------------------- 1) создали GuessDateFormat guess_format; 2) скидали в него все даты, какие есть for(...) guess_format.add_sample(date[n].c_str()); 3) проверили, угадался ли формат if (guess_format.state()==GuessDateFormat::state_ready) 4) переводим даты time_t t1; for(...) guess_format.convert(date[n].c_str(), t1); чего в коде нет: 1) таблицы соответсвия месяц-номер месяца (на всех языках, со всеми сокращениями) 2) не может отличить минуты от секунд. Чтобы это обойти, надо внутри добавить код: пробежаться по вектору с подозрениями и если встретится элемент времени, то последовательно обозначить час, минута, секунда. |
Отправлено: 20:35, 20-07-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Будем жить, Маэстро... Сообщения: 6694
|
Профиль | Сайт | Отправить PM | Цитировать pva, Код конечно шикарный, осталось в нём разобраться.
![]() ![]() |
------- Отправлено: 22:06, 20-07-2010 | #3 |
![]() Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать вот, правда сделано на билдере 4 (у билдера 6 есть проблема с линковкой имён с подчёркиваниями)
|
Последний раз редактировалось pva, 25-02-2012 в 11:59. Отправлено: 22:28, 21-07-2010 | #4 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Assm - Сложение двух чисел | Rebel666 | Программирование и базы данных | 8 | 22-04-2012 17:30 | |
Проблема со временем | PLATON | Непонятные проблемы с Железом | 2 | 20-04-2008 15:35 | |
Delphi - Вычитание дат на Delphi | d_voffka | Программирование и базы данных | 2 | 05-06-2006 11:53 | |
Сложение строк на PHP | Vlad Drakula | Вебмастеру | 1 | 08-06-2003 21:30 |
|