PDA

View Full Version : ذخیره تاریخ هجری شمسی ( ایرانی)



Navid Asadi
سه شنبه 27 مرداد 1388, 15:00 عصر
سلام دوستان
میدونم سوالم تکراری هستش اما من بعد از جستجو های زیادی که کردم و به جواب نرسیدم این تاپیک رو ایجاد کردم سولات حالا من تصمیم گرفتم که تارخ به صورت عدد ذخیره کنم مثلا 1388/05/02 رو به صورت 13880502 در بیارم...
1. چطور در هنگام فرا خوانی داده ها در دیتا گرید ویو / ها رو اضافه کنم(چه بهتر در هنگام Select باشه)
2.آیا میتونم برای محاسبات اون رو به وسیله persianCalender به تاریخ تبدیل کنم تا محاسباتش راحت تر باشه؟
3.میخوام داده هام رو تو MaskTextbox وارد کنم، چیکار کنم که 1388/05/02 رو به صورت 1388/5/2 وارد نکنن؟ و همچنین عدد ماه رو از 12 و روز رو از31 بیشتر وارد نکنن؟
لطفا ایراد نگیرید که چرا تو یه تاپیک 3 تا سوال پرسیدم اینا همش به هم مربوط هستن...

Ali_Mor
چهارشنبه 28 مرداد 1388, 00:20 صبح
من معمولا تاریخ رو بصورت رشته ای و بهمراه اسلش هایش (1388/05/02) ذخیره می کنم. البته روز و ماه حتما باید 2 رقمی باشد. اینطوری در کوئری ها هم راحت میتونم از عملگرهای مقایسه استفاده کنم و برای نمایش آن هم مشکلی وجود ندارد.

Navid Asadi
چهارشنبه 28 مرداد 1388, 11:43 صبح
اما در این روش نمیتوان در دیتا گرید ستون ها را مرتب کرد....

Navid Asadi
چهارشنبه 28 مرداد 1388, 11:45 صبح
شما چطوری در بین اون ها جستجو میکنید؟
مثلا داده های بین تاریخx و Y یا داده های قبل از تاریخ X و...

Ali_Mor
چهارشنبه 28 مرداد 1388, 15:17 عصر
چرا نمیشه مرتب سازی انجام داد؟
دستورات < > = برای رشته ها هم کار می کند. چون تمام تاریخ ها 10 کارکتری و بصورت رشته ذخیره می شوند براحتی میتوان جستجو را انجام داد

mn_zandy63
پنج شنبه 29 مرداد 1388, 19:33 عصر
حق با دوستمون Ali_Mor هست٬ این روش خیلی روش خوبی هست٬ من هم خیلی وقتا ازش استفاده کردم.
هیچ مشکلی هم برای جستجو و مرتب سازی نداره.
فقط پیدا کردن اختلاف دو تا تاریخ دردسر داره٬ باید تبدیل کنی.

Hossis
جمعه 30 مرداد 1388, 11:10 صبح
من در یک پایگاه داده ، تاریخ شمسی رو در فیلدی با قالب Date ذخیره کردم و هیچ مشکلی هم نداشت
این نمونه رو ببینید

Navid Asadi
جمعه 30 مرداد 1388, 15:50 عصر
سلام دوستان من از توجه شما واقعا ممنونم اما قبل از این که شما پاسخ من رو بدید من از روش خودم همه مشکلاتم رو حل کردم .
آقای Hossis (http://www.barnamenevis.org/forum/member.php?u=49368) من هنوز برنامه تون رو امتحان نکردم اما به محض امتحان نظرم رو بهتون میگم...
در مورد روش خودم هم اگه کسی سوالی داره خوشحال میشم کمکش کنم تا دیگه کسی مثل من درگیر نباشه.

mobin-co
شنبه 25 مهر 1388, 11:08 صبح
سلام کاش روش رو ذکر می کردید من هم با مسئله ذخیره تاریخ شمسی بد جوری درگیرم

amirrezapour
شنبه 25 مهر 1388, 18:37 عصر
با عرض سلام و خسته نباشید خدمت دوستان
معمولا برای نگه داری تاریخ در database از فرمت DateTime استفاده میشود
شما باید تاریخ فارسی رو بگیرید و اون رو به لاتین تبدیل کنید بعد اون رو در سرور دخیره کنید
و در نمایش دوباره عمل معکوس را انجام دهید و تاریخ رو بارسی کنید
این طوری در select در فیلد datetime مشکل نخواهید داشت
کافیست که نام Culomn های datagridview رو همنام culomn های دیتابیس انتخاب کنید و
از توابع زیر استفاده کنید
public static void dg_AddRow<T>(ref Shopping.UserControls.DataGridView.mydgv dg, T row)
{

dg.Rows.Add(1);


Type entType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
int rowIndex = 0;

if (dg.AllowUserToAddRows)
rowIndex = dg.Rows.GetLastRow(DataGridViewElementStates.None) - 1;
else
rowIndex = dg.Rows.GetLastRow(DataGridViewElementStates.None) ;

foreach (PropertyDescriptor prop in properties)
{

try
{

(1) dg.Rows[rowIndex].Cells[prop.Name].Value = prop.GetValue(row);
}
catch
{
}

}
}

فقط مشکل نمایش به صورت XXXX/XX/XX باقی میمونه
که باید یه تابع بنویسی که عدد را دگیره و 2 رقمیش کنه
باید در قسمت 1 توی کد این تغییران رو انجام بدی
if( dg.Rows[rowIndex].Cells[prop.Name].Name=="my date culomn")
toTowDigitFormat( dg.Rows[rowIndex].Cells[prop.Name].Value )




//
public string toTwoDigitFormat(strng input)
{
if(input.Lenght<2)
return "0"+input
else return input;
}
//

mina.net
پنج شنبه 30 مهر 1388, 12:37 عصر
سلام
فکر نمی کنم تبدیل تاریخ به میلادی و ذخیره و سپس بازیابی با توجه به راه کارهای ساده تری که وچوددارد کار درستی باشد. البته این نظر من هست .
من از دستور select زیر استفاده می کنم


select SubString(TARIKH,1,4) + '/' + SubString(TARIKH,5,2) + '/' + SubString(TARIKH,7,2) AS NewDate from tablename

mobin-co
پنج شنبه 30 مهر 1388, 17:04 عصر
ممنون از راهنمایی تون اما مشکل تو همین تبدیل تاریخ شمسی به میلادیه اکثر توابعی که من دیدم اشتباه کار میکنن.
شما تابعی سراغ دارین که مطمئن باشه و ورودی اون استرینگ و خروجیش تاریخ باشه؟

mobin-co
پنج شنبه 30 مهر 1388, 17:07 عصر
سلام
فکر نمی کنم تبدیل تاریخ به میلادی و ذخیره و سپس بازیابی با توجه به راه کارهای ساده تری که وچوددارد کار درستی باشد. البته این نظر من هست .
من از دستور select زیر استفاده می کنم


select SubString(TARIKH,1,4) + '/' + SubString(TARIKH,5,2) + '/' + SubString(TARIKH,7,2) AS NewDate from tablename


این دستور اس کیو ال هست؟ آیا موقع پر کردن تاریخ شمسی در متغیر مثلا از تاریخ 1388/02/29 ایراد نمی گیره ؟ چون این تاریخ در تقویم میلادی غلطه

mobin-co
پنج شنبه 30 مهر 1388, 17:08 عصر
سلام
فکر نمی کنم تبدیل تاریخ به میلادی و ذخیره و سپس بازیابی با توجه به راه کارهای ساده تری که وچوددارد کار درستی باشد. البته این نظر من هست .
من از دستور select زیر استفاده می کنم


select SubString(TARIKH,1,4) + '/' + SubString(TARIKH,5,2) + '/' + SubString(TARIKH,7,2) AS NewDate from tablename


موقع پرکردن تاریخ سیستم از تاریخ مثلا 29/02/1388 ایراد نمی گیره؟

mobin-co
پنج شنبه 30 مهر 1388, 17:11 عصر
این دستور سلکت تو اس کیو ال هست؟ موقع پر کردن تاریخ برای تاریخی مثل 1388/02/29 ایراد نمی گیره؟

iman_ad
شنبه 02 آبان 1388, 04:08 صبح
دوستان تاریخ همیشه میلادی ذخیره کنید. موقع نمایش به شمسی تبدیل کنید

mina.net
شنبه 02 آبان 1388, 10:24 صبح
ممنون از راهنمایی تون اما مشکل تو همین تبدیل تاریخ شمسی به میلادیه اکثر توابعی که من دیدم اشتباه کار میکنن.
شما تابعی سراغ دارین که مطمئن باشه و ورودی اون استرینگ و خروجیش تاریخ باشه؟
سلام دوستان
من فکر نمی کردم که اینهمه سوال برای شما پیش بیاد بخاطر همین به این تاپیک دوباره سر نزدم.
لزومی به تبدیل تاریخ و از این جور مسائل نیست.
شما موقع ثبت تاریخ نیازی به سرعت بالا ندارید و می تونید صحت تاریخ رو با توابع مختلف چک کنید اما موقع واکشی اطلاعات بخاطر هجم زیاد حتما باید خیلی راحت و ساده این کار رو انجام بدید.
در ضمن من تاریخ رو به صورت text ذخیره می کنم با تعداد کارکتر 8 تایی البته فیلد من 10 کارکتری هست. به شما هم همین توصیه رو می کنم.

دوتا تابع من نوشتم که الان یک سالی هست تو برنامه هام ازشون استفاده می کنم و هیچ مشکلی پیش نیومده تا الان و امیدوارم بعدا هم پیش نیاد می تونید از این د تابع برای صحت تاریخ تون استفاده کنید.

این تابع مشخص می کنه آیا تاریخ با فرمت درست وارد شده یا نه.حتی سال کبیسه رو هم برای شما چک خواهد کرد.


PublicFunction DATE_adad2(ByVal DATE1_P AsString)
If DATE1_P = NothingThen
MessageBoxFa.Show("¢ں©ی¦ يں©§ 묧ى", name_me, MessageBoxButtons.OK)
ReturnFalse
ExitFunction
EndIf
Dim YYYY AsInteger
Dim STRY AsString = ""
Dim MM AsInteger
Dim STRM AsString = ""
Dim DD AsInteger
Dim STRD AsString = ""
Dim STRP1 AsString
Dim STR_MAIN AsString = ""
If Val(DATE1_P) = 0 Then
ReturnFalse
ExitFunction
EndIf
STRP1 = DATE1_P
Dim I AsInteger
Dim INT1 AsInteger = STRP1.Length
Dim STR AsString = ""
For I = 1 To INT1
If STR = ""Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRY = STRY & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
ElseIf STR = "/"Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRM = STRM & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
ElseIf STR = "//"Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRD = STRD & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
EndIf
Next
If STRY.Length > 4 _
Or STRM.Length > 2 _
Or STRD.Length > 2 _
Or STRY.Length < 4 _
Or STRM.Length < 1 _
Or STRD < 1 Then
MessageBoxFa.Show("¢ں©ی¦ ­¥ی¥ ëی«¢", name_me, MessageBoxButtons.OK)
ReturnFalse
ExitFunction
EndIf
YYYY = CType(STRY, Integer)
MM = CType(STRM, Integer)
DD = CType(STRD, Integer)
If MM < 0 Or DD < 0 Or MM > 12 Or DD > 31 Or YYYY < 1300 Or YYYY > 1450 Then
MessageBoxFa.Show("¢ں©ی¦ ©يھ یں êںى ­¥ی¥ ëی«¢", name_me, MessageBoxButtons.OK)
ReturnFalse
ExitFunction
EndIf
If MM > 6 And DD = 31 Then
MessageBoxFa.Show("ںیë êںى 31 ©يھى ëی«¢", name_me, MessageBoxButtons.OK)
ReturnFalse
ExitFunction
EndIf
If (YYYY - 3) Mod 4 <> 0 And MM = 12 And DD = 30 Then
MessageBoxFa.Show("ںیë êںى 29 ©يھى ى«¢", name_me, MessageBoxButtons.OK)
ReturnFalse
ExitFunction
EndIf
ReturnTrue
EndFunction

این تابع هم در صورتی که تاریخ فرضا به صورت 8/5/88 نوشته شده باشه رو به 13880508 تبدیل می کنه.البته اگه تاریخ به صورت 8 کارکتری بود فقط / رو بر می داره. اگه بازم سوالی بود بفرمایید در خدمتم


PublicFunction DATE_adad1(ByVal DATE1_P AsString)
Dim date_int AsInteger
Dim YYYY AsInteger
Dim STRY AsString = ""
Dim MM AsInteger
Dim STRM AsString = ""
Dim DD AsInteger
Dim STRD AsString = ""
Dim STRP1 AsString
Dim STR_MAIN AsString = ""
If Val(DATE1_P) = 0 Then
Return date_int
ExitFunction
EndIf
STRP1 = DATE1_P
Dim I AsInteger
Dim INT1 AsInteger = STRP1.Length
Dim STR AsString = ""
For I = 1 To INT1
If STR = ""Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRY = STRY & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
ElseIf STR = "/"Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRM = STRM & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
ElseIf STR = "//"Then
STR_MAIN = Mid(STRP1, I, 1)
If STR_MAIN <> "/"Then STRD = STRD & STR_MAIN
If STR_MAIN = "/"Then STR = STR & STR_MAIN
EndIf
Next
Try
YYYY = CType(STRY, Integer)
MM = CType(STRM, Integer)
DD = CType(STRD, Integer)
Catch ex As Exception
bol_t = True
EndTry

If YYYY < 100 Then STRY = "13" & YYYY
If MM < 10 Then STRM = "0" & MM
If DD < 10 Then STRD = "0" & DD
If MM > 12 Then bol_t = True
If DD > 31 Or DD <= 0 Then bol_t = True
If YYYY < 1000 Or YYYY > 1420 Then bol_t = True
If MM > 6 And DD > 30 Then bol_t = True
date_int = STRY & STRM & STRD
Return date_int
EndFunction


در ضمن یک کنترل datetimepiker هجری شمسی هم دارم که می تونید از اون هم استفاده کنید. لینکش تو امضاء من هست.

Somayeh_Zamani
دوشنبه 04 آبان 1388, 22:36 عصر
سلام دوستان
میدونم سوالم تکراری هستش اما من بعد از جستجو های زیادی که کردم و به جواب نرسیدم این تاپیک رو ایجاد کردم سولات حالا من تصمیم گرفتم که تارخ به صورت عدد ذخیره کنم مثلا 1388/05/02 رو به صورت 13880502 در بیارم...
1. چطور در هنگام فرا خوانی داده ها در دیتا گرید ویو / ها رو اضافه کنم(چه بهتر در هنگام Select باشه)
2.آیا میتونم برای محاسبات اون رو به وسیله persianCalender به تاریخ تبدیل کنم تا محاسباتش راحت تر باشه؟
3.میخوام داده هام رو تو MaskTextbox وارد کنم، چیکار کنم که 1388/05/02 رو به صورت 1388/5/2 وارد نکنن؟ و همچنین عدد ماه رو از 12 و روز رو از31 بیشتر وارد نکنن؟
لطفا ایراد نگیرید که چرا تو یه تاپیک 3 تا سوال پرسیدم اینا همش به هم مربوط هستن...


سلام
اصول اينست که تاريخ را به فرمت خود تاريخ در ديتابيس ذخيره کنيد. شما بايد تاريخ را به صورت شمسي از کاربر گرفته، به ميلادي تبديل کرده و در ديتابيس ذخيره کنيد. و براي نمايش دادن تاريخ نيز ابتدا تاريخ ميلادي‌اي که در ديتابيس داريد، را به شمسي تبديل کرده و سپس نمايش دهيد.

تابع زير براي تبديل تاريخ شمسي به ميلادي (به منظور ذخيره در ديتابيس) به کار مي‌رود:


publicstaticDateTime Shamsi2Miladi(string _date)
{
try
{
int year = int.Parse(_date.Substring(0, 4));
int month = int.Parse(_date.Substring(5, 2));
int day = int.Parse(_date.Substring(8, 2));
PersianCalendar p = newPersianCalendar();
DateTime date = p.ToDateTime(year, month, day, 0, 0, 0, 0);
return date;
}
catch (Exception ex)
{
thrownewException(" ");
}
}


و براي تبديل تاريخ ميلادي به شمسي (براي ذخيره در ديتابيس) از کد زير مي‌توانيد استفاده کنيد:


publicstaticstring Miladi2Shamsi(DateTime _date)
{
try
{
PersianCalendar pc = newPersianCalendar();
StringBuilder sb = newStringBuilder();
sb.Append(pc.GetYear(_date).ToString("0000"));
sb.Append("/");
sb.Append(pc.GetMonth(_date).ToString("00"));
sb.Append("/");
sb.Append(pc.GetDayOfMonth(_date).ToString("00"));
sb.Append(" ");
sb.Append(pc.GetHour(_date).ToString("00"));
sb.Append(":");
sb.Append(pc.GetMinute(_date).ToString("00"));
return sb.ToString();
}
catch (Exception ex)
{
thrownewException(" ");
}
}

که با سرچ در همين سايت هم مي‌توانستيد پيدا کنيد
و به عنوال مثال با دستور لينکيو زير مي‌توانيد رکوردهايي که تاريخشان بين دو تاريخ مشخص هست را بيرون بکشيد.


DateTime FD = Shamsi2Miladi(FromDate);
DateTime TD = Shamsi2Miladi(ToDate);
var res = from item in db.T_Times
where (item.StartTime >= FD) && (item.StartTime < TD)
select item;