Exemple #1
0
static void testMonthParsing() {
    const char *months[] = {
        "Jan/", "Feb/", "Mar/", "Apr/", "May/", "Jun/",
        "Jul/", "Aug/", "Sep/", "Oct/", "Nov/", "Dec/"
    };
    for(int i=0; i<12; i++) {
        for(int j=0; j<10; j++) {
            int rv=parseMonth(months[i]);
            if(i != rv) {
                std::cerr << "Expected " << i << " for "
                          << months[i] << " got " << rv << std::endl;
                abort();
            }
        }
    }
    for(int j=0; j<10; j++) {
        for(int i=0; i<12; i++) {
            int rv=parseMonth(months[i]);
            if(i != rv) {
                std::cerr << "Expected " << i << " for "
                          << months[i] << " got " << rv << std::endl;
                abort();
            }
        }
    }
}
const char* parseTime(const char* start, const char* const end, unsigned& t)
{
    t = 0;
    tm tm;
    auto comma = std::find(start, end, ',');
    if (comma != end) {
        start = comma + 1;
        auto hyphen = std::find(start, end, '-');
        if (hyphen != end) {
            // RFC 850:  Weekday, 00-Mon-00 00:00:00 GMT
            start = parseDigits(start, end, tm.tm_mday);
            start = parseMonth(++start, end, tm.tm_mon);
            start = parseDigits(++start, end, tm.tm_year);
            start = parseDigits(start, end, tm.tm_hour);
            start = parseDigits(++start, end, tm.tm_min);
            start = parseDigits(++start, end, tm.tm_sec);
            if (tm.tm_year < 70)
                tm.tm_year += 100;
        } else {
            // RFC 1123: Wkd, 00 Mon 0000 00:00:00 GMT
            start = parseDigits(start, end, tm.tm_mday);
            start = parseMonth(start, end, tm.tm_mon);
            start = parseDigits(start, end, tm.tm_year);
            tm.tm_year -= 1900;
            start = parseDigits(start, end, tm.tm_hour);
            start = parseDigits(++start, end, tm.tm_min);
            start = parseDigits(++start, end, tm.tm_sec);
        }
    } else {
        // asctime: Wkd Mon 00 00:00:00 0000 GMT
        start = skipSpace(start, end);
        start = std::find(start, end, ' ');
        if (start == end)
            return end;
        start = parseMonth(start, end, tm.tm_mon);
        start = parseDigits(start, end, tm.tm_mday);
        start = parseDigits(start, end, tm.tm_hour);
        start = parseDigits(++start, end, tm.tm_min);
        start = parseDigits(++start, end, tm.tm_sec);
        start = parseDigits(start, end, tm.tm_year);
        tm.tm_year -= 1900;
    }
    if (tm.tm_sec < 0 || 59 < tm.tm_sec ||
        tm.tm_min < 0 || 59 < tm.tm_min ||
        tm.tm_hour < 0 || 23 < tm.tm_hour ||
        tm.tm_mday < 1 || 31 < tm.tm_mday  ||
        tm.tm_mon < 0 || 11 < tm.tm_mon ||
        tm.tm_year < 70 || 120 < tm.tm_year) {
        return start;
    }
    t = timegm(&tm);
    return start;
}
CommandBase* ParserList::makeCmdListSpecificMonth(string monthStr) {
    int parsedMonth;
    // Parse month, if month is valid
    try {
        parsedMonth = parseMonth(monthStr);
    } catch (invalid_argument) {
        return NULL;
    }

    // Ensure that the month is the coming month, and not a month which
    // has already passed
    date currentDate = second_clock::local_time().date();
    date startDate = date(currentDate.year(), parsedMonth, 1);
    if (currentDate.month() > parsedMonth) {
        startDate += years(1);
    }

    ptime startTime = ptime(startDate);
    ptime endTime = getLastOfMonth(startTime);
    return makeCmdListPeriod(startTime, endTime);
}
bool DateComponents::parseDate(const String& src, unsigned start, unsigned& end)
{
    unsigned index;
    if (!parseMonth(src, start, index))
        return false;
    // '-' and 2-digits are needed.
    if (index + 2 >= src.length())
        return false;
    if (src[index] != '-')
        return false;
    ++index;

    int day;
    if (!toInt(src, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
        return false;
    if (!withinHTMLDateLimits(m_year, m_month, day))
        return false;
    m_monthDay = day;
    end = index + 2;
    m_type = Date;
    return true;
}
Exemple #5
0
void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential)
{
    int year   = 0;
    int month  = 0;
    int day    = 0;
    int hour   = 0;
    int minute = 0;
    int second = 0;
    int millis = 0;
    int micros = 0;
    int tzd    = 0;

    std::string::const_iterator it   = str.begin();
    std::string::const_iterator end  = str.end();
    std::string::const_iterator itf  = fmt.begin();
    std::string::const_iterator endf = fmt.end();

    while (itf != endf && it != end)
    {
        if (*itf == '%')
        {
            if (++itf != endf)
            {
                switch (*itf)
                {
                case 'w':
                case 'W':
                    while (it != end && std::isspace(*it)) ++it;
                    while (it != end && std::isalpha(*it)) ++it;
                    break;
                case 'b':
                case 'B':
                    month = parseMonth(it, end);
                    break;
                case 'd':
                case 'e':
                case 'f':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(day, 2);
                    break;
                case 'm':
                case 'n':
                case 'o':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(month, 2);
                    break;
                case 'y':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(year, 2);
                    if (year >= 70)
                        year += 1900;
                    else
                        year += 2000;
                    break;
                case 'Y':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(year, 4);
                    break;
                case 'H':
                case 'h':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(hour, 2);
                    break;
                case 'a':
                case 'A':
                    hour = parseAMPM(it, end, hour);
                    break;
                case 'M':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(minute, 2);
                    break;
                case 'S':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(second, 2);
                    break;
                case 'i':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(millis, 3);
                    break;
                case 'c':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(millis, 1);
                    millis *= 100;
                    break;
                case 'F':
                    SKIP_JUNK();
                    PARSE_NUMBER_N(millis, 3);
                    PARSE_NUMBER_N(micros, 3);
                    break;
                case 'z':
                case 'Z':
                    tzd = parseTZD(it, end);
                    break;
                }
                ++itf;
            }
        }
        else ++itf;
    }
    if (month == 0) month = 1;
    if (day == 0) day = 1;
    if (DateTime::isValid(year, month, day, hour, minute, second, millis, micros))
        dateTime.assign(year, month, day, hour, minute, second, millis, micros);
    else
        throw SyntaxException("date/time component out of range");
    timeZoneDifferential = tzd;
}
Exemple #6
0
time_t LogFile::parseTimestamp()
{
    const char *p;

    assert(!line.empty());

    timestamp=-1;

    p=line.c_str();

    try {

        /* The shortest line I can parse is about 32 characters. */
        if(line.length() < 32) {
            /* This is a broken entry */
            fprintf(stderr, "Broken log entry (too short):  %s\n", p);
        } else if(index(p, '[') != NULL) {
            struct tm tm;
            memset(&tm, 0x00, sizeof(tm));

            p=index(p, '[');
            /* Input validation */
            if(p == NULL || line.length() < 32) {
                std::cerr << "Invalid log line:  " << line << std::endl;
                throw BadTimestamp();
            }

            /* fprintf(stderr, "**** Parsing %s\n", p); */
            p++;
            tm.tm_mday=atoi(p);
            p+=3;
            tm.tm_mon=parseMonth(p);
            p+=4;
            tm.tm_year=atoi(p);
            p+=5;
            tm.tm_hour=atoi(p);
            p+=3;
            tm.tm_min=atoi(p);
            p+=3;
            tm.tm_sec=atoi(p);

            /* Make sure it still looks like CLF */
            if(p[2] != ' ') {
                std::cerr << "log line is starting to not look like CLF: "
                          << line
                          << std::endl;
                throw BadTimestamp();
            }

            tm.tm_year-=1900;

            /* Let mktime guess the timezone */
            tm.tm_isdst=-1;

            timestamp=mktime(&tm);

        } else {
            fprintf(stderr, "Unknown log format:  %s\n", p);
        }

    } catch(BadTimestamp e) {
        // Damn.
    }

    if(timestamp < 0) {
        std::cerr << "* Error parsing timestamp from " << line << std::endl;
    }

    return(timestamp);
}