2012-03-19 14 views
18

मैं date.jsdate.parse() के लिए एक सादा सी समकक्ष की तलाश में हूं।सी लाइब्रेरी अनुमानित तिथियों को पार्स करने के लिए

वह कुछ है जो "सप्ताह पहले" या "कल" ​​इनपुट के रूप में समझता है। अंग्रेजी केवल ठीक है।

नोट: पुस्तकालय को जीपीएल के तहत लाइसेंस प्राप्त नहीं किया जाना चाहिए, इसलिए गिट के date.c या जीएनयू date -d के लिए पार्सर नहीं करेगा। बीटीडब्लू, अगर आपको आश्चर्य है कि मैं बस क्यों बैठूं और कोड नहीं करूँगा, तो जाओ और उल्लिखित पुस्तकालयों के स्रोत को देखें ...

+0

क्या इसके लायक है के लिए, date.js एमआईटी लाइसेंस प्राप्त है। तो यदि यहां लक्ष्य कुछ प्राप्त करना है, तो आप स्वामित्व कोड से लिंक कर सकते हैं, तो आपको डेट.जेएस को एक सुरक्षित प्रारंभिक बिंदु के रूप में उपयोग करने में सक्षम होना चाहिए यदि आपको अपना खुद का रोल करना है। हालांकि जावास्क्रिप्ट-टू-सी रीराइटिट पार्क में चलना नहीं हो सकता है। –

+1

यही कारण है कि मैं कोड लिखने के लिए आगे बढ़ने के बजाय इस सवाल से पूछ रहा हूं :-) –

+0

यदि आप अपने स्वयं के पार्सर लिखने के लिए स्रोत जटिलता के बारे में चिंतित हैं, तो क्या आप lex/yacc टूल्स का उपयोग कर सकते हैं? – Jerry

उत्तर

6

निम्न समाधान बिल्कुल वही नहीं है जो आपने पूछा है, लेकिन मुझे उम्मीद है कि एक सादा सी जवाब होने के बावजूद यह आपकी आवश्यकताओं को पूरा करेगा। पहिया को पुनर्निर्मित करने का कोई तरीका नहीं है इसलिए चलिए स्पाइडरमोन्की, मोज़िला जावास्क्रिप्ट इंजन के साथ इसे चलाकर सी में 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'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 के बाद के सभी कॉल के लिए शुरू में बनाई गई संदर्भ पुन: उपयोग से इसके प्रदर्शन को बढ़ा सकता है के रूप में।

लाइसेंसिंग मुद्दों के बारे में बोलते हुए, दिनांक.जेएस एमआईटी और स्पाइडरमोन्की के तहत उपलब्ध है एमपीएल 1.1, जीपीएल 2.0 या एलजीपीएल 2.1 के तहत उपलब्ध है। इसे जोड़ने से गतिशील रूप से गैर-जीपीएल आवश्यकता को पूरा किया जाता है।

टी एल; डॉ:git clone https://gist.github.com/2180739.git && cd 2180739 && make && ./parse yesterday

+3

हे, चालाक चाल, धन्यवाद। मुझे लगता है कि यह मेरे मामले के लिए भी काम करेगा, क्योंकि मुझे उच्च प्रदर्शन की आवश्यकता नहीं है। एक ईमानदार समाधान पॉप अप होने पर मैं प्रश्न खोल रहा हूं :-) –

-1

दिनांक स्वरूपण बहुत भयानक है, ऐसा करने का कोई आसान तरीका नहीं है। आपको चयनित भाषा के दिन और महीने के नामों को ध्यान में रखना होगा, फिर सुनिश्चित करें कि आप एक विशिष्ट प्रारूप में डेटा प्राप्त करते हैं: "dd/mm/yyyy", "दिन mon, yyyy" और इसी तरह। इसके अलावा, जैसा कि आप कहते हैं, आपको कुछ विशिष्ट कीवर्ड की व्याख्या करने की आवश्यकता है, इस प्रकार आपको मशीन पर वर्तमान टाइमस्टैम्प (दिनांक, समय, या दिनांक & समय) तक पहुंच की आवश्यकता है।

आशा आप की जरूरत लिनक्स के लिए, मुझे लगता है कि तुम यहाँ से पढ़ना शुरू कर सकते हैं: Convert textual time and date information back

या आप बस अपने इनपुट स्ट्रिंग tokenize कर सकते हैं कुछ पूर्वनिर्धारित विभाजक (अल्पविराम का उपयोग कर इसे विभाजित करके, स्लेश, शून्य, अंतरिक्ष आदि ।), टोकन की रिक्त स्थान को ट्रिम करना, और फिर टोकन की सूची को संभालने और अपनी तिथि चर बनाने के लिए एक ऑटोमाटा लागू करें। सुनिश्चित करें कि आप इनपुट दिनांक प्रारूप के लिए कुछ प्रतिबंध जोड़ते हैं, और गलत या असंगत टोकन के लिए त्रुटियां फेंकते हैं।

+0

धन्यवाद में मदद कर सकती है, लेकिन 'getdate' को 'कल' नहीं समझा जाता है। कैसे पार्स करना है - मुझे वह मिलता है, लेकिन यह सवाल मौजूदा समाधान के बारे में है। मैं इसे खुद करने से नफरत करता हूं और सभी नुकसान उठाता हूं - मौजूदा जीपीएल-एड कोड से निर्णय लेना बहुत है। –

संबंधित मुद्दे