2012-03-19 8 views
18

date.jsdate.parse()のプレーンC対応を探しています。おおよその日付を解析するためのCライブラリ

つまり、「週前」または「昨日」を入力として理解するものです。英語のみOKです。

注:ライブラリはGPLでライセンスされるべきではないので、Gitのdate.cまたはGNU date -dのパーサでは許可されません。私がちょうど座ってこれをコード化しない理由が不思議なら、言及したライブラリのソースを見てください...

+0

、date.jsはMITがライセンスされています。ですから、ここで目的とするのが独自のコードとリンクできるものを得ることであれば、自分でロールバックする必要がある場合は、date.jsを安全な出発点として使用できるはずです。 javascriptからCへの書き換えは、公園内での歩行ではないかもしれませんが。 –

+1

これはまさに私がコードを書こうとするのではなく、この質問をする理由です:-) –

+0

あなた自身のパーサーを書くためのソースの複雑さが気になる方は、lex/yaccツールを使用できますか? – Jerry

答えて

6

以下の解決策はあなたが求めているものではありませんが、私は平凡なCの回答ではありませんが、あなたのニーズをカバーすることを願っています。ホイールを改造するのは方法ではないので、Cのdate.jsをMozilla JavaScriptエンジンであるSpiderMonkeyで実行してみましょう。

ここで私はそれをしました。私はdate.jsをダウンロードし、それをで定義されたcodeという名前のconst char*に翻訳し始めました。

(\ 
    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's 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'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; 
} 

実際の動作は次のとおりです。

$ 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

+3

ねえ、巧妙なトリック、ありがとう。私は高性能が必要ないので、私の場合でもうまくいくと思う。私は正直な解決策がポップアップする場合は、質問を開いたままにしておきます:-) –

-1

日付の書式設定は非常に面倒です、これを行う簡単な方法はありません。 選択した言語の曜日と月の名前を考慮に入れ、「dd/mm/yyyy」、「day mon、yyyy」などの特定の形式でデータを受信する必要があります。 また、あなたが言うように、いくつかの特定のキーワードを解釈する必要があるため、マシン上の現在のタイムスタンプ(日付、時刻、または日付&)にアクセスする必要があります。 Convert textual time and date information back

それとも、単にいくつかの事前定義されたセパレータ(カンマ、スラッシュ、マイナス、スペースなどを使用して、それを分割することによって、あなたの入力文字列をトークン化することができます:あなたがLinuxの場合、私はあなたがここから読み始めることができると思うことを必要とすることを望ん

。)、トークンのスペースをトリミングし、トークンのリストを処理して日付変数を構築するオートマトンを実装します。 入力日付形式にいくつかの制限を追加し、間違ったトークンまたは互換性のないトークンにエラーをスローするようにしてください。

+0

「getdate」は「昨日」などを理解しません。どのように解析するかについては、私はそれを知るが、この問題は既存の解決策に関するものである。私はそれを自分でやることは嫌いだし、既存のGPLコードから判断すると、たくさんの落とし穴があります。 –

関連する問題