- अगर SQLite के default date functions पर्याप्त नहीं हैं, तो
sqlean-timeएक extension के रूप में nanosecond precision वाले Time·Duration types और date·time functions जोड़ता है - Time value
0001-01-01 00:00:00 UTCके बाद के seconds और मौजूदा second के भीतर nanoseconds से बनी होती है, और 13-byte BLOB के रूप में store करने पर past और future के अरबों वर्षों की range संभाल सकती है - Unix epoch के आधार पर 64-bit NUMBER storage भी संभव है, लेकिन unit जितनी छोटी होती है range उतनी घटती है; nanosecond unit में केवल
1678से2262तक represent किया जा सकता है - API में creation, field extraction, Unix time conversion, comparison, arithmetic, truncation·rounding, ISO 8601 formatting·parsing शामिल हैं, और values हमेशा UTC में store व operate की जाती हैं
- Calendar calculation Gregorian calendar को मानकर चलते हैं और leap seconds handle नहीं करते, इसलिए day·month·year calculations के लिए Duration-based
time_add()के बजायtime_add_date()का उपयोग करना चाहिए
sqlean-time का time model
sqlean-timeSQLite में high-precision date·time processing जोड़ने वाला extension है- SQLite extension को file download करके और database command चलाकर add किया जा सकता है
- Extension दो तरह की values के इर्द-गिर्द काम करता है
- Time: कोई खास instant
- Duration: अवधि
Time representation और storage range
- Time
(seconds, nanoseconds)pair से बना होता हैseconds: zero time यानी0001-01-01 00:00:00 UTCके बाद के seconds दिखाने वाला 64-bit integernanoseconds: मौजूदा second के भीतर nanosecond value, जिसकी range0-999999999है
- अगर maximum flexibility चाहिए, तो Time value को internal representation यानी 13-byte BLOB के रूप में store किया जा सकता है
- यह तरीका past और future के अरबों वर्षों की dates को nanosecond precision के साथ represent करता है
- Unix epoch यानी
1970-01-01 00:00:00 UTCके बाद के seconds, milliseconds, microseconds, nanoseconds को 64-bit integer NUMBER के रूप में store करने का तरीका भी supported है- seconds: past·future के अरबों वर्षों को second precision में represent करता है
- milliseconds: 1970 के आगे-पीछे 292 million years को millisecond precision में represent करता है
- microseconds:
-290307वर्ष से294246वर्ष तक represent करता है - nanoseconds:
1678वर्ष से2262वर्ष तक represent करता है
- Time हमेशा UTC में store और operate किया जाता है
- किसी specific timezone offset के साथ conversion संभव है
- Calendar calculations हमेशा Gregorian calendar मानते हैं
- leap seconds का उपयोग नहीं किया जाता
Duration और value creation
- Duration nanosecond unit वाला 64-bit integer है
- यह लगभग 290 वर्षों तक की अवधि represent कर सकता है
- इसे NUMBER के रूप में store किया जा सकता है
- Current instant
time_now()से बनाया जा सकता है- उदाहरण:
time_fmt_iso(time_now())2024-08-06T21:22:15.431295000Zजैसी ISO string return करता है
- उदाहरण:
- Specific date·time
time_date()से create किया जाता है- सिर्फ date specify करने पर midnight UTC बनता है
- hour·minute·second और nanosecond साथ में specify किए जा सकते हैं
- timezone offset pass करने पर UTC instant में convert हो जाता है
Date·time fields extraction
- Individual field extraction functions year, month, day, hour, minute, second, nanosecond, weekday, day of year, ISO year, ISO week return करते हैं
- उदाहरण:
time_get_year(),time_get_month(),time_get_day(),time_get_hour(),time_get_minute(),time_get_second(),time_get_nano()
- उदाहरण:
- General-purpose function
time_get()field name string से value extract करता है- Supported उदाहरण:
millennium,century,decade,year,quarter,month,day - Time unit उदाहरण:
hour,minute,second,milli,micro,nano - ISO·calendar related उदाहरण:
isoyear,isoweek,isodow,yearday,weekday - Unix epoch value
epochसे लाई जा सकती है
- Supported उदाहरण:
Unix time conversion
- Unix time से Time value बनाने के functions उपलब्ध हैं
time_unix(seconds)time_unix(seconds, nanoseconds)time_milli(milliseconds)time_micro(microseconds)time_nano(nanoseconds)
- Time value को वापस Unix time में बदलने वाले functions भी हैं
time_to_unix()time_to_milli()time_to_micro()time_to_nano()
- Unix-like operating systems अक्सर time को 32-bit seconds value के रूप में record करते हैं, लेकिन
time_to_unix()64-bit value return करता है- past·future के अरबों वर्षों की range में valid है
time_to_milli()1970 के आगे-पीछे 292 million years तक represent करता हैtime_to_micro()-290307वर्ष से294246वर्ष तक represent करता हैtime_to_nano()1678वर्ष से2262वर्ष तक represent करता है
Comparison और arithmetic
- Time comparison functions दो Time values का order determine करते हैं
time_after(): return करता है कि पहला time दूसरे time के बाद है या नहींtime_before(): return करता है कि पहला time दूसरे time से पहले है या नहींtime_compare(): बाद में हो तो1, पहले हो तो-1, समान हो तो0return करता हैtime_equal(): return करता है कि दोनों values एक ही instant को represent करती हैं या नहीं
time_add()Time value में Duration जोड़ता है- Negative Duration का उपयोग करने पर subtract किया जा सकता है
dur_us(),dur_ms(),dur_s(),dur_m(),dur_h()जैसे Duration constants साथ में use किए जा सकते हैं
- day·month·year जोड़ते समय
time_add()नहीं, बल्किtime_add_date()का उपयोग करना चाहिएtime_add_date()year, month, day जोड़ता है और negative values से subtract किया जा सकता है
time_sub()दो Time values के बीच की अवधि nanoseconds में return करता हैtime_since()specified instant के बाद elapsed time nanoseconds में return करता हैtime_until()specified instant तक remaining duration nanoseconds में return करता है
Truncation और rounding
time_trunc()Time value को specified field precision तक round down करता है- Supported उदाहरण:
millennium,century,decade,year,quarter,month,week,day,hour,minute,second,milli,micro - उदाहरण के लिए
2011-11-18T15:56:35.666777888Zकोhourसे truncate करने पर2011-11-18T15:00:00Zबनता है
- Supported उदाहरण:
- Specified Duration के multiple तक भी round down किया जा सकता है
- उदाहरण:
12*dur_h(),dur_h(),30*dur_m(),dur_m(),30*dur_s(),dur_s()
- उदाहरण:
time_round()specified Duration के nearest multiple तक round करता है- उदाहरण:
2011-11-18T15:56:35.666777888Zकोdur_h()से round करने पर2011-11-18T16:00:00Zबनता है - वही value
dur_s()से round करने पर2011-11-18T15:56:36Zबनती है
- उदाहरण:
Formatting और parsing
time_fmt_iso()Time value को ISO 8601 string के रूप में return करता है- Timezone offset को optional रूप से लेकर उस offset में convert करने के बाद format कर सकता है
- Nanoseconds वाली value
2011-11-18T15:56:35.666777888Zकी तरह represent होती है - Offset specify करने पर
2011-11-18T18:56:35.666777888+03:00की तरह represent होती है
time_fmt_datetime(),time_fmt_date(),time_fmt_time()क्रमशः datetime, date, time strings return करते हैं- Timezone offset optional रूप से लिया जा सकता है
time_parse()formatted string को Time value में parse करता है- ISO 8601 nanoseconds और timezone वाली string
- ISO 8601 nanoseconds और UTC
Zstring - ISO 8601 timezone वाली string
- ISO 8601 UTC string
YYYY-MM-DD HH:MM:SSformat की UTC date·timeYYYY-MM-DDformat की UTC dateHH:MM:SSformat का UTC time
time_parse()द्वारा supported layouts limited set हैं
Duration constants
- Common Duration को nanoseconds में return करने वाले functions उपलब्ध हैं
dur_ns()→1dur_us()→1000dur_ms()→1000000dur_s()→1000000000dur_m()→60000000000dur_h()→3600000000000
Implementation base और installation
- Extension C में implement किया गया है, लेकिन design और implementation Go standard library के time package पर काफी हद तक based हैं
- वह package BSD 3-Clause License के तहत है
- Installation latest release download करके SQLite CLI में extension load करने के तरीके से की जाती है
- उदाहरण:
.load ./time - Load करने के बाद
select time_now();जैसी queries use की जा सकती हैं
- उदाहरण:
1 टिप्पणियां
Hacker News पर राय
सोच रहा हूँ कि क्या यह Jon Skeet द्वारा मशहूर तरीके से समझाए गए time zone बदलावों और local time discontinuity जैसे edge cases को भी संभालता है
https://stackoverflow.com/questions/6841333/why-is-subtracti...
Computerphile ने भी इसे 10 मिनट के वीडियो में बहुत अच्छे से समझाया है
https://www.youtube.com/watch?v=-5wpm-gesOY
बहुत पहले मैंने सीख लिया था कि date/time या cryptography libraries खुद नहीं बनानी चाहिए। ऐसे edge cases अंतहीन हैं जहाँ चीज़ें बुरी तरह काट सकती हैं, इसलिए ऐसी नई library देखकर मैं थोड़ा संशय में रहता हूँ
मेरे हिसाब से docs थोड़े और साफ़ हो सकते हैं। लेखक “time zones” कहते हैं, लेकिन library असल में सिर्फ़ time zone offsets से निपटती है। time zone America/New_York जैसी चीज़ है, और time zone offset UTC से अंतर है। New York आज -14400 seconds है, लेकिन daylight saving time बदलाव के कारण कुछ महीनों बाद -18000 seconds हो जाएगा
तीन अलग-अलग time representations/sizes दिलचस्प हैं। उदाहरण के लिए, अरबों साल की range में nanosecond precision की ज़रूरत किस use case में पड़ेगी, समझ नहीं आता
और भी confusing बात यह है कि time granularity बेहद fine है, लेकिन time duration में nanosecond precision की range सिर्फ़ ±290 साल तक सीमित है
लेकिन अगर 2 bits जोड़ ही रहे हैं, तो 16 या 32 bits जोड़ने से रोकता क्या है। फिर 30 cm तक light को travel करने में लगने वाला time calculate करने वाले लोगों से लेकर universe की age calculate करने वालों तक सब cover हो जाते हैं
मेरा अंदाज़ा है कि design decision शायद कुछ इसी तरह आगे बढ़ा होगा :)
बेशक leap seconds support के बिना sub-second accuracy देना मुश्किल है, और human civilization से पहले के leap seconds support का मतलब ही क्या होगा, यह भी अस्पष्ट है
संबंधित लेकिन अलग बात: databases को units track करनी चाहिए। अगर time column है, तो उदाहरण के लिए उसे float64 seconds में duration के रूप में declare कर पाना चाहिए
तब
SELECT * FROM my_table WHERE duration_s >= 2hजैसा लिख सकें, और database अपने-आप “2h” को 7200.0 seconds में बदलकर table scan के दौरान same units की तुलना करेकुछ साल पहले मैंने native unit handling वाला एक special-purpose SQL database बनाया था, लेकिन उसके पहले या बाद में ऐसा नहीं देखा, और यह UI ecosystem में एक gap जैसा लगता है
यह सिर्फ़ time तक सीमित होने की ज़रूरत नहीं है। mass, volume, information amount, temperature आदि पूरी units list handle कर पाना चाहिए।
SELECT 2h + 15kg -- type error!जैसे mathematically nonsensical expressions को भी database reject कर सकेइससे analysis errors को शुरुआत में पकड़ने में बहुत मदद मिलेगी
मेरे हिसाब से यह साफ़ बताना ज़रूरी है कि signed integers इस्तेमाल हो रहे हैं या नहीं। docs पढ़ने पर लगता है कि शायद signed हैं, लेकिन शायद नहीं भी हो सकते
अगर signed integers हैं, तो same date और time को represent करने वाली multiple bit strings बन सकती हैं, और यह अच्छा नहीं है
हालांकि bit patterns library की internal समस्या हैं। अगर code में bug मिल सके तो ज़रूर point out करें, और संभव हो तो fix भी suggest करें
काश SQLite3 में extensible type system होता
extensible type system database end-user performance के लिए बेहद खराब है। तब query parsing और optimization में किसी भी चीज़ को shortcut से handle नहीं किया जा सकता। हर operand का type check करना, सही operator implementation ढूँढना, सही index operator family/class ढूँढना वगैरह के लिए query system catalog को बार-बार lookup करना पड़ता है
values का input/output भी system catalog में stored functions से गुजरता है।
select 1तक का जवाब system catalog देखे बिना नहीं दिया जा सकताउचित built-in types का set और structs/JSON जैसे composition तरीके होने चाहिए। PostgreSQL को छोड़कर ज़्यादातर databases इसी तरह हैं, और मैं दृढ़ता से मानता हूँ कि यही सही दिशा है
यह थोड़ा lazy Ask HN-style सवाल है, लेकिन experience में क्या ज़्यादा उपयोगी या valuable है? nanosecond representation, या फिर 1678~2200 जैसी nanosecond range से बाहर के years को represent करना?
मैं proper scientific work नहीं करता, इसलिए nanoseconds की value बहुत clever experiments या अधिक narrow range वाली financial transaction tracking तक सीमित लगती है
वहीं historical dates को represent कर पाने की क्षमता ज़्यादा बार ज़रूरी लगती है। आप क्या सोचते हैं?
precision को सिर्फ़ 10 nanoseconds तक घटाने पर भी practical तौर पर पर्याप्त range मिल जाती है
समझ नहीं आता कि Go style की तरह Unix timestamp को nanoseconds में signed int64 के रूप में क्यों नहीं इस्तेमाल करते। nanosecond precision के साथ लाखों साल cover नहीं होंगे, लेकिन क्या सच में इसकी ज़रूरत है?
select time_to_nano(time_now());-- 1722979335431295000“seconds since epoch” जैसे expression तभी इस्तेमाल किए जाएँ जब उनका मतलब ठीक वही हो
सोच रहा हूँ कि
select time_sub(time_date(2011, 11, 19), time_date(1311, 11, 18));क्या return करेगाकुछ plausible कारण तो सोच में आते हैं, लेकिन सच में महत्वपूर्ण चीज़ सिर्फ़ “कौन-सा epoch?” है। UNIX-based systems या उनके behavior की नकल करने वाले systems में यह well-defined है। लेकिन आपने अपनी शिकायत क्या है यह नहीं बताया, इसलिए यह बताना मुश्किल है कि अभी जैसा है उसका विरोध या justification कैसे किया जाए
time_date(1311, 11, 18)ज़्यादातर computer systems द्वारा इस्तेमाल किए जाने वाले epoch में defined नहीं है, इसलिए कोई भी result संभव है। MAX_INT, MIN_INT, 0, कोई plausible value जो calendar reforms reflect नहीं करती, किसी दूसरे epoch में convert करके exact seconds calculate किया गया value—कुछ भी हो सकता है। GMT/UTC से पहले सब local time था, इसलिए यह भी कहा जा सकता है कि कोई valid epoch नहीं हैबेशक negative values support करनी चाहिए या नहीं, इस पर दोनों तरफ़ argument हो सकते हैं। 1970-1-1 0:00:00 UTC से ठीक 24 घंटे पहले -86400 होने की उम्मीद की जा सकती है, लेकिन “since” strongly positive values का संकेत देता है
दूसरों के पास अलग कारणों से पूरी तरह अलग epoch हो सकता है, और अगर इस्तेमाल की domain में सभी सहमत हैं तो वह भी ठीक है
या आपकी कोई और आपत्ति थी?