# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > VB.NET > سوال: بدست آوردن فاصله زمانی بین دو تاریخ شمسی ، جمع و کم کردن تاریخ شمسی

## mina.net

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

----------


## DoDoklak

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

----------


## pirmard

> سلام دوستان
> من تاریخ رو تو بانک به صورت کارکتر و بدون / ذخیره می کنم . حالا می خوام فاصله زمانی بین شون و عمل جمع و تفریق رو بینشون انجام بدم . آیا تابع خاصی برای این کار در تاریخ شمسی وجود داره. 
> البته می تونم یک تابع بنویسم که این کار رو بکنه ولی اگه راه بهتری وجود داره بفرمایید.


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

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

----------


## mina.net

سلام دوستان 
من با خود تاریخ مشکل چندانی ندارم . اتفاقا در مورد تاریخ هم کم کار نکردم. منتها الان دارم امکان فروش اقساطی رو برای برنامه ام  حسابداری ام اضافه می کنم که لازمه مثلا برای دیر کرد لازم هست که فاصله دیر کرد رو مشخص کنم. و یا برای ثبت یک قسط مثلا هفتگی با 20 قسط  لازم هست که 20 تاریخ به فاصله هر 7 روز حساب بشه و ثبت انجام بشه. من منظورم اینچیزا هست. و البته منظورم تو خود برنامه هست نه تو بانک.

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



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


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

----------


## mina.net

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

PublicFunction fasele_tarikh(ByVal first_tarikh AsString, ByVal second_tarikh AsString)
first_tarikh = first_tarikh.Replace("/", "")
second_tarikh = second_tarikh.Replace("/", "")
If Val(first_tarikh) <= Val(second_tarikh) Then
Return"0/0/0"
ExitFunction
EndIf
Dim roz1, roz2, mah1, mah2, sal1, sal2, rozR, mahR, salR AsInteger
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 AsInteger = 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
EndIf
EndIf
If mah1 >= mah2 Then
mahR = mah1 - mah2
Else
mah1 += 12
sal1 -= 1
mahR = mah1 - mah2
EndIf
salR = sal1 - sal2
'Dim Dir_fasele As Double = salR + (mahR / 12) + (rozR / 365)
Dim str_fasele AsString = salR & "/" & mahR & "/" & rozR
' Dir_fasele = (Dir_fasele * (darsad / 100)) * mablagh
Return str_fasele
EndFunction

----------


## DoDoklak

یه سری به اینجا بزنhttps://barnamenevis.org/showthread.php?t=179632

----------


## majid_vb_2008

اين تابع بين دوتا تاريخ رو به روز بر مي گردونه

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

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

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

> اين تابع بين دوتا تاريخ رو به روز بر مي گردونه
> 
> 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

سلام دوستان 
جناب *majid_vb_2008* تابع شما را استفاده کردم خوب بود . آیا تابع مشابهی برای جمع و تفریق تاریخ وجود دارد؟ اگه تابعی برای این کار دارید ممنون می شم بزارید.

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

----------


## DoDoklak

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

----------


## mina.net

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


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

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

Dim d1 AsDouble = 1.1 * 100
If d1 = 110 ThenExitSub

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

----------


## arsalansalar

http://www.barnamenevis.org/sh...d.php?t=175669

----------


## DoDoklak

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

----------


## mina.net

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


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

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

----------


## ricky22

دوستان من تاریخ فارسی رو با تابع datediff مقایسه می کنم و مشکلی ندارم
چرا از اون استفاده نی کنید؟

----------


## Reza Safa

دوستان با عرض پوزش نیازی به این همه خط تو خ کردن نیست

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

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

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

----------


## tecnocomputer

واسه جاوا اسكريپت همچين چيزي نداريد؟

----------

