किसी तारीख में महीने जोड़ना सुनने में जितना आसान लगता है उससे कठिन है

किसी तारीख में 7 दिन जोड़ना आसान है। एक संख्या लो, उसमें 7 जोड़ो, बस हो गया। लेकिन एक महीना जोड़ना बिल्कुल अलग समस्या है।

परेशानी यह है कि महीनों की लंबाई अलग-अलग होती है। जनवरी में 31 दिन हैं। फरवरी में 28, कभी 29। अगर आप 31 जनवरी पर हैं और एक महीना जोड़ते हैं, तो आप 31 फरवरी पर पहुँच जाते हैं — जो मौजूद ही नहीं है।

हर कैलेंडर लाइब्रेरी, स्प्रेडशीट और डेटाबेस के पास इसके आगे क्या करना है, इस पर अपनी राय है।

ज्यादातर टूल्स क्या करते हैं

सबसे आम तरीका यह है कि तारीख को लक्ष्य महीने के आखिरी दिन पर ला दिया जाए। 31 जनवरी + 1 महीना = 28 फरवरी (लीप साल में 29)। 31 मार्च + 1 महीना = 30 अप्रैल।

इसे end-of-month clamping कहते हैं और यही Excel, Google Sheets, Python के dateutil, और ज्यादातर डेट लाइब्रेरीज़ करती हैं।

यह समझदारी भरा है, लेकिन इसमें एक सूक्ष्म समस्या है: यह ऑपरेशन उलटा नहीं किया जा सकता। अगर आप 31 जनवरी में एक महीना जोड़ते हैं, तो आप 28 फरवरी तक पहुँचते हैं। फिर अगर आप एक महीना घटाते हैं, तो आप 28 जनवरी पर आते हैं — 31 जनवरी पर नहीं। तीन दिन खो गए।

Overflow का तरीका

कुछ सिस्टम्स तारीख को क्लैम्प करने के बजाय अगले महीने में ओवरफ़्लो होने देते हैं। 31 जनवरी + 1 महीना = 3 मार्च (लीप साल में 2 मार्च, क्योंकि फरवरी में 29 दिन होते हैं)।

यह कुल दिनों की संख्या तो बचा लेता है, लेकिन नतीजा बिल्कुल अलग महीने में आता है जिसका आप इरादा रखते थे। यह हैरान करने वाला है और यूज़र के दृष्टिकोण से आमतौर पर गलत होता है।

SQL की INTERVAL सिंटैक्स कुछ डेटाबेसों में कॉन्फ़िगरेशन के आधार पर यही करती है। अगर आप यह नहीं जानते कि आप किस तरह के व्यवहार के साथ काम कर रहे हैं, तो गलती हो सकती है।

साल जोड़ने में भी यही समस्या है

29 फरवरी सिर्फ लीप सालों में मौजूद है। 29 फरवरी, 2024 में एक साल जोड़ो, तो आप 29 फरवरी, 2025 पर आते हो — जो मौजूद नहीं है। क्लैम्पिंग से आप 28 फरवरी, 2025 को पहुँचते हैं।

वही व्यवहार, वही फायदे और नुकसान।

यह असल में कहाँ बग बनता है

सदस्यता बिलिंग इसका सबसे क्लासिक उदाहरण है। कोई यूज़र 31 जनवरी को साइन अप करता है। उसकी अगली बिलिंग की तारीख 28 फरवरी है। फिर 28 मार्च। फिर 28 अप्रैल। पहले महीने के बाद हर महीने, उन्हें अपेक्षा से 2-3 दिन पहले बिल किया जाता है।

बार-बार आने वाली कैलेंडर इवेंट्स में भी यही समस्या है। "हर महीने 31वें दिन को" खामोशी से बन जाता है "हर महीने के आखिरी दिन को" उन महीनों के लिए जो 31 तक नहीं जाते।

लोन रीपेमेंट शेड्यूल, तनख्वाह की तारीखें, और "मासिक" रिकरेंस वाली कोई भी चीज़ आखिरकार इस edge case में फंस ही जाती है।

दिन जोड़ने में यह समस्या नहीं है

अगर आपको "अब से 30 दिन बाद" के बजाय "अब से एक महीना बाद" कहना है, तो बस 30 दिन जोड़ दो। नतीजा साफ़ और उलटा किया जा सकने वाला होता है।

यह अंतर मायने रखता है: 30 दिन का बिलिंग साइकिल और मासिक बिलिंग साइकिल एक नहीं हैं, और समय के साथ ये अलग हो जाते हैं।

अपने टूल या लाइब्रेरी में क्या चेक करें

किसी भी सिस्टम में डेट एडिशन पर भरोसा करने से पहले, यह जानना काम का है:

  • क्या यह महीने के आखिर की तारीखों पर क्लैम्प करता है या ओवरफ़्लो करता है?
  • क्या यह कई बार जोड़ते समय दिन-of-month को बचाए रखता है, या हर बार फिर से क्लैम्प करता है?
  • लीप साल के edge cases के लिए, 29 फरवरी + 1 साल पर क्या होता है?

Date Calculator आपको किसी भी तारीख और ऑफ़सेट के लिए बिल्कुल सटीक नतीजा दिखाता है — कोड में कोई calculation करने से पहले सेनिटी-चेक करने के लिए उपयोगी।

संबंधित लेख