2 पॉइंट द्वारा GN⁺ 2024-08-16 | 1 टिप्पणियां | WhatsApp पर शेयर करें

हाई-प्रिसिजन date/time extension

SQLite बुनियादी date फ़ंक्शन देता है, लेकिन अधिक सुविधाओं की ज़रूरत होने पर sqlean-time नाम का एक हाई-प्रिसिजन date/time extension बनाया गया। यह extension एक structured API और कई तरह की सुविधाएँ देता है.

नोट. SQLite में extension जोड़ना बहुत आसान है. फ़ाइल डाउनलोड करें और एक database command चलाएँ.

कॉन्सेप्ट

यह extension दो तरह के value types इस्तेमाल करता है: Time और Duration.

  • Time: seconds और nanoseconds से बनी एक जोड़ी, जो 0 समय (0001-01-01 00:00:00 UTC) के बाद के seconds और मौजूदा second के भीतर के nanoseconds को दर्शाती है.

    • time को internal representation में store किया जा सकता है, जिससे अरबों साल पहले और बाद की तारीखों को nanosecond precision के साथ दिखाया जा सकता है.
    • time को Unix epoch (1970-01-01 00:00:00 UTC) के बाद के seconds (milliseconds, microseconds, nanoseconds) के रूप में भी store किया जा सकता है.
    • time हमेशा UTC में store और operate होता है, लेकिन इसे किसी विशेष time zone offset में convert किया जा सकता है.
  • Duration: nanoseconds की इकाई में 64-bit संख्या, जो लगभग 290 साल तक के मान को दिखा सकती है.

time value बनाना

  • मौजूदा समय:

    select time_fmt_iso(time_now());  -- 2024-08-06T21:22:15.431295000Z
    
  • किसी खास date/time के लिए:

    select time_fmt_iso(time_date(2011, 11, 18));  -- 2011-11-18T00:00:00Z
    select time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35));  -- 2011-11-18T15:56:35Z
    

time fields निकालना

अलग-अलग date/time fields निकालने के लिए फ़ंक्शन उपलब्ध हैं:

select 'year  = ' || time_get_year(time_now());
select 'month  = ' || time_get_month(time_now());
select 'day   = ' || time_get_day(time_now());

Unix time

Unix time (1970-01-01 UTC के बाद का समय) से time value बनाने वाले फ़ंक्शन:

select time_fmt_iso(time_unix(1321631795));  -- 2011-11-18T15:56:35Z

Time value को Unix time में बदलने वाले फ़ंक्शन:

select time_to_unix(time_now());  -- 1722979335

time comparison

Time values की तुलना करने वाले फ़ंक्शन:

select time_after(time_now(), time_date(2011, 11, 18));  -- 1
select time_before(time_now(), time_date(2011, 11, 18));  -- 0

time arithmetic

Duration को time value में जोड़ने वाले फ़ंक्शन:

select time_fmt_iso(time_add(time_now(), 24*dur_h()));  -- 2024-08-07T21:22:15.431295000Z

Duration constants:

  • dur_us() - 1 microsecond
  • dur_ms() - 1 millisecond
  • dur_s() - 1 second
  • dur_m() - 1 minute
  • dur_h() - 1 hour

rounding

निर्धारित field precision पर time values को round करने वाले फ़ंक्शन:

select 'original  = ' || time_fmt_iso(t.v) from t union all
select 'millennium = ' || time_fmt_iso(time_trunc(t.v, 'millennium')) from t;

formatting

ISO 8601 time string लौटाने वाले फ़ंक्शन:

select time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888), 3*3600);  -- 2011-11-18T18:56:35.666777888+03:00

Duration constants

सामान्य durations को nanoseconds में लौटाने वाले फ़ंक्शन:

select dur_ns();  -- 1
select dur_us();  -- 1000

आभार

यह extension C में implement किया गया है, और Go की standard library के time package (BSD 3-Clause License) पर आधारित होकर design और implement किया गया है.

इंस्टॉलेशन और उपयोग

  1. नवीनतम release डाउनलोड करें
  2. SQLite command-line interface में उपयोग करें:
    sqlite> .load ./time
    sqlite> select time_now();
    

GN⁺ का सार

  • sqlean-time extension, SQLite में हाई-प्रिसिजन date/time capabilities जोड़ता है, जिससे कई तरह के time operations संभव होते हैं.
  • Time और Duration को nanosecond unit में handle किया जा सकता है, इसलिए बहुत सटीक time calculations संभव हैं.
  • यह कई तरह की time formatting और comparison सुविधाएँ देता है, जिससे developers इसे आसानी से इस्तेमाल कर सकते हैं.
  • SQLite के बुनियादी date फ़ंक्शनों की तुलना में यह कहीं अधिक सुविधाएँ देता है, इसलिए जटिल time operations वाले projects में यह उपयोगी है.

1 टिप्पणियां

 
GN⁺ 2024-08-16
Hacker News टिप्पणियाँ
  • Jon Skeet द्वारा दस्तावेज़ित time zone बदलावों और local time discontinuities के विशेष मामलों को हैंडल किया जाता है या नहीं, इस पर सवाल

    • संबंधित लिंक: Stack Overflow
    • Computerphile की 10 मिनट की वीडियो व्याख्या का लिंक: YouTube
  • date/time और cryptography libraries को खुद बनाना ठीक नहीं माना गया

    • अनगिनत edge cases समस्या पैदा कर सकते हैं
    • नई library देखते समय संदेहशील रहने की वजह
  • तीन अलग-अलग time representations/sizes दिलचस्प लगे

    • यह जिज्ञासा कि अरबों वर्षों की अवधि में nanosecond precision की ज़रूरत वाले use cases कौन से हैं
    • nanosecond precision के साथ सिर्फ ±290 साल की range मिलना भ्रमित करने वाला है
  • signed integer इस्तेमाल हो रहा है या नहीं, इसे स्पष्ट करना ज़रूरी है

    • documentation पढ़ने पर लगता है कि यह signed integer हो भी सकता है और नहीं भी
    • अगर यह signed integer है, तो एक ही date और time को दर्शाने वाली कई bit strings हो सकती हैं
  • काश SQLite3 में extensible type system होता

  • SQLite की एक महत्वपूर्ण missing feature का ज़िक्र करते हुए इसे बहुत शानदार बताया गया

  • यह तर्क कि database को units track करने चाहिए

    • उदाहरण के लिए, यह स्पष्ट किया जा सके कि time column float64 seconds में दर्शाया गया है
    • database को "2h" को 7200.0 seconds में बदलकर table scan के दौरान compare कर पाना चाहिए
    • पहले इस तरह की unit handling करने वाला एक special-purpose SQL database लिखा था, लेकिन उसके बाद ऐसा नहीं देखा
    • सिर्फ समय नहीं, बल्कि mass, volume, information, temperature आदि सभी units को हैंडल कर पाना चाहिए
    • database को mathematical रूप से निरर्थक operations अस्वीकार करना सिखाया जा सकता है, ताकि गणितीय गलतियाँ जल्दी पकड़ी जा सकें
  • nanosecond representation और nano range के बाहर के वर्षों में से कौन ज़्यादा उपयोगी है, इस पर सवाल

    • क्योंकि "exact" science नहीं की जाती, इसलिए nanoseconds का मूल्य सीमित लगता है
    • historical dates को दर्शा पाना ज़्यादा बार ज़रूरी पड़ सकता है
  • golang शैली के Unix timestamp को nanoseconds में, signed int64 के रूप में इस्तेमाल करने का सुझाव

    • nanosecond precision पर लाखों वर्षों को cover करना संभव न हो, लेकिन क्या सच में इसकी ज़रूरत है, इस पर सवाल
  • यह तर्क कि "epoch ke baad ke seconds" जैसे वाक्यांश का इस्तेमाल तब तक नहीं करना चाहिए जब तक उसका अर्थ बिल्कुल सटीक न हो

    • उदाहरण query: select time_sub(time_date(2011, 11, 19), time_date(1311, 11, 18));