функция strtotime в C

1

Я пытаюсь сделать универсальную функцию на C, которая может преобразовать дату из любого файла журнала сервера в любом формате в метку времени, так как я хочу регистрировать, как часто потенциальные хакеры не смогли взломать сервер. В PHP я могу использовать strtotime, но я не думаю, что такая функциональность существует в C.

Если все файлы журналов использовали один и тот же формат времени в виде ГГГГ-ММ-ДД ЧЧ: ММ: СС, я мог бы уйти с кодом вроде этого:

//tmadd = 19 bytes as a char reserved for date/time plus trailing null
long result=0;
struct tm x;
if (sscanf(tmadd,"%i-%i-%i %i:%i:%i",&x.tm_year,&x.tm_mon,&x.tm_mday,&x.tm_hour,&x.tm_min,&x.tm_sec) >= 6){x.tm_year-=1900;result=mktime(&x);}

Проблема состоит в том, что некоторые журналы имеют месяцы в виде слов, и мне еще предстоит найти функцию для записи числового эквивалента.

Я хочу, чтобы иметь возможность делать все преобразования в рамках одной функции.

Есть ли простая функция, которую я могу использовать для получения необработанной метки времени с любой указанной даты в любом распространенном формате? Я в основном ищу способ свернуть свой собственный PHP strtotime().

  • 0
    POSIX имеет strptime() . POSIX не универсален, хотя.
  • 0
    @pmg: Просто любопытно: что будет универсальным? Я могу думать только о человеке, но у него могут быть и проблемы с кодировками пришельцев (да, тех, что указаны выше).
Показать ещё 3 комментария
Теги:
date
time
strtotime

1 ответ

1

Функция преобразования любого формата времени является очень амбициозным проектом, так как A смотрит на распознанные форматы даты для функции PHP strtotime.

Но если у вас есть несколько известных форматов временных меток, используемых на ваших серверах, вы можете проверить их отдельно:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

int strtomonth(int *mm, const char *str)
{
    static const char *sname[] = {
        "jan", "feb", "mar", "apr", "may", "jun",
        "jul", "aug", "sep", "oct", "nov", "dec",
        NULL
    };    
    int i;

    for (i = 0; sname[i]; i++) {
        if (strcmp(sname[i], str) == 0) {
            *mm = i + 1;
            return 1;
        }
    }

    return 0;
}

int strtotime(time_t *time, const char *s)
{
    struct tm tm;
    int dd, mm, yy;
    int hrs, min, sec;
    char buf[20];

    if (sscanf(s, "%u-%u-%u %u:%u:%u",
        &yy, &mm, &dd, &hrs, &min, &sec) == 6) goto okay;

    if (sscanf(s, "%u-%19[a-zA-Z]-%u %u:%u:%u",
        &yy, buf, &dd, &hrs, &min, &sec) == 6
        && strtomonth(&mm, buf)) goto okay;

    return 0;

  okay:
    // Do some sanity checking to rule out 2015-mar-35 and such

    tm.tm_sec = sec;
    tm.tm_min = min;
    tm.tm_hour = hrs;
    tm.tm_mday = dd;
    tm.tm_mon = mm - 1;
    tm.tm_year = yy - 1900;

    *time = mktime(&tm);
    return 1;
}

Этот довольно длинный, но все еще очень грубый код, который не проверяет правильность дат и времени, распознает два формата: "2015-05-30 18:13:04" и "2015-may-30 18:13:04". Вы можете добавить больше, когда будете сталкиваться с ними.

goto может быть уродливым, но я думаю, что это хороший способ добраться до общего кода в конце. Поиск в месяц очень груб, но для коротких строк это должно быть хорошо.

  • 0
    Гораздо лучший способ добраться до общего кода - сделать этот общий код функцией с соответствующими параметрами. и позвоните, когда это необходимо.
  • 0
    Любопытно, почему "%u-%u-%u ..." вместо "%d-%d-%d ... ? Оба принимают '+' и '-' .
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню