تبدیل تاریخ میلادی به شمسی در پروژه خبرخوان استاد
با سلام ، پروژه خبرخوان استاد تاریخ رو به میلادی نشون میده ، حالا چجور باید این تاریخ رو به شمسی نمایش بدیم ؟
جستجوهای زیادی کردم و به نتیجه نرسیدم
الگوریتم تبدیل تاریخ میلادی به تاریخ شمسی :
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 : لینک
میتونید از این اسنیپ برای تبدیل تاریخ شمسی به میلادی و میلادی به شمسی استفاده کنید اسنیپ تبدیل تاریخ
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .