تبدیل تاریخ میلادی به شمسی در پروژه خبرخوان استاد
با سلام ، پروژه خبرخوان استاد تاریخ رو به میلادی نشون میده ، حالا چجور باید این تاریخ رو به شمسی نمایش بدیم ؟
جستجوهای زیادی کردم و به نتیجه نرسیدم
الگوریتم تبدیل تاریخ میلادی به تاریخ شمسی :
1- برای نوشتن الگوریتم به اختلاف روز های میان اولین روز سال میلادی ( 1 ژانویه ) و اولین روز سال شمسی ( 20 مارس ) نیاز داریم که برابر با "79" می باشد .
2- در این مرحله باید تشخیص دهیم که سال میلادی کبیسه است یا خیر . برای اینکار باید سال میلادی داده شده را بر 4 تقسیم کنیم ، اگر بخشپذیر بود ( باقیمانده برابر صفر ) سال کبیسه است در غیر اینصورت سال میلادی کبیسه نیست .
3- با توجه به کبیسه بودن یا کبیسه نبودن سال مشخص می کنیم که در کدامین روز سال میلادی قرار داریم ، که در اینصورت با دو حالت روبرو خواهیم شد :
1-3- سال کبیسه باشد :
1-1-3- روزی که در آن قرار داریم از 79 بیشتر باشد :
به این معنی است که در ماههای بعد از فروردین قرار داریم . حال باید مشخص کنیم که در 6 ماه اول سال شمسی قرار داریم یا در 6 ماه دوم سال قرار داریم . برای اینکار ابتدا " 79 " روز از تعداد روز ها کم می کنیم تا در اول فروردین ماه قرار بگیریم . اگر تعداد روز های بدست آمده از " 186 " ( 31 * 6 ) کمتر باشد یعنی در 6 ماه اول سال شمسی قرار داریم ، در غیر اینصورت در 6 ماه دوم قرار داریم .
1-1-1-3- اگر در 6 ماه اول سال قرار گرفته باشیم ( dates <= 186 ) :
تعداد روزها را بر " 31 " تقسیم می کنیم ( چرا بر 31 تقسیم کنیم ؟ به این دلیل که در 6 ماه اول سال شمسی قرار داریم . ) ، اگر باقیمانده این تقسیم صفر شد ، خارج قسمت تقسیم برابر با ماه شمسی می شود و روز شمسی برابر با 31 می شود . در غیر اینصورت اگر باقیمانده صفر نشود ماه شمسی برابر با خارج قسمت به اضافه ی یک می شود و روز شمسی همان باقیمانده است .
2-1-1-3- اگر در 6 ماه دوم سال قرار گرفته باشیم :
" 186 " روز از تعداد روز ها کم می کنیم و آن را بر " 30 " تقسیم می کنیم ( چرا بر 30 تقسیم می کنیم ؟ چون در 6 ماه دوم سال قرار گرفته ایم و ماه ها 30 روزه می باشند . ) . اگر باقیمانده این تقسیم صفر شد ، خارج قسمت تقسیم به اضافه " 6 " و برابر ماه شمسی قرار خواهد گرفت و روز شمسی برابر با 30 می شود . اگر باقیمانده صفر نشود ماه شمسی برابر با خارج قسمت به اضافه " 7 " می شود و روز شمسی همان باقیمانده است و در نهایت سال شمسی از تفاضل سال میلادی با " 621 " بدست می آید .
چرا برای بدست آوردن سال شمسی ، سال میلادی را از 621 کم کردیم ؟ همان طور که در بالا ( 3-1-1 ) ذکر کردیم ، یعنی روز مورد نظر بین اول فروردین تا 11 دی می باشد .
2-1-3- روزی که در آن قرار داریم کمتر از " 79 " است :
به این معنی است که در روزهای بین اولین روز سال میلادی تا اولین روز سال شمسی ( دی ، بهمن ، اسفند ) قرار داریم . اختلاف روز بین اولین روز سال میلادی داده شده و اولین روز دی ماه در سال شمسی را در نظر می گیریم که این اختلاف برای سال کبیسه " 11 " و برای سال غیر کبیسه " 10 " می باشد .
تــوجــه : در این الگوریتم برای مشخص کردن این اختلاف باید سال قبل از سال داده شده را در نظر بگیریم ، به این دلیل که سال قبل بر روی اولین روز سال میلادی تاثیر می گزارد .
در نهایت اختلاف تاریخ بدست آمده را با تعداد روز ها جمع می کنیم و آن را بر " 30 " تقسیم می کنیم ( 3 ماه آخر سال شمسی 30 روزه است . ) ، اگر باقیمانده این تقسیم صفر شود ، خارج قسمت تقسیم به اضافه ی " 9 " برابر با ماه برابر با خارج قسمت به اضافه " 10 " می شود و روز شمسی همان باقیمانده است . در این حالت سال شمسی از تفاضل سال میلادی با " 622 " بدست می آید . ( چون بین 11 دی تا آخر اسفند قرار داریم . )
2-3- سال کبیسه نباشد :
دقیقا به مانند الگوریتم سال کبیسه عمل می کنیم ، البته با کمی تفاوت که با مطالعه ی sourceCode متوجه آن خواهید شد .
راهنما :
1- بهتر است برای هر دو سال های میلادی کبیسه و غیر کبیسه یک آرایه ی جداگانه در نظر گرفته شود .
2- برای مقدار دهی به آرایه های سال کبیسه و غیر کبیسه ، در این الگوریتم باید با توجه به جدول زیر عمل کنیم :
Length in days | Name | No. |
31 | January | 1 |
28 or 29 leap year | February | 2 |
31 | March | 3 |
30 | April | 4 |
31 | May | 5 |
30 | June | 6 |
31 | July | 7 |
31 | August | 8 |
30 | September | 9 |
31 | October | 10 |
30 | November | 11 |
31 | December | 12 |
به طور مثال ) می خواهیم آرایه ای از سال غیر کبیسه ( not_leap_year ) را با توجه به جدول بالا مقدار دهی کنیم :
مقدار دهی آرایه به این شکل است که : عنصر قبل + عنصر بعد ، با این شرط که اولین عنصر از آرایه مقدار صفر (0) را دارد .
not_leap_year =[0,January+0,(January+0)+28,....]
not_leap_year =[0,0+31,31+28,59+31,90+30,120+31,151+30,181+31,212+31, 243+30,273+31,304+30]
نـکتـه 1 : برای not_leap_year ( سال غیر کبیسه ای ) عدد 28 را در نظر می گیریم . برای is_leap_year (سال کبیسه ای ) عدد 29 را در نظر می گیریم .
نـکتـه 2 : باید دقت داشته باشید که طول آرایه از عدد 12 تجاوز نکند ، چون هر سال 12 ماه دارد .
کد آن به شرح زیر می باشد :
// calculate Solar Date from Gregorian Date public static void SolarCalendar() { String strMonth = ""; int day, month, year, difference_between_days; // Get Current Date Of your Device / Get Total Date Of your Divice Calendar gregorianDate = new GregorianCalendar(); int year_gregorian = gregorianDate.get(Calendar.YEAR); int month_gregorian = gregorianDate.get(Calendar.MONTH) + 1; int day_gregorian = gregorianDate.get(Calendar.DATE); // Day of Month int weekDay = gregorianDate.get(Calendar.DAY_OF_WEEK); int[] not_leap_year = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int[] is_leap_year = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; if ((year_gregorian % 4) != 0) { day = not_leap_year[month_gregorian - 1] + day_gregorian; if (day > 79) { day = day - 79; if (day <= 186) { switch (day % 31) { case 0: month = day / 31; day = 31; break; default: month = (day / 31) + 1; day = (day % 31); break; } year = year_gregorian - 621; } else { day = day - 186; switch (day % 30) { case 0: month = (day / 30) + 6; day = 30; break; default: month = (day / 30) + 7; day = (day % 30); break; } year = year_gregorian - 621; } } else { if ((year_gregorian > 1996) && (year_gregorian % 4) == 1) { difference_between_days = 11; } else { difference_between_days = 10; } day = day + difference_between_days; switch (day % 30) { case 0: month = (day / 30) + 9; day = 30; break; default: month = (day / 30) + 10; day = (day % 30); break; } year = year_gregorian - 622; } } else { day = is_leap_year[month_gregorian - 1] + day_gregorian; if (year_gregorian >= 1996) { difference_between_days = 79; } else { difference_between_days = 80; } if (day > difference_between_days) { day = day - difference_between_days; if (day <= 186) { switch (day % 31) { case 0: month = (day / 31); day = 31; break; default: month = (day / 31) + 1; day = (day % 31); break; } year = year_gregorian - 621; } else { day = day - 186; switch (day % 30) { case 0: month = (day / 30) + 6; day = 30; break; default: month = (day / 30) + 7; day = (day % 30); break; } year = year_gregorian - 621; } } else { day = day + 10; switch (day % 30) { case 0: month = (day / 30) + 9; day = 30; break; default: month = (day / 30) + 10; day = (day % 30); break; } year = year_gregorian - 622; } } switch (month) { case 1: strMonth = "فروردين"; break; case 2: strMonth = "ارديبهشت"; break; case 3: strMonth = "خرداد"; break; case 4: strMonth = "تير"; break; case 5: strMonth = "مرداد"; break; case 6: strMonth = "شهريور"; break; case 7: strMonth = "مهر"; break; case 8: strMonth = "آبان"; break; case 9: strMonth = "آذر"; break; case 10: strMonth = "دي"; break; case 11: strMonth = "بهمن"; break; case 12: strMonth = "اسفند"; break; }
Log.i("Test" , "Month is : " + strMonth );
// call the getCurrentSolarDate Method getCurrentSolarDate(year, month, day); // cal the getDayOfWeek Method getDayOfWeek(weekDay); } // Get Current Solar Date public static void getCurrentSolarDate(int year, int month, int day) { Locale locale = new Locale("en_US"); Log.i("Test", "Date is : " + String.valueOf(year) + "/" + String.format(locale, "%02d", month) + "/" + String.format(locale, "%02d", day)); } // Get Current DayOfWeek public static void getDayOfWeek(int weekDay) { String[] weekOfDay_Solar = {" شنبه ", " یکشنبه " , " دو شنبه ", " سه شنبه ", " چهار شنبه ", " پنج شنبه ", "جمعه"}; for (int i = 0; i < weekOfDay_Solar.length; i++) { if (weekDay == i) { Log.i("Test", " Day is : " + weekOfDay_Solar[i]); } } }
فراخوانی Method نوشته شده :
import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Locale; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Call The SolarCalendar Method SolarCalendar(); }
/* output is :
Month is : آبان
Date is : 1395/08/17
Day is : دوشنبه
*/
لینک دانلود SourceCode : لینک
میتونید از این اسنیپ برای تبدیل تاریخ شمسی به میلادی و میلادی به شمسی استفاده کنید اسنیپ تبدیل تاریخ
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .