شمسی برای رابط، میلادی برای دیتابیس، و یک انتخابگرِ تاریخی که کاربر را اذیت نکند — یک تصمیمنامهٔ کوتاه برای سازندگانِ محصولِ فارسیزبان.
در طولِ چند سالِ گذشته با دهها سازندهٔ محصولِ ایرانی نشستهام و یک سؤالِ بهظاهر کوچک، تقریباً همیشه روی میز بوده است: «تاریخ را شمسی نشان بدهیم یا میلادی؟» این سؤال کوچک نیست. تاریخ یکی از معدود چیزهایی است که در محصولِ فارسیزبان، اگر اشتباه نمایش داده شود، کاربر در همان ثانیهٔ اول حس میکند که محصول برای او ساخته نشده است. اما برعکس هم درست است: اگر فقط شمسی نگه دارید و بعد بخواهید با یک API خارجی صحبت کنید، در ماهِ سوم به دیواری میخورید که کندنش گران تمام میشود.
این یادداشت یک تصمیمنامهٔ کوتاه است. نه فلسفهٔ تقویم، نه تاریخچهٔ هجری شمسی. فقط همان چیزی که خودم وقتی محصولی را از صفر میسازم، روی کاغذ مینویسم و به آن پایبند میمانم.
سؤالِ اول — مخاطبِ شما کجا زندگی میکند
پیش از هر تصمیمِ فنی، یک پرسشِ خیلی ساده از خودتان بپرسید: «این محصول را چه کسی، در کجا، و در چه بستری استفاده میکند؟» جوابِ این سؤال، نود درصدِ بحثِ تقویم را تمام میکند.
اگر محصولتان یک ابزارِ داخلیِ ایرانی است — مثلاً سامانهٔ حضور و غیابِ یک شرکتِ تهرانی، یا یک اپلیکیشنِ مدیریتِ کلاس برای آموزشگاههای زبان، یا یک ابزارِ تقسیمِ صورتحساب بینِ همخانهایها — هر تاریخی که کاربر میبیند باید شمسی باشد. نقطه. کاربرِ ایرانی وقتی میخواهد بفهمد «جلسهٔ بعدی کِی است»، در ذهنش «۱۵ آبان» میگوید، نه «6 November». اصرار بر نمایشِ میلادی در این بستر، یعنی شما تصمیم گرفتهاید کاربرتان هربار یک ترجمهٔ ذهنی انجام بدهد. این ترجمه ارزان نیست.
اگر محصولتان دوزبانه است یا روزی قرار است به خارج از ایران برسد، داستان فرق میکند، ولی به همان اندازه ساده است: تقویم تابعِ زبانِ رابط میشود. وقتی کاربر زبانِ فارسی را انتخاب کرد، شمسی میبیند؛ وقتی انگلیسی را انتخاب کرد، میلادی. این یعنی شما لازم نیست در یک رابطِ فارسی «تاریخِ میلادی هم در پرانتز» نشان بدهید — این کار صرفاً شلوغی است، نه احترام به کاربرِ بینالمللی.
تنها استثنای جدی، محصولاتی هستند که موضوعشان ذاتاً جهانی است: یک ابزارِ توسعهدهنده که با کامیتِ گیتهاب کار میکند، یا یک داشبوردِ تحلیلی که با Stripe و سرویسهای مشابه حرف میزند. آنجا کاربرِ ایرانی هم انتظار دارد تاریخِ یک کامیت را میلادی ببیند، چون مرجعِ اصلی آن داده میلادی است. در دستهٔ ابزارهای توسعهدهنده (mahsoolhunt.ir/categories/devtools) این الگو را بارها دیدهام.
نمایش در رابط — قاعدهای ساده برای فهرستها و گزارشها
برای نمایشِ تاریخ در رابط، یک قاعدهٔ سهسطحی دارم که تقریباً همیشه جواب میدهد.
سطحِ اول، تاریخهای نزدیک. هر چیزی که در هفت روزِ گذشته یا هفت روزِ آینده اتفاق افتاده، باید نسبی نوشته شود: «دیروز»، «امروز»، «فردا»، «سهشنبهٔ گذشته»، «۲ ساعت پیش». این فرمت زبانِ ذهنیِ کاربر است و نه شمسی است نه میلادی — فقط انسانی است. اینجا اصلاً درگیرِ بحثِ تقویم نشوید.
سطحِ دوم، تاریخهای میانمدت. هر چیزی که از یک هفته دورتر است ولی هنوز در همان سال است: «۱۲ آبان». بدونِ سال. ساده، کوتاه، و دقیقاً همانطور که کاربرِ فارسیزبان وقتی به دوستش پیامک میدهد مینویسد. ماه را با حروف بنویسید، نه با عدد. «۸/۱۲» در فارسی هیچوقت آن خواناییای را که در ذهنتان هست ندارد، چون نمیدانیم اول ماه است یا روز.
سطحِ سوم، تاریخهای دور. هر چیزی که از سالِ جاری بیرون است: «۱۲ آبان ۱۴۰۳». سال را اضافه کنید، ولی فقط همان موقع. اضافهکردنِ سال به همهجا، رابط را پیر و رسمی میکند.
برای گزارشها و خروجیهای CSV یا PDF که قرار است بعداً بایگانی شوند، همیشه فرمتِ بلندِ کامل را بهکار ببرید: «دوشنبه، ۱۲ آبان ۱۴۰۳». این فرمت در آینده، وقتی کاربر فایل را شش ماه بعد باز میکند، هیچ ابهامی باقی نمیگذارد.
ذخیره در پایگاه داده — چرا میلادی هنوز انتخابِ امن است
اینجا جایی است که خیلی از سازندگانِ تازهکار اشتباه میکنند. وقتی محصولشان قرار است فقط برای کاربرِ ایرانی باشد، وسوسه میشوند تاریخ را بهصورتِ شمسی در دیتابیس ذخیره کنند. نکنید.
تاریخ را همیشه بهصورتِ UTC و در فرمتِ ISO 8601 (مثلِ `2025-11-03T14:30:00Z`) ذخیره کنید. تبدیل به شمسی فقط در لایهٔ نمایش اتفاق میافتد. دلیلش سه چیز است.
اول، هر کتابخانهٔ تاریخی که در دنیا نوشته شده، با میلادی کار میکند. اگر بخواهید بازهٔ زمانی بگیرید، مرتبسازی کنید، یا اختلافِ دو تاریخ را حساب کنید، با شمسیِ ذخیرهشده باید چرخ را از نو اختراع کنید. دوم، هر سرویسِ ثالثی که با آن صحبت میکنید — از درگاهِ پرداختِ ایرانی گرفته تا سرویسِ ارسالِ پیامک — تاریخ را میلادی برمیگرداند. سوم، روزی که تصمیم بگیرید محصولتان چندزبانه بشود، اگر دادهٔ پایهتان میلادی باشد، فقط لایهٔ نمایش را عوض میکنید. اگر شمسی باشد، باید کلِ دیتابیس را مهاجرت بدهید.
برای تبدیل، در جاوااسکریپت کتابخانهٔ `date-fns-jalali` یا `dayjs` با پلاگینِ jalaliday بهقدرِ کافی پختهاند. در پایتون، `jdatetime`. ابزارِ خاصی نمیخواهد، فقط یک تصمیمِ معماری.
ورودیِ کاربر — انتخابگرِ تاریخی که اذیت نکند
انتخابگرِ تاریخ (date picker) جایی است که اغلبِ محصولاتِ فارسیزبان از پا درمیآیند. یا یک تقویمِ میلادی را با چند خط CSS فارسی کردهاند که اعدادش راستچین نیست و ماههایش هنوز نوامبر و دسامبر است، یا یک کامپوننتِ سنگین آوردهاند که سه ثانیه طول میکشد تا باز شود.
سه اصل را همیشه رعایت کنید. اول، در یک رابطِ فارسی، انتخابگر باید شمسی، راستبهچپ، با اعدادِ فارسی (یا حداقل با ترتیبِ درست) باز شود. کاربر نباید برای پیدا کردنِ «آبان» در فهرستی به نامِ November چشمش را تنگ کند. دوم، همیشه یک ورودیِ متنی در کنارِ انتخابگر بگذارید. کاربری که میداند تاریخِ تولدش «۱۲ مهرِ ۶۸» است، نباید مجبور شود سی و چند سال در تقویم عقب برود. تایپِ مستقیم سریعتر است. سوم، روزِ جمعه را بهصورتِ پیشفرض با رنگِ متفاوت نشان بدهید — جمعه در ایران معادلِ یکشنبه است، نه شنبه.
اگر محصولتان رزروِ زمان دارد، حتماً به منطقهٔ زمانیِ تهران قفل کنید، نه به منطقهٔ زمانیِ مرورگرِ کاربر. کاربری که با VPN وصل است و سرورِ خروجیاش در آمستردام است، اگر ساعتِ ۱۵ تهران را رزرو کند ولی سیستم ۱۵ آمستردام را ثبت کند، بازی تمام است.
موارد لبه — تعطیلات، جمعه و تقویمِ کاری
چند نکتهٔ ریز که در محصولاتِ جدی اهمیت پیدا میکنند.
تعطیلاتِ رسمی در ایران ثابت نیستند. تعطیلاتِ مذهبی هر سال چند روز جابهجا میشوند، و دولت هم گاهی تعطیلاتِ اضطراری اعلام میکند. اگر محصولتان به مفهومِ «روزِ کاری» وابسته است — مثلاً برای تحویلِ سفارش یا محاسبهٔ روزهای مرخصی — یک جدولِ تعطیلات نگه دارید که سالی یکبار بهروز میشود. به محاسبهٔ خودکار اعتماد نکنید.
هفته در ایران از شنبه شروع میشود و جمعه تعطیلِ رسمی است. پنجشنبه در بسیاری از سازمانها نیمهتعطیل است. هیچ کتابخانهٔ خارجی این را بهصورتِ پیشفرض نمیداند. وقتی تقویمِ هفتگی نشان میدهید، ستونِ اول باید شنبه باشد. این یک تنظیمِ یکخطی است، اما فراموششدنش رابط را بیگانه میکند.
و آخر، نوشتارِ تاریخ. «۱۲ آبانِ ۱۴۰۳» با کسرهٔ اضافهٔ بعد از «آبان» درست است، نه «۱۲ آبان ۱۴۰۳». این همان جنسِ ظرافتی است که در راهنمای نیمفاصله نوشتم (mahsoolhunt.ir/rozname/persian-typography-half-space-fundamentals)؛ تاریخ هم بخشی از تایپوگرافی است، نه فقط داده.
اگر محصولی میسازید که با تاریخ سروکار دارد و میخواهید نگاهی به اینکه دیگران در دستهٔ اپلیکیشنها چه کردهاند بیندازید، فهرستِ mahsoolhunt.ir/categories/apps جای خوبی برای شروع است. و اگر خودتان محصولی دارید که این تصمیمها را با دقت گرفتهاید، در mahsoolhunt.ir/submit ثبتش کنید — این جنس از دقتِ ریز، دقیقاً چیزی است که در روزنامه دوست دارم دربارهاش بنویسم.