Подтвердить что ты не робот

Библиотека C для анализа приблизительных дат

Я ищу простой экземпляр C для date.js date.parse().

То есть, что-то, что понимает "неделю назад" или "вчера" в качестве входных данных. Только на английском - это нормально.

Примечание. Библиотека не должна быть лицензирована в GPL, поэтому Git date.c или парсер для GNU date -d не будет работать. Кстати, если вы задаетесь вопросом, почему бы мне просто не присесть и не закодировать это, пойдите и посмотрите на источник упомянутых библиотек...

4b9b3361

Ответ 1

Следующее решение - это не то, о чем вы просили, но я надеюсь, что, несмотря на то, что он не является простым ответом на C, он будет отвечать вашим потребностям. Переосмыслить колесо - это не путь, поэтому давайте использовать date.js в C, запустив его с помощью SpiderMonkey, движка JavaScript Mozilla.

Вот как я это сделал. Я начал с загрузки date.js и перевода его в const char* с именем code, определенным в date.js.h.

( \
  echo 'const char *code =' ; \
  curl https://datejs.googlecode.com/files/date.js | \
    sed -e 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/\r\?$/\\n"/'; \
  echo ';' \
) > date.js.h

Тогда я взял JSAPI Hello, World! в качестве отправной точки.

#include "jsapi.h"
#include "date.js.h"

static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS,
  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
  JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
  JSCLASS_NO_OPTIONAL_MEMBERS };

void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
  fprintf(stderr, "%s:%u:%s\n",
      report->filename ? report->filename : "<no filename>",
      (unsigned int) report->lineno, message);
}

int main(int argc, const char *argv[]) {
  JSRuntime *rt;
  JSContext *cx;
  JSObject *global;
  rt = JS_NewRuntime(8L * 1024L * 1024L);
  if (rt == NULL) return 1;
  cx = JS_NewContext(rt, 8192);
  if (cx == NULL) return 1;
  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
  JS_SetVersion(cx, JSVERSION_LATEST);
  JS_SetErrorReporter(cx, reportError);
  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
  if (global == NULL) return 1;
  if (!JS_InitStandardClasses(cx, global)) return 1;

  /* Here where the interesting stuff is starting to take place.
   * Begin by evaluating sources of date.js */

  jsval out;
  if (!JS_EvaluateScript(cx, global, code, strlen(code), "code", 1, &out))
    return 1;

  /* Now create a call to Date.parse and evaluate it. The return value should
   * be a timestamp of a given date. If no errors occur convert the timestamp
   * to a double and print it. */

  const int buflen = 1024;
  char parse[buflen + 1];
  snprintf(parse, buflen, "Date.parse(\"%s\").getTime();", argv[1]);

  if (!JS_EvaluateScript(cx, global, parse, strlen(parse), "parse", 1, &out))
    return 1;

  double val;
  JS_ValueToNumber(cx, out, &val);
  printf("%i\n", (int) (val / 1000));

  /* Finally, clean everything up. */

  JS_DestroyContext(cx);
  JS_DestroyRuntime(rt);
  JS_ShutDown();
  return 0;
}

Вот как это работает на практике.

$ time ./parse "week ago"
1331938800
0.01user 0.00system 0:00.02elapsed 92%CPU (0avgtext+0avgdata 6168maxresident)k
0inputs+0outputs (0major+1651minor)pagefaults 0swaps
$ time ./parse yesterday
1332457200
0.01user 0.00system 0:00.02elapsed 84%CPU (0avgtext+0avgdata 6168maxresident)k
0inputs+0outputs (0major+1653minor)pagefaults 0swaps

Как вы можете видеть это довольно быстро, и вы можете значительно увеличить его производительность, повторно используя первоначально созданный контекст для всех последующих вызовов Date.parse.

Говоря о проблемах с лицензированием, date.js предоставляется в соответствии с условиями MIT, а SpiderMonkey доступен под MPL 1.1, GPL 2.0 или LGPL 2.1. Связывание его динамически удовлетворяет требованию, отличному от GPL.

TL; DR: git clone https://gist.github.com/2180739.git && cd 2180739 && make && ./parse yesterday

Ответ 2

Форматирование даты довольно ужасно, нет простого способа сделать это. Вы должны учитывать названия дней и месяцев выбранного языка, затем убедитесь, что вы получили данные в определенном формате: "dd/mm/yyyy", "day mon, yyyy" и т.д. Кроме того, как вы говорите, вам нужно интерпретировать некоторые конкретные ключевые слова, поэтому вам нужен доступ к текущей временной отметке (дата, время или дата и время) на машине.

Надеясь, что вам нужно, что для Linux, я думаю, вы можете начать читать здесь: Конвертировать текстовые данные о времени и дате назад

Или вы можете просто токенизировать свою входную строку, разделив ее на некоторые предопределенные разделители (запятая, косая черта, минус, пробел и т.д.), обрезая пробелы токенов и затем применяя автоматы для обработки списка токенов и создайте переменную даты. Убедитесь, что вы добавили некоторые ограничения для формата входных дат и выбрасывали ошибки для неправильных или несовместимых токенов.