ورود

View Full Version : درج تاریخ شمسی به فرمت DateTime در دیتابیس



m_amin_t
چهارشنبه 05 دی 1386, 14:17 عصر
سلام
برنامه من با تاریخ شمسی کار میکنه و یکی از مهمترین کارهاش جستجو بین تاریخهای موجود در دیتابیسه. من چطور میتونم این تاریخ ها رو در دیتابیس ذخیره کنم به شرطی که بعدا امکان جستجو بین دو تارخ مشخص رو داشته باشم. وقتی در دیتابیس فرمت DateTime رو انتخاب میکنم در درج تاریخ شمسی خطایی میده که تاریخ باید بین 1753 تا 9999 باشه. اگر هم بخوام به صورت یک string ذخیره ش کنم در هنگام جستجو مشکل پیش میاد و نمیدونم چطور جستجو رو انجام بدم.
ممنون میشم اگه راهنماییم کنید.

JAFO_IRAN
چهارشنبه 05 دی 1386, 15:02 عصر
سلام

یک روش قابل تصور اینه که اصولا تاریخها رو به صورت میلادی ذخیره کنی و بعد در لایه ui فقط در زمان بازنمایی یا درج یا اخذ اطلاعات تبدیل رو انجام بدی - قاعدتا در client ابزارهای لازم برای کار با تاریخ شمسی و تبدیل به میلادی (و برعکس) از قبل درست شده‌اند. این روش نتیجه بسیار دقیق رو در سطح db به شما خواهد داد.

ارادت

m_amin_t
چهارشنبه 05 دی 1386, 15:15 عصر
ولی اینکار مشکل چندتا مشکل به وجود بیاره. مثلا پایین اومدن سرعت برنامه. یا اینکه وقتی از sp استفاده میکنیم دیگه چنین کاری امکان پذیر نیست (یا من بلد نیستم!)

JAFO_IRAN
چهارشنبه 05 دی 1386, 18:14 عصر
ولی اینکار مشکل چندتا مشکل به وجود بیاره. مثلا پایین اومدن سرعت برنامه. یا اینکه وقتی از sp استفاده میکنیم دیگه چنین کاری امکان پذیر نیست (یا من بلد نیستم!)

اولا که اصلا فکر سرعت رو نکنید - زمان پردازشهای تبدیل نسبت به اینکه از نوع داده غیر از DateTime استفاده کنید کاملا قابل صرف نظر هستند.

در مورد spها هم فقط یک مشکل جدی ممکنه پیش بیاد و اون هم در صورتی که در منطق پردازش با مفاهیم تاریخ فارسی سر و کار داشته باشید: مثلا بدست آوردن اجزای یک تاریخ (مثل شماره ماه) یا بدست آوردن تاریخ متناظر با یک تاریخ در ماه یا سال بعدی - این آخری، به خصوص به علت تفاوت مفهوم سال کبیسه بین شمسی و میلادی دشوار هم هست.

متاسفانه در این موارد باید خیلی مراقب باشید که ساختار و معنی فرض شده برای تاریخ شمسی بین client و sp دقیقا یکسان باشند. راه حل داره ولی خوب حق دارید، اصلا راحت نیست.

اگر مواردی که گفتم در spهای شما پیش نمیاد، به نظر من اصلا شک نکنید و در db از تاریخ میلادی استفاده کنید. اگر نه، حتی شاید بشه دردسر نوشتن توابع لازم در db رو تحمل کرد ولی باز انتخاب با شما است....

ارادت

sinpin
چهارشنبه 05 دی 1386, 18:36 عصر
من قبلا هم این پیشنهاد رو داده بودم :
من خودم معمولا تاریخ رو به هر دوشکل در دیتابیس ذخیره میکنم (اما به این شرط که تعداد رکوردها خیلی زیاد نباشه). توجه داشته باشید که بعضی وقتها با نقض قوانین نرمالسازی روشهای بهینه تری برای طراحی دیتابیس پیدا میکنیم (مخصوصا زمانیکه جایی زندگی کنیم که دنیا برخی از کمیت های زندگی ما رو - مثل تاریخ یا زبان - به رسمیت نشناخته باشه!)

ذخیره تاریخ به هر دوشکل چند مزیت داره (که اغلب به performane برمیگردن) :
1- در گرید ها ، گزارشها و ... بدون افت سرعت تاریخ رو شمسی نشون میدید
2- برای انجام مقایسه و سایر عملیات تاریخی از توابع میلادی درونکار استفاده میکنید.
3- و ...

برای اینکار :
توی برنامه تاریخ رو به کاربر شمسی نشون بدید اما هنگامی که تغییر یا درجی شکل گرفت به هر دوشکل تاریخ رو در دو فیلد مجزا در دیتابیس ذخیره کنید

دوستان اگه نظر یا انتقادی دارند خوشحال میشم بشنوم.

SYNDROME
چهارشنبه 05 دی 1386, 19:27 عصر
می توانید تاریخ را به صورت رشته ذخیره کنید.
همه روشهای دوستان مناسب است ولی بستگی به برنامه شما دارد که نیاز به چه نوع داده ای داشته باشید و چه استفاده بخواهید بکنید.
موفق باشید

JAFO_IRAN
پنج شنبه 06 دی 1386, 06:08 صبح
سلام


دوستان اگه نظر یا انتقادی دارند خوشحال میشم بشنوم.

قبلا از اینکه پاسخ کمی طولانی شده پوزش میخوام - ولی کماکان امیدوارم باعث خوشحالی بشه.


من خودم معمولا تاریخ رو به هر دوشکل در دیتابیس ذخیره میکنم (اما به این شرط که تعداد رکوردها خیلی زیاد نباشه).


integrity داده‌ها چی میشه؟ چه تضمینی وجود داره که دو تا مقدار با هم match بمونند؟ اگه منطق تاریخ فارسی در db پیاده نشده باشه نمیشه از تریگر برای این منظور استفاده کرد


توجه داشته باشید که بعضی وقتها با نقض قوانین نرمالسازی روشهای بهینه تری برای طراحی دیتابیس پیدا میکنیم (مخصوصا زمانیکه جایی زندگی کنیم که دنیا برخی از کمیت های زندگی ما رو - مثل تاریخ یا زبان - به رسمیت نشناخته باشه!)


1. نرمال سازی و نقض اون، در مورد داده‌های تشکیل دهنده "رابطه" تعریف میشه - تکرار کردن هر داده در db که نقض نرمال سازی نیست.
2. تاریخ شمسی یک مفهوم مجرد هست که باید در لایه‌های مختلف سیستم به درستی تعریف شده باشه. مهم تر از همه وظیفه ui هستش که یک قرارداد رو برای بازنمایی و اخذ تاریخ لحاظ کنه - از نظر db تاریخ یک عدد اعشاری معمولیه. همین الان هم درگیر شدن db با "مفهوم" و "معنی" تاریخ بعضی جاها حتی در تاریخ‌های میلادی هم یک سردردهای خفیفی ایجاد میکنه - مثلا وقتی با دلفی کار کنیم با 3 جور تاریخ مواجه میشیم ک یکیش برای فایل‌ها تعریف شده، یکیش برای پردازشهای داخلی دلفی و یکیش هم همونه که در یک فیلد از db درج میشه.
3. کاملا off topic: دنیا کمترین مشکل رو با زبان فارسی میداشت - اگر ما فارسی زبانها در موقع مناسب دست از سر این خط عربی برمیداشتیم. این خط برای زبانهای سامی مناسبه و اصلا به درد زبان فارسی که پیشرفته ترین زبان دربین زبانهای هند و اروپایی هستش نمیخوره.
4. اما به هر حال، اگر خط عربی رو حفظ میکنیم، پس غرورمون رو هم کم کنیم و از ک و ی عربی به جای فارسی استفاده کنیم. اونوقت تقریبا هیچ مشکلی با SQL Server نخواهیم داشت (به جز اینکه برادران عرب زبان انتهای الفبا رو به صورت ن ه و ی مرتب میکنند).



ذخیره تاریخ به هر دوشکل چند مزیت داره (که اغلب به performane برمیگردن) :
1- در گرید ها ، گزارشها و ... بدون افت سرعت تاریخ رو شمسی نشون میدید


ببینید، تقریبا در هیچیک از لایه های ui که الان هست نمیشه عین آنچه که مثلا با ADO از سرور دریافت میشه رو به عنوان تاریخ نمایش داد. اصلا تاریخ به صورت text از سرور دریافت نمیشه. حتما فرمت میشه (عدد ما به ازای تاریخ به یک string تبدیل میشه). حال ما میخواهم این عمل را با یک عمل معادل "جایگزین" کنیم. من با دلفی کار میکنم و در اونجا به صورت تضمینی میگم که اگر از یک تعریف مفهومی ساده و مرتب برای تاریخ‌های شمسی استفاده شده باشد (مثلا فاصله روزهای تاریخ از اول فروردین سال شمسی هجرت) میشه با همون سرعت و با حفظ 99 درصد performance تاریخ شمسی رو فرمت کرد.



2- برای انجام مقایسه و سایر عملیات تاریخی از توابع میلادی درونکار استفاده میکنید.


تنها مشکلی که در پست های قبلی به اونها اشاره شد مربوط به stored proc ها و سایر کدهایی بود که باید در سرور نوشته شوند. اگر این بحث مطرح نبود، اصلا شکی در کفایت تاریخ میلادی نداشتیم - در روش شما اون مشکل که هنوز سرجای خودش میمونه.

باز هم در خدمت هستیم - پوزش از پاسخ طولانی

ارادت

sinpin
پنج شنبه 06 دی 1386, 09:35 صبح
ممنونم از پاسخی که دادید.


integrity داده‌ها چی میشه؟ چه تضمینی وجود داره که دو تا مقدار با هم match بمونند؟ اگه منطق تاریخ فارسی در db پیاده نشده باشه نمیشه از تریگر برای این منظور استفاده کرد


خب همونطور که قبلا گفتم: زمانی که کاربر خواست اطلاعات رو بنوعی درج یا بروزرسانی کنه برنامه مقدار تاریخ شمسی اون رو + تبدیل شده ی اون تاریخ به میلادی رو (که خود برنامه این تبدیل رو دور از چشم وی انجام میده) در دو فیلد مجزا ذخیره میکنه.
و اما اگه منظور شما اینه که ممکنه کاربر با دستکاری در دیتابیس یه تاریخی رو عوض کنه باید بگم که این مشکل در مورد راه حلهای قبلی هم پابرجاست. ضمن اینکه در اینجا چون تاریخ به دو شکل و در دو فیلد مجزا ذخیره میشه با مقایسه این دو فیلد تا حدی (یه کوچولو) میتوان جلوی تغییرات دستی رو گرفت.

m_amin_t
پنج شنبه 06 دی 1386, 10:03 صبح
ممنون از همه دوستان که عنایت داشتن. اتفاقا خودم هم کم کم داشتم به این نتیجه میرسیدم که تاریخ شمسی و میلادی رو ذخیره کنم. البته در مورد اون مطلبی که گفتین که ممکنه مشکل match شدن دو تا تاریخ پیش بیاد باید بگم که اولا در برنامه من همچین اتفاقی نمی افته چون مدیریت تاریخ ها همگی با خود منه و کاربر نقشی در اون نداره و ثانیا من در ui با یه سری از کلاس و توابع "مطمئن" کار تبدیل دو تا تاریخ رو به هم انجام میدم که مشکلی پیش نمیاد. بنابراین با همه این تفاصیل فکر کنم ساده ترین راه و (شاید) درست ترین کار همین باشه که هم تاریخ شمسی و هم میلادی رو ذخیره کنم و به موقع از هر کدوم استفاده کنم.
باز هم اگه نظری دارین ممنون میشم که بفرمایید.

JAFO_IRAN
پنج شنبه 06 دی 1386, 11:19 صبح
سلام

این چندمین بار است که در این سایت عزیز اینقدر احساس شفافیت میکنم...

ارادت - موفق باشید

mamizadeh
دوشنبه 27 اسفند 1386, 15:05 عصر
1. نرمال سازی و نقض اون، در مورد داده‌های تشکیل دهنده "رابطه" تعریف میشه - تکرار کردن هر داده در db که نقض نرمال سازی نیست.

آیا واقعا با اصل نرمال سازی مغایرت نداره ؟
اینو از روی چه منطقی می گین منطق خودتون هستش یا از جای معتبری خوانده اید
به نظر این بنده حقیر این مطلب شما با اصل سوم نرمال سازی مغایرت داره
البته به نظر من
اگه با منطق و سند معتبر روشنم کنید ممنون می شم
دوستان در تاپیک های دیگه در مورد نوشتن یه زیر برنامه در sql server بحث هایی رو انجام دادن به نظرتون اون روش ها بهتره یا این روش دو تاریخه یا استفاده از کد در UI
با تشکر :چشمک: