net - parse exact datetime
Biblioteca C para analizar fechas aproximadas (2)
Estoy buscando una contraparte C simple para date.js date.parse()
.
Es decir, algo que entiende "entrada hace una semana" o "ayer" como entrada. Solo en inglés está bien.
Nota: una biblioteca no debe tener una licencia bajo la GPL, por lo que date.c
o el analizador de Git para la date -d
GNU date -d
no funcionaría. Por cierto, si te preguntas por qué no me siento y codifico esto, ve a ver la fuente de las bibliotecas mencionadas ...
El formato de fecha es bastante espantoso, no hay una forma fácil de hacerlo. Debe tener en cuenta los nombres de los días y los meses del idioma seleccionado, luego asegúrese de recibir los datos en un formato específico: "dd / mm / aaaa", "day mon, yyyy" y así sucesivamente. Además, como dice, debe interpretar algunas palabras clave específicas, por lo que necesita acceso a la marca de tiempo actual (fecha, hora o fecha y hora) en la máquina.
Esperando que necesite eso para Linux, creo que puede comenzar a leer desde aquí: convertir la información textual de fecha y hora de vuelta
O simplemente puede tokenizar su cadena de entrada, dividiéndola usando algunos separadores predefinidos (coma, barra, menos, espacio, etc.), recortando los espacios de los tokens y luego implementando un autómata para manejar la lista de tokens y construir su fecha variable. Asegúrese de agregar algunas restricciones para el formato de fecha de entrada y arroje errores por tokens incorrectos o incompatibles.
La siguiente solución no es exactamente lo que ha pedido, pero espero que, a pesar de no ser una respuesta C clara, cubra sus necesidades. Reinventar la rueda no es una forma de hacerlo, así que vamos a usar date.js en C ejecutándolo con SpiderMonkey, el motor de JavaScript de Mozilla.
Así es como lo hice. He empezado a descargar date.js y a traducirlo en un code
const char*
denominado definido en 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
Luego tomé el Hola, Mundo de JSAPI ! como punto de partida.
#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''s 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;
}
Así es como funciona en la práctica.
$ 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
Como puede ver, es bastante rápido y podría aumentar significativamente su rendimiento al reutilizar el contexto creado inicialmente para todas las llamadas posteriores a Date.parse
.
Hablando de problemas de licencia, date.js está disponible bajo los términos de MIT y SpiderMonkey está disponible bajo MPL 1.1, GPL 2.0 o LGPL 2.1. Vincularlo de forma dinámica satisface el requisito de no GPL.
TL; DR: git clone https://gist.github.com/2180739.git && cd 2180739 && make && ./parse yesterday