1927: वह क्षण जब समय पीछे चला गया
\n\nकल्पना करें: आप Java में मिलीसेकंड में दो तिथियों के बीच अंतर की गणना करने के लिए एक सरल स्क्रिप्ट लिख रहे हैं। आप 1927 लेते हैं, एक मान को दूसरे से घटाते हैं — और 3600 सेकंड (एक घंटा) नहीं, बल्कि एक अजीब संख्या प्राप्त करते हैं। आप कोड की दोबारा जाँच करते हैं, गूगल करते हैं, और हजारों बार देखे गए StackOverflow पर प्रसिद्ध प्रश्न पाते हैं। और आप समझ जाते हैं: आप अकेले नहीं हैं।
\n\nयह बग इतिहास का एक वास्तविक अवशेष है जो आज भी नौसिखियों को डराता है। इस लेख में हम विश्लेषण करेंगे कि 1927 में epoch-milli times को घटाने पर अजीब परिणाम क्यों आता है, इसे Java कोड के वास्तविक उदाहरणों के साथ दिखाएंगे, और सबसे महत्वपूर्ण बात, इस जाल से बचने के काम करने वाले तरीके देंगे। यदि आप ऐतिहासिक डेटा के साथ काम करते हैं या बस विश्वसनीय कोड लिखना चाहते हैं — यह जानकारी आपके लिए है।
\n\nसमस्या का सार: 31 दिसंबर 1927 का जादू
\n\nआइए सीधे कोड पर आते हैं। यहाँ एक क्लासिक उदाहरण है जो दिमाग हिला देता है:
\n\nimport java.util.TimeZone;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\npublic class StrangeDateDifference {\n public static void main(String[] args) throws Exception {\n TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");\n SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");\n sdf.setTimeZone(tz);\n\n Date date1 = sdf.parse("1927-12-31 23:54:07");\n Date date2 = sdf.parse("1927-12-31 23:54:08");\n\n long diff = date2.getTime() - date1.getTime();\n System.out.println("मिलीसेकंड में अंतर: " + diff);\n // हम 1000 की उम्मीद करते हैं, लेकिन प्राप्त करते हैं...\n }\n}\n\nजब आप इसे चलाते हैं — तो 1000 मिलीसेकंड (1 सेकंड) के बजाय आपको 353 दिखाई देता है? या शायद ऋणात्मक संख्या? बधाई हो, आप 1927 की तिथियों को घटाने की त्रुटि से टकराए हैं।
\n\nइसका कारण Java में बग नहीं है (हालाँकि इसमें भी है, लेकिन उस पर बाद में)। इसका कारण समय क्षेत्र का ऐतिहासिक परिवर्तन है। 31 दिसंबर 1927 को शंघाई (Asia/Shanghai) में एक अजीब घटना हुई: 23:54:08 पर स्थानीय समय को 5 मिनट 52 सेकंड पीछे कर दिया गया। वास्तव में, एक सेकंड 1000 मिलीसेकंड नहीं, बल्कि केवल 353 मिलीसेकंड तक चला। Java ईमानदारी से इस ऐतिहासिक तथ्य को दर्शाता है, लेकिन डेवलपर के लिए यह जादू जैसा लगता है।
\n\nडेवलपर्स द्वारा की जाने वाली शीर्ष त्रुटियाँ
\n\n1. पुराने API (java.util.Date और SimpleDateFormat) पर आँख बंद करके भरोसा करना
\n\nपहली और सबसे आम गलती पुरानी कक्षाओं java.util.Date और SimpleDateFormat का उपयोग करना है। वे न केवल असुविधाजनक हैं, बल्कि उनमें छिपे हुए आश्चर्य भी हैं, खासकर ऐतिहासिक तिथियों के साथ काम करते समय।
कैसे बचें: java.time (Java 8+) का उपयोग करें। उदाहरण के लिए:
import java.time.LocalDateTime;\nimport java.time.ZoneId;\nimport java.time.ZonedDateTime;\nimport java.time.format.DateTimeFormatter;\n\npublic class SafeDateDifference {\n public static void main(String[] args) {\n DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");\n ZoneId zone = ZoneId.of("Asia/Shanghai");\n\n LocalDateTime ldt1 = LocalDateTime.parse("1927-12-31 23:54:07", formatter);\n LocalDateTime ldt2 = LocalDateTime.parse("1927-12-31 23:54:08", formatter);\n\n ZonedDateTime zdt1 = ldt1.atZone(zone);\n ZonedDateTime zdt2 = ldt2.atZone(zone);\n\n long diff = zdt2.toInstant().toEpochMilli() - zdt1.toInstant().toEpochMilli();\n System.out.println("मिलीसेकंड में अंतर: " + diff);\n // फिर भी आपको एक अजीब संख्या मिलेगी, लेकिन कम से कम आपको पता होगा कि क्यों!\n }\n}\n\n2. समय क्षेत्रों के ऐतिहासिक परिवर्तनों को अनदेखा करना
\n\nबहुत से लोग सोचते हैं कि समय क्षेत्र UTC से केवल एक निश्चित बदलाव है। लेकिन वास्तव में, पिछले 100 वर्षों में वे दर्जनों बार बदले हैं।