Author:
    Creation:2026-09-02Last update:2026-09-02

    Intl के साथ लोकेल के अनुसार दिनांक और संख्याओं को फॉर्मेट करना

    स्ट्रिंग्स का अनुवाद करना अंतर्राष्ट्रीयकरण (i18n) का केवल दृश्यमान हिस्सा है। दूसरा हिस्सा जो लगातार बग रिपोर्ट उत्पन्न करता है, वह है फ़ॉर्मेटिंग: एक जर्मन उपयोगकर्ता 1.234,56 के बजाय 1,234.56 देखता है, एक जापानी उपयोगकर्ता 08/02/2026 को देखता है और इसे अगस्त समझता है, या एक तारीख जो सर्वर और क्लाइंट पर अलग-अलग रेंडर होती है और React के हाइड्रेशन को विफल कर देती है।

    इनमें से किसी के लिए भी लाइब्रेरी की आवश्यकता नहीं है। Intl प्रत्येक आधुनिक रनटाइम में पहले से उपलब्ध है।

    विषय सूची

    अपने हाथ से लिखे दिनांक सहायक फ़ंक्शन को हटाने से शुरुआत करें

    लगभग हर कोडबेस में एक formatDate फ़ंक्शन होता है जो लोकेल के बारे में सोचने से पहले लिखा गया था। यह एक निश्चित क्रम, एक विभाजक और आमतौर पर अंग्रेज़ी महीने के नामों को हार्डकोड करता है।

    ts
    // जिसे आपको हटाना चाहिए:
    const formatDate = (d: Date) =>
      `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`;
    

    Intl.DateTimeFormat इसे पूरी तरह बदल देता है और हर लोकेल में सही परिणाम देता है:

    ts
    new Intl.DateTimeFormat("de-DE", { dateStyle: "long" }).format(date);
    // "2. August 2026"
    new Intl.DateTimeFormat("ja-JP", { dateStyle: "long" }).format(date);
    // "2026年8月2日"
    

    यही बात संख्याओं पर भी लागू होती है। toFixed(2) हर जगह 1234.56 उत्पन्न करता है, जो अधिकांश यूरोप में गलत है।

    Intl क्या कवर करता है

    API इसके लिए उपयोग करें
    Intl.DateTimeFormat दिनांक और समय, dateStyle / timeStyle प्रीसेट के साथ
    Intl.NumberFormat दशमलव, मुद्रा, प्रतिशत, इकाइयाँ, संक्षिप्त संकेतन
    Intl.RelativeTimeFormat "3 दिन पहले", "2 घंटे में"
    Intl.ListFormat "क, ख और ग" की सूची फॉर्मेटिंग
    Intl.PluralRules यह तय करना कि कोई संख्या किस बहुवचन श्रेणी में आती है
    Intl.Collator भाषा के अनुसार स्ट्रिंग्स को सही ढंग से क्रमबद्ध करना

    Intl.Collator वह है जिसे लोग अक्सर भूल जाते हैं। स्ट्रिंग्स पर सादा array.sort() यूनिकोड कोड पॉइंट क्रम का उपयोग करता है, जिससे उच्चारण वाले अक्षर z के बाद चले जाते हैं। यदि आप उपयोगकर्ताओं को दिखने वाली सूचियों को सॉर्ट करते हैं, तो हमेशा एक collator का उपयोग करें।

    ts
    ["zebra", "édouard", "apple"].sort(new Intl.Collator("hi").compare);
    // ["apple", "édouard", "zebra"]
    

    हाथ से बनाए गए विकल्पों की तुलना में प्रीसेट को प्राथमिकता दें

    dateStyle और timeStyle लोकेल को क्रम और विभाजक तय करने की अनुमति देते हैं। year, month और day को अलग-अलग निर्दिष्ट करना आपको ऐसा नियंत्रण देता है जो आमतौर पर नहीं होना चाहिए, क्योंकि सही क्रम लोकेल के अनुसार भिन्न होता है और आप अपनी मान्यताओं के साथ CLDR डेटा को अधिलेखित कर रहे होते हैं।

    ts
    // लोकेल संरचना तय करता है:
    new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(d);
    
    // जब आप संरचना तय करते हैं, तो यह अन्य क्षेत्रों में गलत हो जाता है:
    new Intl.DateTimeFormat(locale, {
      year: "numeric",
      month: "2-digit",
      day: "2-digit",
    }).format(d);
    

    स्पष्ट घटकों का उपयोग केवल तभी करें जब डिज़ाइन को वास्तव में एक निश्चित चौड़ाई की आवश्यकता हो, उदाहरण के लिए एक संकीर्ण तालिका कॉलम।

    फ़ॉर्मेटर बनाना महंगा है

    यह प्रदर्शन विवरण है जो मायने रखता है। Intl.NumberFormat का निर्माण लोकेल डेटा लोड करता है, और यह बाद के .format() कॉल से कहीं अधिक महंगा है। एक हजार पंक्तियों पर लूप के अंदर ऐसा करने से ध्यान देने योग्य धीमापन आता है।

    ts
    // प्रत्येक पंक्ति पर फ़ॉर्मेटर का पुनर्निर्माण (धीमा):
    rows.map((r) => new Intl.NumberFormat(locale).format(r.total));
    
    // एक बार बनाएं, पुन: उपयोग करें (तेज़):
    const nf = new Intl.NumberFormat(locale);
    rows.map((r) => nf.format(r.total));
    

    toLocaleDateString() और toLocaleString() के अंदर भी यही समस्या छिपी है: प्रत्येक कॉल एक नया फ़ॉर्मेटर बनाता है। वे एक मान के लिए ठीक हैं और सूची के लिए गलत हैं।

    लोकेल और विकल्पों के संयोजन द्वारा कैश करें:

    ts
    const cache = new Map<string, Intl.NumberFormat>();
    
    const getNumberFormat = (
      locale: string,
      options: Intl.NumberFormatOptions = {}
    ) => {
      const key = `${locale}:${JSON.stringify(options)}`;
      let formatter = cache.get(key);
      if (!formatter) {
        formatter = new Intl.NumberFormat(locale, options);
        cache.set(key, formatter);
      }
      return formatter;
    };
    

    टाइमज़ोन बग जो केवल उत्पादन में दिखाई देता है

    यह समस्या कई डेवलपर घंटे बर्बाद करती है। सर्वर SSR के दौरान एक तारीख प्रस्तुत करता है, ब्राउज़र इसे हाइड्रेट करता है, और React एक हाइड्रेशन बेमेल फेंकता है क्योंकि दोनों ने अलग-अलग पाठ उत्पन्न किया है।

    कारण यह है कि Intl.DateTimeFormat परिवेशी समय क्षेत्र का उपयोग करता है जब आप किसी एक का नाम नहीं देते हैं। आपका उत्पादन सर्वर UTC में चलता है। आपका लैपटॉप नहीं। इसलिए यह बग स्थानीय स्तर पर अदृश्य है और केवल उत्पादन में ही सामने आता है।

    ts
    // UTC में सर्वर और UTC+5:30 में ब्राउज़र असहमत हैं। हाइड्रेशन बेमेल:
    new Intl.DateTimeFormat(locale, { dateStyle: "short" }).format(d);
    
    // दोनों पूरी तरह सहमत हैं:
    new Intl.DateTimeFormat(locale, { dateStyle: "short", timeZone: "UTC" }).format(
      d
    );
    

    तीन व्यावहारिक दृष्टिकोण:

    • सर्वर पर टाइमज़ोन को पिन करें और इसे स्पष्ट रूप से पास करें। सटीक और नियतात्मक, लेकिन हर कोई UTC देखता है।
    • केवल क्लाइंट पर रेंडर करें, सर्वर पास के लिए एक स्थिर प्लेसहोल्डर के साथ। उपयोगकर्ता के लिए सटीक, लेकिन हल्का फ़्लैश होता है।
    • उपयोगकर्ता के टाइमज़ोन को संग्रहीत करें और इसे दोनों पक्षों पर पास करें। सबसे अच्छा परिणाम, अधिक काम।

    आप जो भी चुनें, सर्वर और क्लाइंट दोनों पर प्रस्तुत की गई किसी भी तारीख के लिए हमेशा timeZone स्पष्ट रूप से पास करें। बिना टाइमज़ोन की तारीख दो मानों वाली तारीख होती है।

    मुद्रा को मुद्रा की आवश्यकता है, लोकेल की नहीं

    लोकेल और मुद्रा स्वतंत्र हैं। fr-FR का अर्थ यूरो नहीं है: एक फ्रांसीसी उपयोगकर्ता USD इनवॉइस देख सकता है।

    ts
    new Intl.NumberFormat("fr-FR", { style: "currency", currency: "USD" }).format(
      1234.5
    );
    // "1 234,50 $US"
    

    लोकेल विभाजक, अंक समूहीकरण और प्रतीक प्लेसमेंट को नियंत्रित करता है। मुद्रा आपके डेटा से आती है। एक से दूसरे का अनुमान लगाना एक बग है जो लेखांकन तक पहुँचता है।

    currencyDisplay पर भी ध्यान दें। ऐसे इंटरफ़ेस में जहाँ कई डॉलर मुद्राएँ सह-अस्तित्व में हैं, "code" अमेरिकी, कनाडाई और ऑस्ट्रेलियाई डॉलर के बीच अस्पष्टता को दूर करता है।

    सापेक्ष समय पूर्ण समय से बेहतर पढ़ा जाता है

    किसी भी हालिया घटना के लिए, "2 घंटे पहले" एक सटीक टाइमस्टैम्प से बेहतर होता है, और Intl.RelativeTimeFormat इसे ठीक से स्थानीयकृत करता है।

    ts
    new Intl.RelativeTimeFormat("hi", { numeric: "auto" }).format(-1, "day");
    // "कल"
    

    numeric: "auto" वह है जो "1 दिन पहले" के बजाय "कल" उत्पन्न करता है।

    Intlayer क्या जोड़ता है

    Intlayer इन्हें कैश्ड हेल्पर्स में लपेटता है ताकि आपको ऊपर दिए गए मैप को मैन्युअल रूप से प्रबंधित न करना पड़े, और सक्रिय लोकेल हर कॉल साइट पर पास होने के बजाय डिफ़ॉल्ट रूप से लागू हो।

    ts
    import {
      number,
      currency,
      date,
      relativeTime,
      units,
      compact,
      list,
    } from "intlayer";
    
    number(1234.5); // "1,234.5"
    currency(1234.5, { currency: "EUR" }); // "€1,234.50"
    date(new Date(), "short");
    relativeTime(now, twoHoursAgo, { unit: "hour", numeric: "auto" }); // "2 घंटे पहले"
    units(5, { unit: "kilometer", unitDisplay: "long" }); // "5 किलोमीटर"
    compact(1200); // "1.2K"
    list(["सेब", "केला", "संतरा"]); // "सेब, केला और संतरा"
    

    date() फ़ंक्शन प्रीसेट ("short", "long", "dateOnly", "timeOnly", "full") भी स्वीकार करता है। React और Vue के समकक्ष हुक और कंपोज़ेबल संदर्भ से सक्रिय लोकेल को हल करते हैं।

    यह प्लेटफ़ॉर्म API पर एक कुशल कैशिंग परत है। वास्तविक फ़ॉर्मेटिंग व्यवहार पूरी तरह से Intl है। पूर्ण हस्ताक्षर फ़ॉर्मेटर्स दस्तावेज़ में देखें।

    सामान्य गलतियाँ

    • बिना लोकेल के toLocaleDateString(). रनटाइम के डिफ़ॉल्ट का उपयोग करता है, जो सर्वर पर कंटेनर कॉन्फ़िगरेशन पर निर्भर करता है।
    • बिना कैश के लूप में फ़ॉर्मेट करना। फ़ॉर्मेटर का निर्माण अधिकांश लागत लेता है। एक बार बनाएं।
    • आइसोमॉर्फिक तिथियों पर कोई timeZone नहीं। हाइड्रेशन बेमेल जो आपके स्थानीय सिस्टम पर कभी प्रकट नहीं होता।
    • लोकेल से मुद्रा का अनुमान लगाना। fr-FR हमेशा यूरो नहीं होता है।
    • दृश्यमान स्ट्रिंग्स पर सादा sort(). हमेशा Intl.Collator का उपयोग करें।
    • महीने या दिन के नामों को हार्डकोड करना। वे हर भाषा के लिए CLDR में पहले से ही उपलब्ध हैं।
    • सापेक्ष समय के लिए numeric: "always" बनाए रखना। इससे "कल" के बजाय अप्राकृतिक "1 दिन पहले" मिलता है।

    आगे पढ़ें

    टिप्पणियाँ

    अभी तक कोई टिप्पणी नहीं। अपने विचार साझा करने वाले पहले व्यक्ति बनें।

    संबंधित पोस्ट

    नवीनतम पोस्ट