मुख्य सामग्री पर जाएँ

समय और भाषाएँ

यह पृष्ठ अंग्रेज़ी से अनुवादित है। अंग्रेज़ी पृष्ठ पढ़ें

तारीख़ें और समय बिज़नेस ऐप में बग का आम स्रोत हैं: जन्मदिन जो उपयोगकर्ता के यात्रा करने पर एक दिन खिसक जाता है, शिफ़्ट जो घड़ी बदलने के बाद एक घंटा देर से शुरू होती है। Zeyn हर प्रकार के मान को अपना टाइप देता है, इसलिए कंपाइलर उन्हें अलग रखता है।

चार टाइप

टाइपक्या हैउदाहरण
Dateकैलेंडर का दिन, बिना क्षेत्रजन्मदिन, इनवॉइस की तारीख़
Timeदीवार घड़ी का समय, बिना क्षेत्रखुलने का समय
DateTimeएक सटीक क्षण, UTC में सहेजा गयारिकॉर्ड कब बना
LocalDateTimeकिसी जगह की दीवार घड़ी की तारीख़ और समयइस्तांबुल में 14:00 पर अपॉइंटमेंट

कैलेंडर के दिन को कभी क्षण के रूप में न सहेजें। Date हर क्षेत्र में वही दिन है; DateTime हर जगह वही क्षण है और हर क्षेत्र में अलग दीवार घड़ी का समय दिखाता है।

let day = Date::new(2026, 3, 29).unwrap_or_default();
let at = Time::new(9, 30, 0).unwrap_or_default();
let slot = LocalDateTime::new(day, at);
let zone = TimeZone::named("Europe/Istanbul").unwrap_or(TimeZone::UTC);
let moment = DateTime::from_local(slot, zone)?;
let back = moment.local(zone);

DateTime::from_local ऐसे दीवार घड़ी के समय के लिए, जो क्षेत्र में मौजूद नहीं है, जैसे वसंत में घड़ी बदलने के दौरान, अंदाज़ा लगाने के बजाय विफल होता है।

घड़ी

ctx.now() और ctx.today() इस्तेमाल करें, कभी सिस्टम घड़ी नहीं। ctx.today() उपयोगकर्ता के क्षेत्र में आज है। टेस्ट App::fixed_now(moment) से हर अनुरोध के लिए घड़ी तय करते हैं।

समय क्षेत्र

App::new(t!("app.name"))
    .time_policy(TimePolicy::User { default: TimeZone::named("Europe/Istanbul").unwrap_or(TimeZone::UTC) })
    .time_zone_picker()
नीतिक्षण किसमें दिखाए जाते हैं
TimePolicy::User { default }वह क्षेत्र जो उपयोगकर्ता का ब्राउज़र बताता है, या जब तक वह न बताए तब तक default
TimePolicy::Organization(zone)सबके लिए एक क्षेत्र

.time_zone_picker() मेनू में चयनकर्ता जोड़ता है ताकि उपयोगकर्ता हाथ से क्षेत्र चुन सकें। सिंगल साइन ऑन प्रॉक्सी भी क्षेत्र को हेडर में भेज सकता है (ForwardAuth::time_zone)। DateTime कॉलम पर ग्रिड फ़िल्टर उपयोगकर्ता के क्षेत्र में पढ़े जाते हैं।

पिकर

तारीख़, समय और तारीख़-समय फ़ील्ड को कीबोर्ड के अनुकूल पिकर मिलते हैं। DateOptions सीमित करता है कि क्या चुना जा सकता है:

Form::of(visit)
    .row(|r| r.field(Visit::day).field(Visit::arrives))
    .range(Visit::stay_from, Visit::stay_to)
    .date_options(Visit::day, DateOptions::new().no_weekends().week_numbers())
    .date_options(Visit::arrives, DateOptions::new().step_minutes(15))

प्रारूप: 2024-12-31। आप यह भी टाइप कर सकते हैं: आज, +3d।

प्रारूप: 14:30। आप यह भी टाइप कर सकते हैं: अभी, 930।

प्रारूप: 2024-12-31 14:30। आप यह भी टाइप कर सकते हैं: आज, +3d।

प्रारूप: 2024-12-31। आप यह भी टाइप कर सकते हैं: आज, +3d।

भाषा चुनना

सर्वर भाषा zeyn_locale कुकी से चुनता है, फिर ब्राउज़र के Accept-Language से, फिर ऐप के डिफ़ॉल्ट से। <html lang> हमेशा मेल खाता है। मेनू में भाषा चयनकर्ता कुकी सेट करता है और पृष्ठ को बिना रीलोड के उसी जगह बदल देता है।

App::locale_paths() के साथ भाषा URL का हिस्सा बन जाती है: डिफ़ॉल्ट भाषा /orders पर रहती है, बाकी भाषाओं को /tr/orders या /ar/orders मिलता है। भाषा केवल पथ से तय होती है, इसलिए साझा किया गया लिंक उसी भाषा में खुलता है, और हर Screen का अब भी एक ही route होता है और वह भाषा ctx.locale() से पढ़ता है। मेनू के लिंक भाषा बनाए रखते हैं, और चयनकर्ता उसी पृष्ठ को बिना रीलोड के दूसरी भाषा में खोलता है। अरबी और दाएँ से बाएँ लिखी जाने वाली दूसरी भाषाओं को <html dir="rtl"> मिलता है। किसी सार्वजनिक पृष्ठ की भाषाएँ खोज इंजनों को Screen::alternate("tr", "/tr/orders") से बताएँ।

संख्याएँ, मुद्रा और तारीख़ें

मान सर्वर पर उपयोगकर्ता की भाषा के लिए स्वरूपित होते हैं: तुर्की में 1.234,56 और अंग्रेज़ी में 1,234.56, तारीख़ें 29.03.2026 या 3/29/2026 के रूप में, और मुद्रा अपने करेंसी चिह्न के साथ। इनपुट वही प्रारूप वापस पढ़ते हैं।

Money पूर्णांक न्यूनतम इकाइयाँ और करेंसी रखता है, इसलिए योग में कभी एक पैसा नहीं खोता:

let price = Money::tl(2_500_000);
let text = price.format("tr");