PDA

View Full Version : محاسبه تاریخ چند ماه بعد



mojtabadj
پنج شنبه 21 آبان 1388, 20:46 عصر
سلا به دوستان عزیز

من تو برنامم با تاریخ سرو کار دارم من یک جا تو برنامم باید با توجه به تاریخ امروز

تاریخ جند ماه بعد رو محاسبه کنم برای اینکار شما جه راهی را پیشنهاد میدید؟

با تشکر

salehbagheri
پنج شنبه 21 آبان 1388, 21:28 عصر
دوست عزيز! لطفا سوال خود را واضح تر مطرح کنيد!

ACorvinus
پنج شنبه 21 آبان 1388, 22:06 عصر
سلام .
لطفا سوال خود را واضح تر مطرح کنيد!

منظورتون از اینکه تاریخ چند ماه بعد رو محاسبه کنین، چیه ؟

mojtabadj
جمعه 22 آبان 1388, 10:42 صبح
دوست عزيز! لطفا سوال خود را واضح تر مطرح کنيد!

فرض کنید تاریخ امروز 1388/5/1 هستش حالا میخوام بدونم 5 ماه بعد تاریخش چه روزی

هستش ! که جوابش میشه 1388/10/1

من یکمی رو محاسبه سالهای کبیسه مشکل دارم اگه تاریخ 1388/11/25 تاریخ 5 ماه

بعدش میره تو سال بعد اگه کبیسه هم بیاد توش یه کمی مشکل میشه !

لطفا راهنماییم کنید

salehbagheri
جمعه 22 آبان 1388, 11:56 صبح
بعدش میره تو سال بعد اگه کبیسه هم بیاد توش یه کمی مشکل میشه !

کبيسه بودن سال هيچ تأثيري در ماههاي سال نداره!

فقط تعداد روزها دچار تغيير ميشه!

mojtabadj
جمعه 22 آبان 1388, 19:29 عصر
کبيسه بودن سال هيچ تأثيري در ماههاي سال نداره!

فقط تعداد روزها دچار تغيير ميشه!

خوب حالا چه طوری من محاسبه کنم که 5 ماه بعد تاریخش چندمه؟

salehbagheri
جمعه 22 آبان 1388, 21:05 عصر
خوب حالا چه طوری من محاسبه کنم که 5 ماه بعد تاریخش چندمه؟

دوست عزيز! مثل اينکه پست قبلي بنده رو خوب نخوندي!

مثلا امروز 22 آبان 1388 هست! پنج ماه بعد ميشه 22 فروردين 1389! اگر سال 88 کبيسه هم باشه بازهم 22 فروردين مد نظر هست! نه 23 فروردين! (يعني در تغيير دادن ماه، روز رو بيخيال شو! البته روزهاي 30 ام و 31 ام رو خودت بايد تعميم بدي!)

اما اگه منظور شما تعداد روزها باشه خوب کبيسه بودن تأثير داره! 5 ماه بعد ميشه 148 روز! که در صورت کبيسه بودن سال ميشه 149 روز!!!

اين روش معمول هست! روش ديگري هم هست و اون اينه که شما تعداد روزهاي ماههاي پيش رو را محاسبه کرده و در نتيجه نهايي تأثير بديد! اين طوري ديگه خودتون بايد برنامه اش رو بنويسيد!

viper2009
جمعه 22 آبان 1388, 22:19 عصر
من هم تو محدوده تاریخ مشکل دارم
می خوام با زدن یک دکمه دو تا تاریخ Date Time Picker رو عوض کنه و اولی رو در اول ماه نشون بده و دومی هم آخر ماه رو

مثل : 1/8/1388 تا 30/8/1388

ACorvinus
جمعه 22 آبان 1388, 23:21 عصر
سلام بچه ها .

به نظرم شما مشکلتون اینه که یکی برنامه رو بنویسه بده شما استفاده کنین !
اگه اینجوریه بگین ها، خجالت نداره، من آدمشو دارم !!!

آره ؟

DoDoklak
شنبه 23 آبان 1388, 11:25 صبح
ورودی تابع بصورت YYYY/MM/DD است و خروجی نیز همین است.

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

تابع اضافه کردن یک ماه



PrivateFunction ADDMonth(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(m) + 1) <= 12 Then
m = (CInt(m) + 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
ElseIf (CInt(m) + 1) > 12 Then
m = "01"
y = (CInt(y) + 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction



تابع کم کردن یک ماه



PrivateFunction DECMonth(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(m) - 1) >= 1 Then
m = (CInt(m) - 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
ElseIf (CInt(m) - 1) < 1 Then
m = "12"
y = (CInt(y) - 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع اضافه کردن یک روز


Private Function ADDDAY(ByVal dat As String) As String
Dim y As String = dat.Substring(0, 4).ToString
Dim m As String = dat.Substring(5, 2).ToString
Dim d As String = dat.Substring(8, 2).ToString
Dim ps As New Globalization.PersianCalendar
Dim CountDay As Integer = ps.GetDaysInMonth(y, m, 1)
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (1 + CInt(d)) <= CountDay Then
If m.Length <= 1 Then m = "0" + m
d = CStr((CInt(d) + 1))
If d.Length <= 1 Then d = "0" + d
ElseIf (1 + CInt(d)) > CountDay Then
If (CInt(m) + 1) <= 12 Then
m = (CInt(m) + 1)
If m.Length <= 1 Then m = "0" + m
d = "01"
ElseIf (CInt(m) + 1) > 12 Then
m = "01"
d = "01"
y = (CInt(y) + 1)
End If
End If
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
End Function


تابع کم کردن یک روز



Private Function DECDAY(ByVal dat As String) As String
Dim y As String = dat.Substring(0, 4).ToString
Dim m As String = dat.Substring(5, 2).ToString
Dim d As String = dat.Substring(8, 2).ToString
Dim ps As New Globalization.PersianCalendar
Dim CountDay As Integer = ps.GetDaysInMonth(y, m, 1)
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(d) - 1) >= 1 Then
If m.Length <= 1 Then m = "0" + m
d = CStr((CInt(d) - 1))
If d.Length <= 1 Then d = "0" + d
ElseIf (CInt(d) - 1) < 1 Then
If (CInt(m) - 1) >= 1 Then
m = (CInt(m) - 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
d = CountDay
ElseIf (CInt(m) - 1) < 1 Then
m = "12"
y = (CInt(y) - 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
d = CountDay
End If
End If
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
End Function


تابع اضافه کردن یک سال


Private Function ADDYear(ByVal dat As String) As String
Dim y As String = dat.Substring(0, 4).ToString
Dim m As String = dat.Substring(5, 2).ToString
Dim d As String = dat.Substring(8, 2).ToString
Dim ps As New Globalization.PersianCalendar
Dim CountDay As Integer = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
y = (CInt(y) + 1)
If CInt(m) = 12 Then
CountDay = ps.GetDaysInMonth(y, m, 1)
If CInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
End If
End If
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
End Function


تابع کم کردن یک سال


Private Function DECYear(ByVal dat As String) As String
Dim y As String = dat.Substring(0, 4).ToString
Dim m As String = dat.Substring(5, 2).ToString
Dim d As String = dat.Substring(8, 2).ToString
Dim ps As New Globalization.PersianCalendar
Dim CountDay As Integer = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
y = (CInt(y) - 1)
If CInt(m) = 12 Then
CountDay = ps.GetDaysInMonth(y, m, 1)
If CInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
End If
End If
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
End Function


تابع گرفتن تاریخ شمسی


Private Function ShamsiDate() As String
Dim ps As New Globalization.PersianCalendar()
Dim y As String = ps.GetYear(DateTime.Now)
Dim m As String = ps.GetMonth(DateTime.Now)
Dim d As String = ps.GetDayOfMonth(DateTime.Now)
If y.Length <= 1 Then y = "0" + y
If m.Length <= 1 Then m = "0" + m
If d.Length <= 1 Then d = "0" + d
Return y & "/" & m & "/" & d
End Function


تابع اختلاف دو تاریخ خروجی یک عدد است(منفی یا مثبت)



Public Function SUBDAY(ByVal dat2 As String, ByVal dat1 As String) As Long
Try
Dim y1 As String = dat1.Substring(0, 4).ToString
Dim m1 As String = dat1.Substring(5, 2).ToString
Dim d1 As String = dat1.Substring(8, 2).ToString
'''''''''''''''''''''''''''''''''''''''''''''''''' '
Dim y2 As String = dat2.Substring(0, 4).ToString
Dim m2 As String = dat2.Substring(5, 2).ToString
Dim d2 As String = dat2.Substring(8, 2).ToString
'''''''''''''''''''''''''''''''''''''''''''''''''
Dim ps As New Globalization.PersianCalendar
Dim CountDay1 As Integer = ps.GetDaysInMonth(y1, m1, 1)
Dim CountDay2 As Integer = ps.GetDaysInMonth(y2, m2, 1)
If dat2 = dat1 Then Return 0
If dat2 > dat1 Then
Dim result As Long = 0
Dim flag As Boolean = True
Dim tmpdate As String = dat1
Do While flag
tmpdate = ADDDAY(tmpdate)
If tmpdate = dat2 Then
result += 1
flag = False
Else
result += 1
flag = True
End If
Loop
Return result
ElseIf dat1 > dat2 Then
Dim result As Long = 0
Dim flag As Boolean = True
Dim tmpdate As String = dat2
Do While flag
tmpdate = ADDDAY(tmpdate)
If tmpdate = dat1 Then
result -= 1
flag = False
Else
result -= 1
flag = True
End If
Loop
Return result
End If
Catch ex As Exception
Return 0
End Try
End Function

ACorvinus
شنبه 23 آبان 1388, 15:13 عصر
ورودی تابع بصورت YYYY/MM/DD است و خروجی نیز همین است.

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

تابع اضافه کردن یک ماه



PrivateFunction ADDMonth(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(m) + 1) <= 12 Then
m = (CInt(m) + 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
ElseIf (CInt(m) + 1) > 12 Then
m = "01"
y = (CInt(y) + 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction



تابع کم کردن یک ماه



PrivateFunction DECMonth(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(m) - 1) >= 1 Then
m = (CInt(m) - 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
ElseIf (CInt(m) - 1) < 1 Then
m = "12"
y = (CInt(y) - 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع اضافه کردن یک روز


PrivateFunction ADDDAY(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = ps.GetDaysInMonth(y, m, 1)
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (1 + CInt(d)) <= CountDay Then
If m.Length <= 1 Then m = "0" + m
d = CStr((CInt(d) + 1))
If d.Length <= 1 Then d = "0" + d
ElseIf (1 + CInt(d)) > CountDay Then
If (CInt(m) + 1) <= 12 Then
m = (CInt(m) + 1)
If m.Length <= 1 Then m = "0" + m
d = "01"
ElseIf (CInt(m) + 1) > 12 Then
m = "01"
d = "01"
y = (CInt(y) + 1)
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع کم کردن یک روز



PrivateFunction DECDAY(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = ps.GetDaysInMonth(y, m, 1)
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
If (CInt(d) - 1) >= 1 Then
If m.Length <= 1 Then m = "0" + m
d = CStr((CInt(d) - 1))
If d.Length <= 1 Then d = "0" + d
ElseIf (CInt(d) - 1) < 1 Then
If (CInt(m) - 1) >= 1 Then
m = (CInt(m) - 1)
If m.Length <= 1 Then m = "0" + m
CountDay = ps.GetDaysInMonth(y, m, 1)
d = CountDay
ElseIf (CInt(m) - 1) < 1 Then
m = "12"
y = (CInt(y) - 1)
CountDay = ps.GetDaysInMonth(y, m, 1)
d = CountDay
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع اضافه کردن یک سال


PrivateFunction ADDYear(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
y = (CInt(y) + 1)
IfCInt(m) = 12 Then
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع کم کردن یک سال


PrivateFunction DECYear(ByVal dat AsString) AsString
Dim y AsString = dat.Substring(0, 4).ToString
Dim m AsString = dat.Substring(5, 2).ToString
Dim d AsString = dat.Substring(8, 2).ToString
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay AsInteger = 0
'''''''''''''''''''''''''''''''''''''''''''''''''' ''
y = (CInt(y) - 1)
IfCInt(m) = 12 Then
CountDay = ps.GetDaysInMonth(y, m, 1)
IfCInt(d) > CountDay Then
d = CountDay
If d.Length <= 1 Then d = "0" + d
EndIf
EndIf
'''''''''''''''''''''''''''''''''''''''''''''''''' '''
Return y & "/" & m & "/" & d
EndFunction


تابع گرفتن تاریخ شمسی


PrivateFunction ShamsiDate() AsString
Dim ps AsNew Globalization.PersianCalendar()
Dim y AsString = ps.GetYear(DateTime.Now)
Dim m AsString = ps.GetMonth(DateTime.Now)
Dim d AsString = ps.GetDayOfMonth(DateTime.Now)
If y.Length <= 1 Then y = "0" + y
If m.Length <= 1 Then m = "0" + m
If d.Length <= 1 Then d = "0" + d
Return y & "/" & m & "/" & d
EndFunction


تابع اختلاف دو تاریخ خروجی یک عدد است(منفی یا مثبت)



PublicFunction SUBDAY(ByVal dat2 AsString, ByVal dat1 AsString) AsLong
Try
Dim y1 AsString = dat1.Substring(0, 4).ToString
Dim m1 AsString = dat1.Substring(5, 2).ToString
Dim d1 AsString = dat1.Substring(8, 2).ToString
'''''''''''''''''''''''''''''''''''''''''''''''''' '
Dim y2 AsString = dat2.Substring(0, 4).ToString
Dim m2 AsString = dat2.Substring(5, 2).ToString
Dim d2 AsString = dat2.Substring(8, 2).ToString
'''''''''''''''''''''''''''''''''''''''''''''''''
Dim ps AsNew Globalization.PersianCalendar
Dim CountDay1 AsInteger = ps.GetDaysInMonth(y1, m1, 1)
Dim CountDay2 AsInteger = ps.GetDaysInMonth(y2, m2, 1)
If dat2 = dat1 ThenReturn 0
If dat2 > dat1 Then
Dim result AsLong = 0
Dim flag AsBoolean = True
Dim tmpdate AsString = dat1
DoWhile flag
tmpdate = ADDDAY(tmpdate)
If tmpdate = dat2 Then
result += 1
flag = False
Else
result += 1
flag = True
EndIf
Loop
Return result
ElseIf dat1 > dat2 Then
Dim result AsLong = 0
Dim flag AsBoolean = True
Dim tmpdate AsString = dat2
DoWhile flag
tmpdate = ADDDAY(tmpdate)
If tmpdate = dat1 Then
result -= 1
flag = False
Else
result -= 1
flag = True
EndIf
Loop
Return result
EndIf
Catch ex As Exception
Return 0
EndTry
EndFunction




سلام دوست عزیز .

به نظرتون این کدها برای کم و بیش کردن روز و ماه و سال زیاد نیستن ؟

کم و زیاد کردن روز :



Today.Date.AddDays(value As Double)


value اگه منفی باشه از روزهای امروز کم میکنه اگه مثبت باشه به اون اضافه میکنه .
ماه و سال هم همچنین .

حالا همین تاریخ بدست اومده رو میتونین با فرستادن به تابع ShamsiDate به شمسی برش گردونین و ... .

به هر حال اینم نظر من بود، موفق باشین .

kasmaii61
شنبه 23 آبان 1388, 15:50 عصر
من هم با نظر ACorvinus در مورد زیاد بودن این کدها برای کم و زیاد کردن تاریخ موافقم
برای کار با تاریخ ابتدا تاریخ شمسی رو به میلادی تبدیل کنید و سپس با استفاده از توابعی که برای کار با تاریخ وجود داره عملیات مورد نظرتون رو انجام بدید و در پایان دوباره تاریخ رو به شمسی تبدیل کنید
با استفاده از این روش هیچ وقت در محاسبه سالهای کبیسه نیز دچار مشکل نمیوید
کل کد دوستمون رو در چند خط کد زیر میشه خلاصه کرد
ابتدا NameSpace زیر رو اضافه کنید :

Imports System.Globalization
و سپس :

Dim VarPersianDate As New PersianCalendar
Dim ShamsiDate As String = "1388/8/18"
Dim MiladiDate As Date
Dim VarAddDay As Integer = 15
Dim VarAddMonth As Integer = 5
Dim VarAddYear As Integer = 2
Dim VarSplDate(2) As String
VarSplDate = ShamsiDate.ToString.Split("/")
'تبدیل به میلادی
MiladiDate = VarPersianDate.ToDateTime(VarSplDate(0), VarSplDate(1), VarSplDate(2), 0, 0, 0, 0)
MsgBox(MiladiDate.ToString)
'اضافه کردن روز
MsgBox(MiladiDate.AddDays(VarAddDay))
'اضافه کردن ماه
MsgBox(MiladiDate.AddMonths(VarAddMonth))
'اضافه کردن سال
MsgBox(MiladiDate.AddYears(VarAddYear))
'تبدیل به شمسی
ShamsiDate = CStr(VarPersianDate.GetYear(MiladiDate)) + "/" + CStr(VarPersianDate.GetMonth(MiladiDate)) + "/" + CStr(VarPersianDate.GetDayOfMonth(MiladiDate))
MsgBox(ShamsiDate)
همون طور که دوستمون هم گفتن برای کم کردن مقادیر هم از منفی اعداد استفاده کنید

DoDoklak
شنبه 23 آبان 1388, 17:24 عصر
دوستان آیا توابع خود را برای تاریخ شمسی کامل تست کرده اید؟
مطمئنم تست نکردید چون اشتباه عمل میکنه.
توابع خود دات نت مخصوصا بخش Globalization تو اضافه کردن روزها همیشه تا 31 روز جلو میره در حالی که 6 ماه دوم سال 30 روزه و برج 12 گاهی 29 روز ولی این اگه بهش 29/12/1388 بدی با افزایش یک روز اونو تبدیل 30/12/188 و بعد 31/12/1388 میکنه که غلطه.

بعد تو تاریخهای 28/02/1388 و 29/02/1388 و 30/02/1388 مه میلادی تبدیلش میکنی دچار مشکل میشه و میگه که این تاریخها نامعتبر است
من خودم قبل از نوشتن این توابع از همین روش ی که شما گفتید استفاده کردم که خیلی به ضررم تموم شد تا خودم یه تابع نوشتم و اونو تبدیل به یک Dll کردم و الان همیشه خیالم راحته.

برای اطمینان میتونید چیزی رو که گفتم تست کنید

kasmaii61
سه شنبه 26 آبان 1388, 11:31 صبح
دوستان آیا توابع خود را برای تاریخ شمسی کامل تست کرده اید؟
مطمئنم تست نکردید چون اشتباه عمل میکنه.
توابع خود دات نت مخصوصا بخش Globalization تو اضافه کردن روزها همیشه تا 31 روز جلو میره در حالی که 6 ماه دوم سال 30 روزه و برج 12 گاهی 29 روز ولی این اگه بهش 29/12/1388 بدی با افزایش یک روز اونو تبدیل 30/12/188 و بعد 31/12/1388 میکنه که غلطه.

بعد تو تاریخهای 28/02/1388 و 29/02/1388 و 30/02/1388 مه میلادی تبدیلش میکنی دچار مشکل میشه و میگه که این تاریخها نامعتبر است
من خودم قبل از نوشتن این توابع از همین روش ی که شما گفتید استفاده کردم که خیلی به ضررم تموم شد تا خودم یه تابع نوشتم و اونو تبدیل به یک Dll کردم و الان همیشه خیالم راحته.

برای اطمینان میتونید چیزی رو که گفتم تست کنید

دوست عزیز بر عکس اطمینانی که شما داری من این توابع رو کامل امتحان کردم و حتی یک DateTimePicker هم با همین توابع نوشتم و از صحت اون کاملا اطمینان دارم
یه مقدار عجیبه که بگیم مایکروسافت گاف به این گندگی داده
من نمی دونم شما چه جوری از این توابع استفاده می کنی که به این نتایج می رسی ولی قطعا روشت اشتباهه. برای اینکه از صحت حرفم اطمینان پیدا کنی من پروژه رو اینجا برات upload می کنم خودت تست کن. هم سال 1388 رو که مد نظر شما بو د نتیجه رو میده هم سال 1387 که یه سال کبیسه بود و می بینی که هیچ اشتباهی هم در کار نیست:


Imports System.Globalization
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim a As Date
a = ShamsiToMiladi("1388/12/28")
a = a.AddDays(1)
MsgBox(MiladiToShamsi(a))
''''' Result : 1388/12/29

a = a.AddDays(1)
MsgBox(MiladiToShamsi(a))
''''' Result : 1389/1/1


a = ShamsiToMiladi("1387/12/29")
a = a.AddDays(1)
MsgBox(MiladiToShamsi(a))
''''' Result : 1387/12/30

'''' Because 1387 is Leap Year''''''

a = a.AddDays(1)
MsgBox(MiladiToShamsi(a))
'''''Result : 1388/1/1

End Sub

Public Function ShamsiToMiladi(ByVal ShmasiDate As String) As Date
Dim PersianDate As New PersianCalendar
Dim VarSpl(2) As String
VarSpl = ShmasiDate.Split("/")
Return PersianDate.ToDateTime(CInt(VarSpl(0)), CInt(VarSpl(1)), CInt(VarSpl(2)), 0, 0, 0, 0, 0)
End Function

Public Function MiladiToShamsi(ByVal MiladiDate As Date) As String
Dim PersianDate As New PersianCalendar
Return PersianDate.GetYear(MiladiDate).ToString + "/" + PersianDate.GetMonth(MiladiDate).ToString + "/" + PersianDate.GetDayOfMonth(MiladiDate).ToString
End Function
End Class

mina.net
سه شنبه 26 آبان 1388, 16:34 عصر
سلام دوستان
من هم فکر می کنم حق با دوست مون جناب kasmaii61 و جناب DoDoklak در اشتباه هستند. بهتره دوباره آزمایش کنند.

DoDoklak
سه شنبه 26 آبان 1388, 16:52 عصر
برنامه کاربر kasmaii61 درست کار میکنه اما من بازم میگم تابع PersianCalendar اشتباه میکنه

دلیل:

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

حالا اینو امتحان کنید


Dim ps As New PersianCalendar
MsgBox(ps.AddDays("1388/12/29", 1))


PersianCalendar یک شی مستقل برای محاسبه و عملیات تاریخ شمسی هستش و خودش تمام کارهای تاریخ رو انجام میده ولی تو افزایش و کاهش ماه و کبیسه رو حساب نمیکنه

ACorvinus
سه شنبه 26 آبان 1388, 18:18 عصر
برنامه کاربر kasmaii61 درست کار میکنه اما من بازم میگم تابع PersianCalendar اشتباه میکنه

دلیل:

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

حالا اینو امتحان کنید


Dim ps AsNew PersianCalendar
MsgBox(ps.AddDays("1388/12/29", 1))


PersianCalendar یک شی مستقل برای محاسبه و عملیات تاریخ شمسی هستش و خودش تمام کارهای تاریخ رو انجام میده ولی تو افزایش و کاهش ماه و کبیسه رو حساب نمیکنه


سلام .

قربونت برم چه گیری دادی به این کبیسه بودن سال ؟
همه یه مثال هایی زدن شما هم متوجه شدی .

به نظر من خودتون برا خودتون یه تابع بنویسین زیاد بد نیست .

سال 999 هجری یه سال کبیسه بوده . حالا 999 رو از تمام سالها کم کنین، اگه Mod اون به 4 برابر صفر شد ماه دوازدهم اون سال میتونه 30 روز باشه در غیر اینصورت نمیتونه 30 روز باشه و باید 29 روز باشه .

یا از همون PersianCalendar کمک بگیرین :



Dim PC As New System.Globalization.PersianCalendar
If PC.IsLeapYear(value as integer) Then
Msgbox("این سال کبیسه است")
Else
Msgbox("این سال کبیسه نیست")
End If

حالا اگه مشکلتون حل نشد بگین من یه تابع براتون بنویسم . جدی میگم . موفق باشی .

mina.net
سه شنبه 26 آبان 1388, 19:29 عصر
سلام دوستان
ظاهرا حرف DoDoklak هم درسته. منتها این چیزی که kasmaii61 گفتن هم مشکل ما رو حل می کنه.
در ضمن برعکس اونچیزی که همه فکر می کنن دقیقا هر 4 سال یکبار یک سال کبیسه نیست. بلکه اندکی تفاوت داره ولی من پیشنهاد می کنم اون تفاوت اند رو بیخیال شیم چون فکر می کنم کاربران عزیز این اشکال رو که احتمالا هر صد سال رخ می ده رو به بزرگواری خودشون خواهند بخشید.
من عکس با کدی که این کار رو انجام می ده رو گذاشتم.

http://www.barnamenevis.org/forum/attachment.php?attachmentid=39943&stc=1&d=1258471749



http://www.barnamenevis.org/forum/attachment.php?attachmentid=39944&stc=1&d=1258471749

kasmaii61
چهارشنبه 27 آبان 1388, 09:06 صبح
این دوست گرامی جهت افزایش تاریخ عملا" از میلادی استفاده کرده نه فارسی به اینصورت که تاریخ شمسی رو به میلادی تبدیل بعد افزایش تاریخ میلادی و بعد تبدیل به شمسی یعنی عملا تاریخ میلادی با تابع مورد نظر افزایش پیدا کرده . خوب من که نگفتم تو میلادی اشتباه میکنه
دوست عزیز اگه کامنت اول من رو هم بخونید اونجا ذکر کردم که ابتدا تاریخ شمسیتون رو به میلادی تبدیل کنید و سپس هر عملیاتی خواستید روش انجام بدید و در نهایت دوباره به شمسی بر گردونید. شما فرمودید که این کد تست نشده و این کار نتیجه اشتباه میده من هم کد براتون گذاشتم که نه درسته
اصل مشکل دوستی که این پست رو زدن اضافه کردن روز و ماه به یک تاریخ بود که با این کد به نظر من حل میشه و با توجه به اینکه از خود توابع تاریخ DotNet استفاده شده هیچ خطایی هم توش نیست حتی اون حالت استثنا سال کبیسه که به جای هر 4 سال یکبار هر 5 سال یکبار اتفاق میفته و دوستان بهش اشاره کردن رو هم محاسبه می کنه
اصل حرف من این بود که به جای نوشتن یه تابع از همین توابع موجود DotNet استفاده بشه تا هم کد نویسی کمتر بشه و هم اطمینان از صحت بیشتر