PDA

View Full Version : سوال: بدست آوردن فاصله زمانی بین دو تاریخ شمسی ، جمع و کم کردن تاریخ شمسی



mina.net
یک شنبه 17 آبان 1388, 13:35 عصر
سلام دوستان
من تاریخ رو تو بانک به صورت کارکتر و بدون / ذخیره می کنم . حالا می خوام فاصله زمانی بین شون و عمل جمع و تفریق رو بینشون انجام بدم . آیا تابع خاصی برای این کار در تاریخ شمسی وجود داره.
البته می تونم یک تابع بنویسم که این کار رو بکنه ولی اگه راه بهتری وجود داره بفرمایید.

DoDoklak
یک شنبه 17 آبان 1388, 15:33 عصر
منظور از تابع کجا رو میگید.داخل توابع بانک یا داخل زبان برنامه نویسی.البته توابعی هست ولی من پیشنهاد میکنم خودتون اونو بنویسید چون تابعهای موجود برای تاریخ شمسی دچار مشکل میشن.اگر تابع خواستی من نوشتم بگو میزارم

pirmard
یک شنبه 17 آبان 1388, 16:38 عصر
سلام دوستان
من تاریخ رو تو بانک به صورت کارکتر و بدون / ذخیره می کنم . حالا می خوام فاصله زمانی بین شون و عمل جمع و تفریق رو بینشون انجام بدم . آیا تابع خاصی برای این کار در تاریخ شمسی وجود داره.
البته می تونم یک تابع بنویسم که این کار رو بکنه ولی اگه راه بهتری وجود داره بفرمایید.

بهترین روش برای کار باتاریخ شمسی اینه که اونو فقط در دیتا انتری-پرزنتیشن به کار ببرید .
و در دیتابیس و لایه های غیر از لایه واسط کاربر با معادل میلادی اون تاریخ کار کنین .
یعنی اگر قرار است در دیتابیس تاریخی ذخیره شود میلادی باشد . اگر قرار است در لایه ی منطق محاسبات و یا تصمیم گیری های بر مبنای تاریخ انجام شود باید میلادی باشد .

فقط برای نمایش و یا دریافت از شمسی استفاده کنید .

mina.net
یک شنبه 17 آبان 1388, 17:02 عصر
سلام دوستان
من با خود تاریخ مشکل چندانی ندارم . اتفاقا در مورد تاریخ هم کم کار نکردم. منتها الان دارم امکان فروش اقساطی رو برای برنامه ام حسابداری ام اضافه می کنم که لازمه مثلا برای دیر کرد لازم هست که فاصله دیر کرد رو مشخص کنم. و یا برای ثبت یک قسط مثلا هفتگی با 20 قسط لازم هست که 20 تاریخ به فاصله هر 7 روز حساب بشه و ثبت انجام بشه. من منظورم اینچیزا هست. و البته منظورم تو خود برنامه هست نه تو بانک.

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


منظور از تابع کجا رو میگید.داخل توابع بانک یا داخل زبان برنامه نویسی.البته توابعی هست ولی من پیشنهاد میکنم خودتون اونو بنویسید چون تابعهای موجود برای تاریخ شمسی دچار مشکل میشن.اگر تابع خواستی من نوشتم بگو میزارم

بزار خوشحال می شیم.

mina.net
یک شنبه 17 آبان 1388, 17:29 عصر
این تابع رو همین الان انجام دادم احتمالا اشکال هم داشته باشه. آزمایش کنید اگه ایرادی داره در خدمتم. در ضمن دارم تابع جمع به تاریخ رو هم می نویسم اگه شد همین امشب برای آزمایش می زارم. لطفا فعلا اگه می شه این تابع رو در حالت های مختلف آزمایش کنید. در صورت دیدن اشتباهی در تابع حتما با ذکر تاریخ شروع و تاریخ پایان به من اطلاع دهید تا اصلاح کنم.


Public Function fasele_tarikh(ByVal first_tarikh As String, ByVal second_tarikh As String)
first_tarikh = first_tarikh.Replace("/", "")
second_tarikh = second_tarikh.Replace("/", "")
If Val(first_tarikh) <= Val(second_tarikh) Then
Return "0/0/0"
Exit Function
End If
Dim roz1, roz2, mah1, mah2, sal1, sal2, rozR, mahR, salR As Integer
sal1 = Val(Mid(first_tarikh, 1, 4))
sal2 = Val(Mid(second_tarikh, 1, 4))
mah1 = Val(Mid(first_tarikh, 5, 2))
mah2 = Val(Mid(second_tarikh, 5, 2))
roz1 = Val(Mid(first_tarikh, 7, 2))
roz2 = Val(Mid(second_tarikh, 7, 2))
Dim s1 As Integer = sal1 Mod 33
If roz1 >= roz2 Then
rozR = roz1 - roz2
Else
If mah1 = 12 And (s1 = 1 Or s1 = 5 Or s1 = 9 Or s1 = 13 Or s1 = 17 Or s1 = 22 Or s1 = 26 Or s1 = 30) Then
roz1 += 29
mah1 -= 1
rozR = roz1 - roz2
ElseIf mah1 <= 6 Then
roz1 += 31
mah1 -= 1
rozR = roz1 - roz2
Else
roz1 += 30
mah1 -= 1
rozR = roz1 - roz2
End If
End If
If mah1 >= mah2 Then
mahR = mah1 - mah2
Else
mah1 += 12
sal1 -= 1
mahR = mah1 - mah2
End If
salR = sal1 - sal2
'Dim Dir_fasele As Double = salR + (mahR / 12) + (rozR / 365)
Dim str_fasele As String = salR & "/" & mahR & "/" & rozR
' Dir_fasele = (Dir_fasele * (darsad / 100)) * mablagh
Return str_fasele
End Function

DoDoklak
یک شنبه 17 آبان 1388, 17:44 عصر
یه سری به اینجا بزن
http://barnamenevis.org/forum/showthread.php?t=179632

majid_vb_2008
یک شنبه 17 آبان 1388, 18:59 عصر
اين تابع بين دوتا تاريخ رو به روز بر مي گردونه


Public Function ShamsiDateDiff(ByVal Date1 As String, ByVal Date2 As String, Optional ByVal Seperator As String = "/") As Integer
Dim pc As New Globalization.PersianCalendar
Dim da1 = Date1.Split(Seperator)
Dim da2 = Date2.Split(Seperator)
Dim dt1 = pc.ToDateTime(da1(0), da1(1), da1(2), 0, 0, 0, 0)
Dim dt2 = pc.ToDateTime(da2(0), da2(1), da2(2), 0, 0, 0, 0)
Return DateDiff(DateInterval.Day, dt1, dt2)
End Function

mina.net
یک شنبه 17 آبان 1388, 20:45 عصر
سلام دوستان
همونطور که قول دادم برای جمع کردن یک مقدار (روز ، ماه ، سال) با تاریخ تابعی نوشتم لطفا موشکافانه عیبیابی بفرمایید .


PublicFunction jam(ByVal first_tarikh AsString, ByVal sal_jam AsInteger, _
ByVal mah_jam AsInteger, ByVal roz_jam AsInteger)
first_tarikh = first_tarikh.Replace("/", "")
Dim roz1, mah1, sal1, rozR, mahR, salR, Jroz, Jmah, Jsal AsInteger
sal1 = Val(Mid(first_tarikh, 1, 4))
mah1 = Val(Mid(first_tarikh, 5, 2))
roz1 = Val(Mid(first_tarikh, 7, 2))
Jroz = roz1 + roz_jam
Jmah = (mah1 + mah_jam) - 1
Jsal = sal1 + sal_jam
Jsal += Jroz \ 365
Jsal += Jmah \ 12
Jroz = Jroz Mod 365
Jmah = Jmah Mod 12
If (Jmah \ 6) = 1 Then
Jroz += 186
Jroz += (Jmah Mod 6) * 30
Else
Jroz += Jmah * 31
EndIf
Jsal += Jroz \ 365
If Jroz <= 186 Then
Jmah = Jroz \ 31
Jroz = Jroz Mod 31
Else
Jroz -= 186
Jmah = (Jroz \ 30) + 6
Jroz = Jroz Mod 30
EndIf
If Jroz = 0 And Jmah <= 6 Then
rozR = 31
ElseIf Jroz = 0 And Jmah > 6 Then
rozR = 30
Else
rozR = Jroz
EndIf
If Jmah = 0 Then
mahR = 1
ElseIf rozR = 31 And Jmah <= 6 Then
mahR = Jmah
ElseIf rozR = 30 And Jmah > 6 Then
mahR = Jmah
Else
mahR = Jmah + 1
EndIf
If Jsal = 0 Then
salR = 1
Else
salR = Jsal
EndIf
Return salR & "/" & mahR & "/" & rozR
EndFunction


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

mina.net
یک شنبه 17 آبان 1388, 20:49 عصر
اين تابع بين دوتا تاريخ رو به روز بر مي گردونه


Public Function ShamsiDateDiff(ByVal Date1 As String, ByVal Date2 As String, Optional ByVal Seperator As String = "/") As Integer
Dim pc As New Globalization.PersianCalendar
Dim da1 = Date1.Split(Seperator)
Dim da2 = Date2.Split(Seperator)
Dim dt1 = pc.ToDateTime(da1(0), da1(1), da1(2), 0, 0, 0, 0)
Dim dt2 = pc.ToDateTime(da2(0), da2(1), da2(2), 0, 0, 0, 0)
Return DateDiff(DateInterval.Day, dt1, dt2)
End Function
جناب majid_vb_2008 ممنون از توجهی که دارید . آزمایش می کنم. حتمالا در کوتاه کردن و همچنین بهینه کردن تابع من موثر خواهد بود

جناب DoDoklak ممنون
منتظر نظرات بیشتر دوستان هستم همچنان

mina.net
دوشنبه 18 آبان 1388, 08:01 صبح
سلام دوستان
جناب majid_vb_2008 تابع شما را استفاده کردم خوب بود . آیا تابع مشابهی برای جمع و تفریق تاریخ وجود دارد؟ اگه تابعی برای این کار دارید ممنون می شم بزارید.

بخوام توضیح بیشتر بدم. من یک تابعی می خوام هر مقداری رو جمع کنه. یعنی اگه بهش تعداد روز دادیم ، ماه دادیم یا سال فرق نکنه و مثلا بهش بگیم +455 روز یا مثلا +18 ماه. تابعی که خودم گذاشتم برای جمع هنوز کبیسه رو حساب نمی کنه.

DoDoklak
دوشنبه 18 آبان 1388, 08:34 صبح
تابع موجود در دات نت مربوط به تاریخ تو محاسبه چند روز سل شمسی دچار مشکل میشن .اینها رو امتحان کنید :27,28,29/2/1387,1388 .برای سال زیاد مطمئن نیستم حالا هر دوشو امتحان کنید

mina.net
دوشنبه 18 آبان 1388, 12:23 عصر
تابع موجود در دات نت مربوط به تاریخ تو محاسبه چند روز سل شمسی دچار مشکل میشن .اینها رو امتحان کنید :27,28,29/2/1387,1388 .برای سال زیاد مطمئن نیستم حالا هر دوشو امتحان کنید

تاریخی که گذاشتید رو متوجه نشدم. در ضمن نمی دونم منظور شما چی بود تابع من اشکال داره یا دات نت.

یک مطلبی بگم : اشکال تو همه نرم افزارهای دنیا وجود داره حتی گاها تو چیزای خیلی پیش پا افتاده ای مثل جمع ضرب.
مثال می زنم


Dim d1 As Double = 1.1 * 100
If d1 = 110 Then Exit Sub

قاعدتا برنامه باید متوقف بشه ولی نمی شه. همین موضوع به این سادگی دچار اشکال هست یعنی 1.1*100=110 نمی شه ، می شه 110.00000000000001
به هر حال نرم افزار بدون ایراد وجود ندارد

arsalansalar
دوشنبه 18 آبان 1388, 12:43 عصر
http://www.barnamenevis.org/forum/showthread.php?t=175669

DoDoklak
دوشنبه 18 آبان 1388, 12:45 عصر
نمونه برنامه ای که گذاشتید معلومه که کار نمیکنه چون شما یک عدد اعشاری رو با یک عدد صحیح مقایسه کردید که شاید هیچ وقت برابر نشن(خطای منطقی) این مشکل از برنامه نویسه نه خود عمل مقایسه یا ضرب.بعد منظور من تابع دات نت بود تو تاریخای 27/02/1388 و 28/02/1388 و 29/02/1388 میتونی سال 87 رو هم در نظر بگیری .توابع تاریخ دات نت این تاریخها را نامعتبر تشخیص میدن برای همین میگم بهتره تو بحث تاریخ خودتون تابع مورد نظر رو بنویسید

mina.net
سه شنبه 19 آبان 1388, 12:05 عصر
نمونه برنامه ای که گذاشتید معلومه که کار نمیکنه چون شما یک عدد اعشاری رو با یک عدد صحیح مقایسه کردید که شاید هیچ وقت برابر نشن(خطای منطقی) این مشکل از برنامه نویسه نه خود عمل مقایسه یا ضرب.بعد منظور من تابع دات نت بود تو تاریخای 27/02/1388 و 28/02/1388 و 29/02/1388 میتونی سال 87 رو هم در نظر بگیری .توابع تاریخ دات نت این تاریخها را نامعتبر تشخیص میدن برای همین میگم بهتره تو بحث تاریخ خودتون تابع مورد نظر رو بنویسید
سلام دوستان
آیا بنظر شما 110.00000000000001 با 110.00000000000000 با هم برابر هستند؟ بگزریم من هدفم این بود که تو دات نت مثل همه نرم افزار های دیگر اشکال همواره وجود دارد که البته شما هم قبول دارید و هیچ وقت به صفر نخواهد رسید هر چند تعداد اشکالات کم خواهد شد.

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

ricky22
شنبه 17 بهمن 1388, 08:59 صبح
دوستان من تاریخ فارسی رو با تابع datediff مقایسه می کنم و مشکلی ندارم
چرا از اون استفاده نی کنید؟

Reza Safa
شنبه 17 بهمن 1388, 13:39 عصر
دوستان با عرض پوزش نیازی به این همه خط تو خ کردن نیست

از time span استفاده کنید
تاریخ های خودتونو به میلادی برگردانید و در timespan مثل یک تفریق ساده کم کنید و تعداد روز را مشخص میکنه

یعنی باور نمیکنید که این همهراه رو میتونستید با این خط ساده بنویسید

من چند صد بار استفاده کردم و جواب گرفتم

tecnocomputer
دوشنبه 10 اسفند 1388, 22:09 عصر
واسه جاوا اسكريپت همچين چيزي نداريد؟