کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی
کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی

تبدیل تاریخ میلادی شمسی - اختلاف روزهای شمسی از سال 1300 تا کنون


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







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


بررسی اختلافِ روزها از  سال 1300 تا تاریخ شمسی بزرگتر از این تاریخ


بررسی روزِ هفته یِ تاریخ شمسی مورد نظر و مروری بر تابع پربرکت WeekDay در اکسس


بررسی تابع بابرکت Choose  در اکسس 


بررسی سن فرد


با ما باشید حتی اگر Vba نمی دانید مباحث در انتها شیرین خواهد شد 


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




dDate : "2021/01/04"  ....  1400/10/14


گرفتن سال ، ماه و روز بصورت جداگانه با توابعی که اکسس در اختیار ما قرار داده 


YY=Year(dDate)=2021

MM=Month(dDate)=1

DD=Day(dDate)=4




 Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are


هر سالی که دقیقا بر 4 بخش پذیر باشد ، سال کبیسه است ( Leap Year ) ، جز سال هایی که بر یک قرن که 100 سال است بخش پذیر باشد . اینها در صورتی کبیسه هستند که  دقیقا بر 400 بخش پذیر باشند. مثلا سال های 1700 ، 1800 و 1900 کبیسه نیستند ولی 1600 و 2000 کبیسه هستند.



پس سال 2022 کبیسه نیست و ماه فوریه 28 روز است .


 تابع زیر تاریخ میلادی را داخل دابل کوتیشن می گیرد و مقدار Boolean را بر می گرداند.اگر کبیسه نباشد مقدار برگشتی False است.


IsLeapYear(dDate As Date) As Boolean

Dim GetYear As Long

GetYear=Year(dDate)


IsLeapYear=?

'select  iif(612 mod 100=0,iif(612 mod '400=0,True,False),iif(612 mod 4=0,True,False))


?IsLeapYear("2021/01/04"

False


Leap years within your range:1600~2004

1600, 1604, 1608, 1612, 1616, 1620, 1624, 1628, 1632, 1636, 1640, 1644, 1648, 1652, 1656, 1660, 1664, 1668, 1672, 1676, 1680, 1684, 1688, 1692, 1696, 1704, 1708, 1712, 1716, 1720, 1724, 1728, 1732, 1736, 1740, 1744, 1748, 1752, 1756, 1760, 1764, 1768, 1772, 1776, 1780, 1784, 1788, 1792, 1796, 1804, 1808, 1812, 1816, 1820, 1824, 1828, 1832, 1836, 1840, 1844, 1848, 1852, 1856, 1860, 1864, 1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936, 1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004



سرآغاز گاهشماری ایران روز جمعه «۱ فروردین سال ۱ هجری خورشیدی» (۲۹ شعبان ۱ سال پیش از هجرت)[۷] برابر با ۱۹ مارس ۶۲۲ میلادی قدیم (یولیانی) و ۲۲ مارس ۶۲۲ میلادی جدید (گرگوری) است؛ یعنی، ۱۱۹ روز پیش از مبدأ گاه‌شماری هجری قمری و ۱۷۹ روز پیش از هجرت.[۸]


کبیسه گیری گاه شمار رسمی ایران : 


تقویم رسمی کنونی ایران معمولاً هر چهار سال یکبار کبیسه می‌شود و برای جبران کسر سال حقیقی، در آغاز هر دورهٔ ۲۹، ۳۳ یا ۳۷ساله، یک کبیسه پنج ساله وجود دارد. در یک فراز پنج هزارساله، ما به ازای هر دورهٔ ۳۷ساله، نزدیک به پنج دورهٔ ۲۹ساله و تقریباً ۲۰ دورهٔ ۳۳ساله وجود دارد. ترتیب و توالی کبیسه‌ها قاعده‌مند نیست. چنانچه لحظه تحویل سال خورشیدی بعد از ظهر ۳۶۶اُمین روز از سال باشد، آن سال کبیسه و روز بعد نوروز است.[۱۴]


برای تشخیص سال‌های کبیسه در گاهشماری رسمی ایران شیوه کاملاً یکنواختی وجود ندارد. برای سال‌های ۱۲۴۴ تا ۱۳۴۲ چنانچه باقی‌ماندهٔ حاصل تقسیم سال مورد نظر بر عدد ۳۳، یکی از اعداد (۱، ۵، ۹، ۱۳، ۱۷، ۲۱، ۲۶ و ۳۰) باشد آن سال کبیسه خواهد بود.[۷] و برای سال‌های اخیر (سال‌های ۱۳۴۳ تا ۱۴۷۲)، به‌جای ۲۱، باقی‌ماندهٔ ۲۲ ملاک خواهد بود


جدول اعداد تعیین‌کننده کبیسه «تقویم حسابی بهروز-بیرشک» تا سال ۳۲۹۳ هجری خورشیدی حسابی

۰ – ۴ – ۸ – ۱۲ – ۱۶ – ۲۰ – ۲۴ (۲۵) – ۲۹ – ۳۳ – ۳۷ – ۴۱ – ۴۵ – ۴۹ – ۵۳ – ۵۷ (۵۸) – ۶۲ – ۶۶ – ۷۰ – ۷۴ – ۷۸ – ۸۲ – ۸۶ – ۹۰ (۹۱) – ۹۵ – ۹۹ – ۱۰۳ – ۱۰۷ – ۱۱۱ – ۱۱۵ – ۱۱۹ (۱۲۰) – ۱۲۴


مانده سال شمسی مورد نظر تقسیم بر 128 اگر یکی از اعداد بالا بود آن سال کبیسه است و برای سال های 1 تا 473 گفته اعداد داخل کمان مد نظر است.


البته گفته شده چون در چند دوره 33 ساله قرار گرفته ایم مانده عدد تقسیم بر عدد 33 اگر اعدادی در بازه 1 ، 5 ، 9 ، 13 ، 17 ، 21 ، 26 ، 30  بود آن سال کبیسه است البته اگر عدد 22 شد کبیسه ۵ ساله می شود.




سال 1300، 1304 ، 1309 کبیسه هستند.


128 : 1,3091,280=29 

1,3751,280=95

33    : 1,30933×39=22    کبیسه پنج ساله

33    : 1,37541×33=22   کبیسه پنج ساله


سالهای 1399 و 1403 کبیسه 4 ساله و سال 1408 کبیسه پنج ساله هستند چون مانده  تقسیم  1408 بر 33 عدد 22 است.


1,40842×33=22

1,40811×128=0  طبق جدول


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

(۱۳۹۱+۲۳۴۶)×(۰/۲۴۲۱۹۸۵۸۱۵۶) =۹۰۵/۰۹۶۰۹۹۲۹۱

اگر عدد اعشار که درمثال بالا 0.096099291 از عدد 0.24219858156 کمتر بود آن سال کبیسه است یا 


(1,408+2,346)×0.2421985815=909.213474951 

که عدد اعشاری کمتر از عدد اعشاری ضرب شده است و بنابراین سال کبیسه است البته تا 2346 اعتبار دارد.

پس طبق موارد گفته شده در بالا هر کدام که بهتر بود را انتخاب نموده و تابعی بنویسید تا کبیسه بودن یا نبودن را مشخص نماید 


تاریخ 1/1/1 برابر است با 22 مارس 622 میلادی ... برای بدست آوردن اختلاف روز میلادی در دو بازه این تاریخ و تاریخ میلادی مد نظر را بدست می آورید و بعد می توانید از یک Counter استفاده کنید که یکی یکی increment شود و به 1/1/1 اضافه شود واگر سالی کبیسه بود برج 12 آن 30 روزه در نظر گرفته شود.

Function IsShamsiLeapYears(y As Integer) As Boolean
Select Case y Mod 33
     Case 1, 5, 9, 13, 17, 21,22, 26, 30  'No : 22  Leap 5 
     IsShamsiLeapYears = True
End Select
End Function
?IsShamsiLeapYears("1407")
False
?IsShamsiLeapYears("1408")
True

Function IsShamsiLeapYears1(y As Integer) As Boolean
Select Case y Mod 128 And (y <= 3293 or y>473)
     Case 0, 4, 8, 12, 16, 20, 24, 29, 33, 37, 41, 45, 49, 53, 57, 62, 66, 70, 74, 78, 82, 86, 90, 95, 99, 103, 107, 111, 115, 119, 124
     IsShamsiLeapYears1 = True
End Select
Select Case y Mod 128 And (y>1 Or y <= 473)
     Case 25, 58, 91, 120
     IsShamsiLeapYears1 = True
End Select

End Function




Function GetMiladiDays(M)
Select Case M
   Case 1, 3, 5, 7, 8, 10, 12: DD = 31: Case 4, 6, 9, 11: DD = 30: Case 2: DD = 28
End Select
GetMiladiDays = DD
End Function

Function GetShamsiDays(M)
Select Case M: Case 1 To 6: DD = 31: Case 1 To 11: DD = 30: Case 12: DD = 29: End Select
GetShamsiDays = DD
End Function


غیر از روش Counter بالا که یکم کند ولی دقیق است ،  راه دیگری پیشنهاد شده ولی می بایست در صحت و سقم آن کنکاش بیشتری نمود

روش به این ترتیب گفته شده که در حالتی که دو تاریخ کبیسه نیستند .تعداد روزها از اول فروردین تا 10 دی برای سال های غیر کبیسه میلادی که میشود 
6×31+3×30+10=286
تعداد روزها از اول فروردین تا 11 دی برای سال های کبیسه میلادی که میشود 
6×31+3×30+11=287

365-286=79
365-287=78

البته12 هم اول ژانویه میشود مثل سال 1293 میلادی  پس در عملکرد مناسب ماژول زیر باید کنکاش بیشتری کرد.


در نتیجه چون دو سال 1293 میلادی و 671 شمسی کبیسه نیستند لذا اول ژانویه بایدبرابر 10 دی شود درحالیکه 12 دی شد پس محاسبه زیرین قطعا به مشکل برخواهد خورد .

فرضا میخواهید معادل شمسی تاریخ میلادی 1997/01/20 را بیابید مراحل زیر را طی کنید البته در بعضی موارد با اختلاف یک روز می دهد  که بعدا شرح می دهیم 

1-بدست آوردن روزهای سپری شده از ماه میلادی  ، چون سال 1997  کبیسه است لذا ماه فوریه می بایست 29  در نظر گرفته شود. در اینجا 20 روز گذشته و به ماه فوریه که 2 میلادی است ربطی ندارد ولی حتما برای ماه های دیگر این نکته فراموش نشود.
Dim YY,MM,DD As single
Dim i As Integer
YY=Year(dDate)
MM=Month(dDate)
DD=Day(dDate)
For i=1 To MM
x=x+iif(i=MM And DD<GetMiladiDays(MM),DD,GetMiladiDays(MM))
Next
Debug.Print x
2-برای تعیین سال شمسی  اگر روزهای گذشته میلادی از 79 ( اختلاف اول ژانویه تا آخر اسفند در صورتیکه دو تا کبیسه نباشند ) کوچکتر بود سال میلادی را منهای 622 می نمائیم .در غیر اینصورت 621 و شاید حالات دیگر هم وجود داشته باشد می بایست چک شود. در اینجا چون کوچکتر است سال شمسی میشود 1375
if x<79 Then y=YY-622 Else y=YY-621
3-اگر سال شمسی کبیسه بود که در اینجا 1375 سال کبیسه است جمع روزهای سال شمسی 366 در نظر گرفته میشود ، در غیر اینصورت 365  .. درنهایت 79 را از آن کم کرده و به روزهای سپری شده میلادی می افزائیم در نتیجه عدد بدست آمده میشود 307=20+79-366
4-عدد 307 بدست آمده را باید در روزهای شمسی سرچ کنید که در کدام ماه می افتد در این مورد جمع ماه ها تا برج  10 عدد 306 است و تا برج 11 عدد 336 پس در ماه 11 قرار دارد ... لوپ زیر بدست آوردن ماه Simulate شده ( cc جمع ماه ها است و این لوپ به انداره مقدار ii برای تابع GetMiladiDays و شرط ادامه پیدا می کند ، شرط : تا زمانیکه جمع ترتیبی ماه های شمسی از یک تا ... کوچکتر از 307 باشد و باصطلاح False شود )  ff در اینجا 307 است.

307>306 ( 10 ) که می شود True  و بعد 307> 336(11) و می شود False و در ii=11 این لوپ خاتمه می یابد.

اگر در یک Function استفاده می کنید چون i یکبار در بالا ذکر شده در این لوپ ii استفاده کنید یا i را برابر صفر قرار دهید ( اگر صفر نکنید همان مقدار i در بالا را نقطه شروع قرار میدهد.
Dim ii As Integer
ii = 0
Do While cc < ff  '366<366 = False Exit Loop
ii = ii + 1
cc = cc + IIf(ii = 12 And IsShamsiLeaped = True, 30, GetShamsiDays(ii))
Loop
Debug.Print "Shamsi Month :" & ii

ff=307
ii=1    cc=31
ii=2   cc=62
.
.
.
ii=10  cc=306  cc<ff  306<307 True
ii=11 cc=336  cc<ff  336<307  False 'Exit Here
So ii=11 And cc=336

5-برای بدست آوردن روز باید روزهای ماه های شمسی را باهم جمع بزند تا به عددی برسد که اختلافش  با عدد 307 مثبت باشد.

ff-cc>0  307-306>0       1   True
ff-cc>0  307-336>0  -29 False
?(307-306>0)
True
?(366-336>0)
True
?(366-366>0)
False




خب روش بالا خالی از شکال نیست چون 12 دی 1293 برابر 1 ژانویه است نه 10 یا 11 دیماه که در یکسری وبلاگ ها بیان شده ... پس 12 دی برابر اول ژانویه هم می تواند باشد که بود .... با با حساب می توانید چک کنید.


در تابع زیر تعداد کبیسه های میلادی همانطور که در مطالب بالا گفته شد ، بیان شده فرضا از 1 تا سال 622 میلادی 150 کبیسه وجود دارد که از آن برای محاسبات استفاده می نمایند.

Function NumberOfLeapYears(Year As Long)
For i = 1 To Val(Year) Step 1
c = c + (IIf(i Mod 100 = 0, IIf(i Mod 400 = 0, 1, 0), IIf(i Mod 4 = 0, 1, 0)))
Next
Debug.Print c
End Function
?NumberOfLeapYears(622)
 150
?NumberOfLeapYears(2022)
 490 

در روش دیگر می توانید مبنا را بگذارید بر تاریخ خاصی 

سال های کبیسه شمسی بین 1300 تا 1441 : 

1300,1304,1309,1313,1317,1321,1325,1329,
1333,1337,1342,1346,1350,1354,1358,1362,
1366,1370,1375,1379,1383,1387,1391,1395,
1399,1403,1408,1412,1416,1420,1424,1428,
1432,1436,1441

سال های 1309 ، 1342 ، 1375 ، 1408 و  1441 جزء کبیسه های 5 ساله اند که باقیمانده تقسیم آنها به 33 عدد 22 است.



Like : 1300/01/01=1921/03/21
با تابع DateDiff در اکسس اختلاف تا تاریخ روز میلادی فرضا 2022/01/06 گرفته شد و عدد 36816 بدست آمد :
?DateDiff("d","1921/03/21","2022/01/06")
 36816
تعداد سال های کبیسه بین مبدا قراردادی ما یعنی از 1921 تا 2022 شد 25 سال
?NumberOfLeapYearsRange(1921,2022)
 25 

?(36816-25*366+1)-((36816-25*366)\365+1)*365
292 
OR 
?(36816-25*366+1)-75*365
 292 
?292-6*31-3*30  
 16 
1300+25+75=1400 ' سال 
10 ' ماه
16 ' روز

1978/09/11  = 1357/06/20
?(20993-14*366+1)-((20993-14*366+1)\365)*365
 175 
?175-5*31 ' 5+1 =6 ماه
 20 'روز  
1300+14+43=1357 ' سال

1981/07/20=1360/04/29
?datediff("d","1921/03/21","1981/07/20")
 22036 ' اختلاف روزهای میلادی
?NumberOfLeapYearsRange(1921,1981)
 15  ' تعداد کبیسه های میلادی دو بازه 1921تا 1981
?(22036-15*366+1)-((22036-15*366+1)\365)*365 
 122 
?(22036-15*366)\365
 45 
?122-3*31 ' 3+1=4 ماه شمسی
 29  ' روز شمسی
1300+15+45=1360 ' سال شمسی

1996/03/20=1375/01/01
?dateDiff("d","1921/03/21","1996/03/20")
 27393 
?NumberOfLeapYearsRange(1921,1996)
 19 ' تعداد کبیسه های میلادی بین 1921 تا 1996
 ?(27393-19*366+1)\365 
 56 
?(27393-19*366+1)-((27393-19*366+1)\365)*365
 0 ' چون صفر شد ماه یک و روز یک را درنظر می گیریم
?1300+19+56=1375 ' سال شمسی
 
2013/03/20=1391/12/30
?NumberOfLeapYearsRange(1921,2013) 
 23  ' تعداد سال های کبیسه 1921 تا 2013
?dateDiff("d","1921/03/21","2013/03/20")
 33602 ' اختلاف دو تاریخ میلادی که 1921 مبدا قرار دادیم
 ?(33602-23*366+1)-((33602-23*366+1)\365)*365  
 0   ?????
?(33602-23*366+1)\365
 69  ?????
 ?1300+23+69
 1392 ?????

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

یک راه دیگر :  اختلاف دو بازه میلادی یعنی 1921/03/21 و تاریخ جاری رابدست می آوریم و تقسیم بر 364.25 می نمائیم که تعداد سالهایی که به عدد 1300 اضافه می کنیم بدست آید.

27393\365.24=75
1300+75=1375
27393-75×365.24=0
عدد صفر بدست آمد که ماه و روز را یک میگیریم

1996/03/26=1375/01/07

27,399÷365.24=75

1300+75=1375 ' سال شمسی 

27399-75×365.24=6 '6+1 =7 روز شمسی

عدد 6 را با عدد یک جمع می کنیم میشود روز هفتم 



33602/365.24=91.999
1300+91=1391 ' سال شمسی
33602-91×365.24=365.16

همانطور که گفته شد مبدا محاسبه ما برای اضافه کردن 1300/01/01 قرار گرفت ( یعنی تعداد اختلاف روزهای میلادی 1921/03/20 و تاریخ میلادی روز یا بزرگتر از 1921 را با DateDiff در اکسس بدست آورده و با Counter به 1300/01/01 اضافه می نمائیم )

20993/365.24=57.47
1300+57=1357 ' سال شمسی
20993-57×365.24=174.32 'int(174.32)=174
174+1=175 ' با روز یک سال 1300 جمع شد
175-5×31=20 ' روز شمسی 
5+1=6 ' ماه شمسی

2016/10/31=1395/08/10
DateDiff : 34923 Days 
34923/365.24=95.61
1300+95=1395 ' سال شمسی
34923-95×365.24=225.2 ' int(225.2)=225
225+1+6×31-1×30=10 ' روز شمسی
6+1+1=8 ' ماه شمسی

'همانطور که در بالا اشاره شد مبدا 1921/03/21
1992/09/30=???
'select 'datediff("d","1921/03/21","1992/09/30")
26126 ' اختلاف روزهای میلادی 
26126/365.24=71.53
1300+71=1371 ' سال شمسی

26,126365.24×71=193.96 'int(193.96)

193+1-6×31=8 ' روز شمسی

6+1=7 ' ماه شمسی


1921/03/21=?

'select 'datediff("d","1921/03/21","1921/03/21")

0

0\365.24=0

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


Function ShamsiDate(dDate As Date)

Dim Miladi As Date, Shamsi

Dim DaysDiff As Long

Miladi = "1921/03/21"

Shamsi = "1300/01/01"

DaysDiff = DateDiff("d", Miladi, dDate)

debug.Print DaysDiff

?shamsiDate("2016/10/31")

 34923 


البته تابع بالا کامل نشده و فقط اعلام شده که DaysDiff که ازتابع DateDiff گرفته شده پرینت شود.همانطور که ملاحظه می فرمائید خروجی عدد 34923 بدست آمد و این عدد باید به 1300/01/01 اضافه شود.


جمع بندی برای محاسبه از طریق 365.24 


34,923÷365.2421985815 =95.618

(34923+1)-95×365.2421985815=225.99

  226      1395/08/10

22,036÷365.2421985815 =60 .33

(22036+1)-365.2421985815×60 =122.46       

122      1360/04/29

27,39365.2421985815=74.99

 (27,393+1)365.2421985815×74=366.07

 366       1375/01/01

33,60365.2421985815=91.99

(33,602+1)365.2421985815×91=365.95          

 365   1391/12/30

20,993÷365.2421985815÷57.47

(20,993+1)365.2421985815×57 =175. 19

175   1357/06/20

26,126÷365.2421985815=71.53

(26,126+1)-365.2421985815×71=194.80

194  1371/07/08


روش بالا هم بی اشکال نیست چون یک روز اختلاف در آن اجتناب ناپذیر است اگر روش شما تست نشود مثل تصویر زیر خواهد شد که اختلاف یکروز را منجر خواهد  شد:




روش دیگر این است که تعداد کبیسه های دو تاریخ میلای بدست آید یکی از آن کم شود بعد در 366 ضرب شده و از اختلاف روزهای دو تاریخ میلادی کم شوند و سپس بر 365 تقسیم شده ..... 


1921/03/21 'مبنای ما 1300/01/01

1996/03/20 ' تاریخی که باید تبدیل شود

DateDiff=27393

NumberOfLeapYearsInRange(1921,1996)=19

19-1=18

(27393-18×366)÷365=57

57-1=56

(27393-18×366)-56×365=365

365+1=366 'چون 1300 کبیسه بود

1300+18+56=1374

1374 ' کبیسه نیست  و 365 روز دارد

چون عدد 366 بدست آمد به 1374 می افزائیم در نتیجه چون سال 74 کبیسه نیست پس 365 روز و معادل یکسال است در نتیجه سال 75 میشود و یک روز اینجا باقی میماند که میشود روز یکم فروردین 

1375/01/01


2013/03/20 

NumberOfLeapYearsInRange(1921,2013)=23

DateDiff=33602

23-1=22

(33602-22×366)÷365=70

70-1=69

(33602-22×366)-365×69=365

365+1=366

1300+22+69=1391  ' کبیسه است 

چون 1391 کبیسه است لذا 366 روزه است و در نتیجه سال همان 1391  باقی می ماند و ماه سال میشود 12 و روز نیز میشود 30 اُم ...... پس تاریخ میلادی 2013/03/20 معادل 1391/12/30 شد.




2000/03/20 =????? 137901/01

1921/03/21~2000/03/20

DaysDiff=28854

NumberOfLeapYersInRange(1921,2000)=18

18-1=17

(28854-17×366)÷365=62.005

62-1=61

(28854-17×366)-365×61=367

1300+17+61=1378



خب باروش بالا هم به بن بست خوردیم  



پس دقیق ترین روش استفاده از Counter است که تعداد اختلاف روزها را به 1300/01/01 اضافه کنیم و اینکار اگر بخواهد یک روز یک روز به این تاریخ اضافه کند یک مقدار زمانبر است ولی خب بسیار دقیق است البته کبیسه گیری شمسی نیز در این امر بسیار مهم است !!!


در مثال زیر تعداد کبیسه های شمسی از 1300 تا 1391 23 تاست که کبیسه اول ( چون اختلاف اول فروردین تا 30 اسفند 1300 ،  365 روز است ) و آخر ( سال 91 ) از آن کم شده که تا تقریبا یکسال قبلش بدست آید  91=70+21 ، سال 1391 و کبیسه است پس 366 روز میشود  همان 12/30

71-1=70

(33,60221×366)70×365=366


(6,5743×366)÷365=15

15-1=14

(6,5743×366)-14×365=366

1300+3+14=1317  ' کبیسه است 

1317/12/30


(6,5753×366)14×365=367

1300+3+14=1317 ' کبیسه است 

366 '1317/12/30

1         '1318/01/01


نوشتن لوپ برای کم کردن 365 یا 366 روز از اختلاف روزهای میلادی 


'1978/09/11=1357/06/20

ii=0

DaysDiff=DateDiff("d","1921/03/21","1978/09/11")

Diff=DaysDiff

Do

x=Diff-iif(IsLeapYears1(1300+i)=True,366,365)

Y=Year(dDate)+1  ' تابع  Year("1978/09/11")=1978

YY=1300+i

ii=ii+1

Loop Until Y=Year(dDate)-1

Debug.Print x

Debug.Print YY


???? Maybe Use But Not Reliable

(6,5754×366)13×365=366 '1300+4+13=1317/12/30

از 1921 تا 2013 =92 

Right Way   '2013/03/20

(33,602+122×366)69×365=366 '1300+22×69=1391/12/30


' Loop : To Get jalali leap years from 1300

t=1300+(2013-1)-(1921+1) '1390

For i = 1300 To t '1390

x = x + IIf(IsShamsiLeapYears1(i) = True, 1, 0)

DoEvents

Num=x

If IsShamsiLeapYears1((1390)) = True Then Num = x - 1

Next

Debug.Print Num 

?ShamsiDate()

22


کابرد Doevents  : اگر Loop نامناسبی نوشته شد که درجا بزند و انتهایی نداشته باشد  دقیقا بعلت اشتباه غلط خودمون بتوانیم با Stop از لوپ خارج شویم وگرنه سیستم هنگ می کند چون لوپ بی نهیت میخواهد اجرا شود.



e = Int((DaysDiff+1 - Num * 366) / 365) - 1

Y=1300+e+Num '1300+22+69

Debug.Print "Contant :" & e

diff = (DaysDiff+1 - Num * 366) - e * 365

Debug.Print "Diff :" & diff

?ShamsiDate("1939/03/21")
DaysDiff :6574
Y  :1317
Contant :14
Diff :366




از یک لوپ بعنوان کانتر می شود استفاده کرد که بین 1 تا عدد 366 یا بیشتر که بدست آمد یک Counter یا شمارنده ایجاد بنماید ( حالت افزایشی تکی ) .Increment مثل عبارت Counter استفاده شده در AutoNumber .


'Counter

Function ShamsiDateCounter(yy, diff)

Dim Y As Single

Dim MM, DD, i, a As Integer

For i = 1 To diff

DD = DD + 1

If DD > IIf(MM=12 And IsShamsiLeapYears1(yy) = True, 30, GetShamsiDays(MM)) Then MM = MM + 1: DD = 1

If MM > 12 Then yy = yy + 1: MM = 1

'CurrentDb.Execute ("delete from table2")

'CurrentDb.Execute ("insert into table2 (mah,rooz) values (" & MM & "," & DD & ")")

Next

Debug.Print yy & "..." & MM & "..." & DD

End Function

?ShamsiDateCounter(1378,36)

1378...2...6

?ShamsiDateCounter(1378,365)
1378...12...29
?ShamsiDateCounter(1378,366)
1379...1...1
?ShamsiDateCounter(1378,368)
1379...1...3
?ShamsiDateCounter(1378,396)
1379...2...1





از کانتر بالا نیز می توان برای چند ماه و چند روز از سال گذشته استفاده کرد . تاریخ شمسی طبق روز میلادی جاری بدست آمده و فقط یک پارامتر Optional به آن  اضافه کنید ، اگر مقدارآن True بود تاریخ شمسی را بگیرد و سپس لوپ را تا آن ماه مشخص ادامه دهد.


برای وارد کردن صحیح  ماه و روز در تکست باکس در زمان Data Entry یا زمان داده گیری ، می توان در رویداد OnExit خود تکست باکس نوشت در صورتیکه Dirty=True شد چک کند که ماه بین یک تا 12 باشد و روز هم طبق ماهی که وارد شده و کبیسه بودنش اگر نبود Undo کند و در BeforeUpdate فرم هم می توان نوشت که تکست باکس اگر خالی باشد Cance=True شود. 


پس راه من درآوردی ما بدین شکل شد :


1-مبنای محاسبه  را  تاریخ 1921/03/21 معادل 1300/01/01 قرار دادیم.

2-بدست آوردن کبیسه های شمسی بین دو بازه تاریخ میلادی البته  یک واحد از سال میلادی مورد نظر کم می کنیم و به مبنا اضافه ،  فرضا سال میلادی تبدیلی 2013 است

2012-1922=90 ' 1300+90=1390

تعداد سال های کبیسه از 1300 تا 1390 طبق لیست کبیسه ها که در بالاتر ذکر شده 22 است.اگرسال آخر کبیسه بود یک واحد از تعداد کبیسه ها کم می کنیم.


3-اختلاف روزهای دوبازه تاریخی یعنی مبنا و تاریخ تبدیلی را با تابع بسیار پربرکت DateDiff بدست می آوریم و یک واحد بخاطر جبران سال 1300 مبنا که کبیسه است و اختلاف اول فروردین آن تا 30  اسفند  آن 365 روز است ، اضافه می نمائیم . از سایت  w3Schools نیز می توانید استفاده کنید اگر سیستم ندارید مثال : 

DaysDiff=DateDiff("d","1921/03/21","2013/03/20")



پس طبق تصویر اختلاف روزهای دو تاریخ میلادی شد 33602 روز. و با یک جمع می کنید 33603


4-تعدادکبیسه در 366 را از روزهای بدست آمده کم می کنیم و بر 365 تقسیم می کنیم و عدد صحیح آنرا منهای یک می کنیم : 

(33603-22×366)/365=70.0027

Int((33603-22×366)/365)=70

70-1=69

5- 69 را با تعداد کبیسه ها جمع می کنیم میشود 91

6- حاصل عدد 69 در 365 را از حاصل تفریق تعداد کبیسه در 366 و تعداد روزها + یک میشود مانده ی ما یا Diff 

(33,60322×366)69×365=366

7-عدد حاصله را در یک تابع Counter گذاشتیم تا بگوید 366 روز بعد از سال 91 چه تاریخی خواهد شد .

چون 91 کبیسه است 366 اُمین روزش میشود 12/30 در نتیجه خروجی ما 1391/12/30 خواهد بود.


میشود از کانتر استفاده کرد و عدد 33602 باضافه یک  را یکی یکی اضافه کرد تا بعد از 1300 را نشان دهد ولی خب کُندِس و حدود 5 ثانیه طول میکشد تا جواب بدهد.


مثال دیگر : 2022/01/08 ( مبنا 1921/03/21 )

DaysDiff=36818

2022-1-1922=99+1300=1399

Leaps Between 1300 ~ 1399=25

چون 1399 کبیسه است پس یک واحد از تعداد کبیسه کم کنیم.

int((36,818+124×366)÷365)=76.80

76-1=75

(36,818+124×366)-75×365=660

Y=1300+24+75=1399,Diff=660

چون 1399 کبیسه است 366 از 660 کم میشود و 294 می ماند 294 اُمین روز سال هم میشود 10/18 یا 294=18+30×3+31×6 .... کانتر محاسبه بعد از 1399 را انجام خواهد داد.


1921/03/21-1939/03/20:6573

1921/03/21-1939/03/21:6574

1921/03/21-1939/03/22:6575

اول اضافه کردن یک واحد به سال مبنا که 1921 است و کسر کردن یک واحد از سال تبدیلی که 1939 است

1300+(1,9391)(1,921+1)=1316

مورد اول  تعداد کبیسه ها از 1300 تا 1316 ، عدد 4 است و خوشبختانه 1316 کبیسه نیست اگر بود از 4 یک واحد کسر می شد.

(6573+1-4×366)/365=14

14-1=13

(6,573+14×366)13×365=365

1300+4+13=1317

سال 1317 کبیسه و 366 روزه است پس 365 اُمین روز آن 12/29 می شود 1317/12/29.


'6575

Diff=(6,575+14×366)13×365=367

1300+4+13=1317 , 367 

چون 1317 کبیسه است پس 366 از 367 کم شده و یکسال به سال اضافه میشود ( تابع کانتر را ملاحظه بفرمائید ) سال میشود 1318 و روز و ماه هم یک می شود.

1318/01/01


همانطور که شرح داده شد روش آخر اگر چه حدود دو ثانیه طول می کشد ولی Reliable است البته برای زیر 365 یا 366 نیز چاره ای بیاندیشید.


در مورد زیر : 


1921/03/21~1922/03/22=366

1301/01/01

1300+1921+1-(1922-1)=1301

در 1300 تا 1301 یک کبیسه  وجود دارد

(366+1-1×366)÷365=0.002

0

if 0 Then 

Diff=DaysDiff+1 : Y=1300

End if

Counter (1300,367)

چون 1300 کبیسه است لذا 366 روزه است بعد از ارسال به کانتر باید جواب 1301/01/01 استخراج شود.


1921/03/21~1922/03/21=365

1300+(1921+1)-(1922-1)=1301

1 Leap Years ( jalali )

(365+1-1×366)=0

if 0 Then

Diff=365+1 : Y=1300

Counter(1300,365)

1300/12/30


1921/03/21~1922/06/13

DaysDiff(Use DateDiff)=449

1300+(1921+1)-(1922-1)=1301

(449+1-1×366)÷365=0

if 0 Then

Diff=449+1 : Y=1300

Counter(1300,450)


روش دیگری هم می توانید خلق کنید.



اگر روش های بالاتر را بکار ببرید اختلاف یکروز کاملا مشهود خواهد بود مثل تصویر زیر 













ملاحظه کنید کدام یک از روشها بهتر است همان را اجرا بنمائید.البته با تحقیق بیشتر و محاسبات  گوناگون !!!


لطفا پس ازاستفاده فاتحه ای برای پدر مرحومم قرائت فرمائید.



اختلاف روزهای شمسی از سال 1300 : 


شرح محاسبات  : 

1-سال شمسی را از سال مبنا که در اینجا 1300 قرار دادیم کم میکنیم 
2-تعداد کبیسه ها از 1300 تا یکسال قبل از سال شمسی مورد نظر را بدست آورده و منهای یک می کنیم 
3-اختلاف بدست آمده در مرحله یک را در 365 ضرب و به تعداد مرحله 2 می افزائیم 
4-تعداد روزهای سپری شده سال شمسی مورد نظر را بدست آورده به مرحله 3 می افزائیم . براحتی اختلاف از سال 1300بدست آمد بدون خطا ، موارد زیر نیز با DateDiff مقایسه گردید. کبیسه ها مهم هستند در محاسبات !!!

سال های کبیسه شمسی بین 1300 تا 1441 : 

1300,1304,1309,1313,1317,1321,1325,1329,
1333,1337,1342,1346,1350,1354,1358,1362,
1366,1370,1375,1379,1383,1387,1391,1395,
1399,1403,1408,1412,1416,1420,1424,1428,
1432,1436,1441

2013/03/21=1392/01/01
'jalali leap year 1300-1391=23-1=22

92×365+22+1=33603


2013/03/20=1391/12/30

'jalali leap year 1300-1390=22-1=21

91×365+21+366=33602

چون تا 12/30 میشود 366 روز لذا اضافه شده 


select datediff("d","1921/03/21","2022/01/09")

Equivalant :1400/10/19 - 2022/01/09

=36819

'jalali leap year 1300~1399=25-1=24

1400-1300=100

100×365+24=36524

36819-36524=295

295=6×31+3×30+19

100×365+24+6×31+3×30+19=36819


1357/06/20 '1978/09/11  یازدهم سپتامبر
1357-1300=57
'jalali leap year 1300~1356=14-1=13
57×365+13+(5×31+20)=20993
select datediff("d","1921/03/21","1978/09/11")

1378/10/10-1999/12/31
1378-1300=78
jalali leap years 1300~1377=19-1=18
78×365+18+(6×31+3×30+10)=28774

1378/10/11-2000/01/01
1378-1300=78
jalali leap years 1300~1377=19-1=18
78×365+18+(6×31+3×30+11)=28775

دو عدد بالا را با تصویر زیر مقایسه کنید اینهم اثبات روش 







1300~1391 'کبیسه ۲۲ منهای یک 

91×365+21+6×31+3×30+12=33524


کبیسه های میلادی از 1920 تا 2104 :
Leap years within your range:

1920, 1924, 1928, 1932, 1936, 1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060, 2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, 2096, 2104

 تبدیل شمسی البته بعد از سال 1300 به میلادی چون سال مبنا را 1300/01/01 معادل 1921/03/21 قراردادیم 

1921+(1391-1300)=2012
'Leap Years 1921~2011

33,524+(31+28+21)91×36522=367

سال 2012 کبیسه است و 366 روزه در نتیجه چون عدد 367 بدست آمد یک واحد به سال 2012 اضافه و روز و ماه نیز یک میشود  

2013/01/01

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

تعداد روزهای میلادی به ترتیب از سمت چپ :
31,28 or 29 31,30,31,30,31,31,30,31,30,31

1357/06/20 '1978/09/11  یازدهم سپتامبر
1357-1300=57
1921+(1357-1300)=1978
ShamsiDiff=20993
'1921/03/21=80 (31+28+31)
'Leap Years 1921~1977
20993+80-57×365-14=254
Or

20,99336556×36514=174

174+80=254



1378/01/01
ShamsiDiff=28775(1300/01/01~1378/01/0)
1921+(1378-1300)=1999
'Leap Years 1921~1998=19
28775+80-78×365-19=366
سال 1999 کبیسه نیست و 365 روز دارد پس 366 اُمین روز میشود 2000/01/01

مبحث شیرینی بود پس در تبدیل ها ما 1300/01/01 را برای شمسی و معادلش 1921/03/21 را مبنا قرار دادیم و برای تبدیل شمسی به میلادی از تابعی استفاده شود که طبق معادلات قبل تر اختلاف دقیق تاریخ شمسی مد نظر با مبنا را بگیرد و در معادله بالا قرار داده شود.



بررسی تابع Weekday در اکسس

In MS Access, The weekday() function returns the weekday number for a given date
این تابع شماره روز هفته تاریخی را بر می گرداند که از یک یعنی یکشنبه شروع میشود و به 7 یعنی شنبه ختم میشود .در نتیجه شماره 6 میشود روز جمعه برای تاریخ میلادی مناسب است .

برای اینکه بدانیم تاریخ شمسی بدست آمده چه روزی است کافیست یک شماره به روز مبنا بدهیم ( در اینجا تاریخ میلادی مبنا روز دوشنبه 21 مارس 1921 قرار گرفت )  در تابع WeekDay که رفرنس است عدد دوشنبه 2 می باشد پس هر عددی که بدست آوردیم را باضافه این عدد می کنیم و تابعی می نویسیم که روز هفته را به فارسی بر گرداند . در تابع WeekDay عدد یکشنبه 1 است میتوان با همان تابع عدد را در متغیری ذخیره کرد .
DaysNo=Weekday(#1921/03/21#)=2
'SELECT Weekday(#1921/03/21#)

WeekDay(#1921/03/21#)=2 ' دوشنبه

جمع این عدد با  مانده تقسیم اختلاف روزها بر 7 

DaysDiff=20993 '1921/03/21~1978/09/11
2+20993 Mod 7=2+0=2 ' دوشنبه
DaysDiff=22766 '1921/03/21~1983/07/20
2+22766 Mod 7=2+2=4 ' چهارشنبه
DaysDiff=33524 '1921/03/21~2013/01/01
2+33524 Mod 7=2+1=3 ' سه شنبه
DaysDiff=31309 '1921/03/21~2006/12/09
2+31309 Mod 7=2+5=7 ' شنبه

Var1=2+DaysDiff Mod 7
Choose(Var1,"Yek","Do","3eh","4ar","5anj","jom","Shan")

از تابع Choose نیز می توان استفاده نمود :  index از یک شروع می شود.






برای بدست آوردن سن به سال ، ماه و روز می توان اختلاف تاریخ سن و تاریخ جاری  را بدست آورد و تقسیم بر 365.24 کرد و مانده را نیز تقسیم بر 30.437 نمود.

1334/03/28~1400/10/18
ShamsiDiff=24312
'jalali leap years 16
24312÷365.24=66.56  'int(66.56)=66 ' سال
24312-365.24×66=206.16
206.16÷30.437=6.64 'int(6.64)=6 ' ماه
206.16-6×30.437=23.538 'int(23.538)=23 ' روز
البته محاسبه با این روش نیز اختلاف یک یا دو روز مشهود است 

محاسبه تصویر بالا برای مشخص کردن سن بدین شکل است : 
(ShamsiDiff-jalaliLeapYears)÷365=ExtractYear
(ShamsiDiff-jalaliLeapYears)-365×int(ExtractYear)=Remain
سال مشخص شد منظور ExtractYear است . و ملاک محاسبه ماه و روز ،  ماه تولد است  یعنی اگر ماه تولد 4 باشد ماه 4 و 5 ، 31 روزه محاسبه میشود و 6 و ... ، 30 روزه . یا اگر متولد برج 7 باشید ببعد 30 روزه کم میشود می بینید باز هم احتیاج به ساخت تابع جدیدی است.یا اگر متولد فروردین باشید 1 تا 6 ، 31 روزه در نظر  گرفته خواهد شد.




اختلاف روزهای شمسی و میلادی :


1921/03/21:

1,920×365+(31+28+21)+480:1920÷4=701360

1300/01/01

1299×365+1+324:1299÷4=474460

701,360474,460=226900




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

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



 








ایسنا نوشت:بر اساس گزارشی، یک سری ایمیل‌های افشا شده نشان می‌دهد چندین دانشمند آمریکایی و انگلیسی بر این باور بوده‌اند که ویروس کرونا به صورت تصادفی از یک آزمایشگاه ووهان به بیرون نشت کرده اما این نگرانی را داشتند که بحث بیشتر بر سر این مساله، به مبحث علم در چین آسیب وارد کند.



قبیله موسو در چین

این قبیله که موسو نام دارد یکی از نادرترین وعجیب‌ترین قبیله‌ها در جهان است که در آن زن و شوهر با هم زندگی نمی‌کنند بلکه پیش پدر یا مادر خود می‌مانند. در قبیله‌ای به‌نام موسو، مادربزرگ خانواده در واقع رهبر خانواده است و نام‌های خانوادگی و هویت اجتماعی فرد از طریق مادر و اجداد او معنی می‌یابد.

چند شوهری

این قبیله در دامنه‌های هیمالیا وجود دارد و توسط زنان اداره می‌شود و مردان آن به کلی به حاشیه رانده شده‌اند. در واقع نظام کمونیستی نتوانست تنوع فرهنگی این مردم را بر طبق اهداف کمونیستی، یکسان ساز کند. در این قبیله بسیاری از کارهای مهم توسط زنان انجام می‌شود اما شکار و ماهیگیری را همچنان مردان انجام می‌دهند.

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


خانه بهروز وثوقی :



امام جمعه رفسنجان عنوان کرد: جمعیت عظیمی از شهدای بسیج داریم که به‌دلیل غیرت دینی خود در صحنه به شهادت رسیدند. دشمنان دنبال این هستند که غیرت دینی را در جامعه کمرنگ کنند، اگر به جایگاه رهبری و ولایت فقیه توهین شود، برای کمرنگ‌کردن غیرت دینی است. اگر مسأله بدحجابی یا بی‌حجابی را در جامعه ترویج می‌کنند یا یک خانم را از سر بی‌دینی و نفهمی تشویق می‌کنند که دوچرخه‌سواری کند، با اینکه دوچرخه‌سواری بانوان در انظار عموم حرام است، دنبال خدشه‌دار کردن غیرت دینی مردم هستند.

وی ادامه داد: اگر افسار سگ را به دست دختر و پسر ما در کوچه و خیابان دادند برای خدشه‌دارکردن غیرت دینی است و اگر به مسائل مذهبی، نماز و روزه ما حمله کردند دیدند که غیرت دینی جامعه را از بحران‌ها نجات می‌دهد که باید خیلی به هوش باشیم و از سر این قضایا به‌سادگی نگذریم و بگوییم دختر جوان دوست دارد دورچرخه‌سواری کند! خیر، باید هوشیار باشیم و نگذاریم چنین کاری در جامعه گسترش پیدا کند.



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


لطفا نظر سنجی فراموش نشود



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