بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

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

مدیریت گفتگو
احسان 10 سال پیش
آخرین تغییر: 8 سال پیش

با سلام ، پروژه خبرخوان استاد تاریخ رو به میلادی نشون میده ، حالا چجور باید این تاریخ رو به شمسی نمایش بدیم ؟

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

 

 

نظرات

پاسخ‌ها 2

سهرابیان 10 سال پیش

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

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  : لینک  

نظرات

سهرابیان 10 سال پیش
سلام . دوستان توجه داشته باشند ، در الگوریتم بالا برای انجام برخی محاسبات سعی کردم که بیشتر از دستور Switch استفاده کنم . چرا ؟ به این دلیل که : همیشه این نکته را به یاد داشته باشید ، دستور Switch خیلی بهینه تر و سریعتر از سایر دستورات کنترلی عمل می کند .
سهرابیان 10 سال پیش
توجه داشته باشید که متد getDayOfWeek را نیز می توان با دستور Switch پیاده سازی کرد .
سهرابیان 10 سال پیش
توجه داشته باشید که متد getDayOfWeek را نیز می توان با دستور Switch پیاده سازی کرد .
احسان 10 سال پیش
ممنون میشم کلاس یا پروژه کامل سمپل با کدهاتون رو بزارید چون وقتی میخوام پیاده سازی کنم(اندروید استودیو) به مشکل بر میخورم
سهرابیان 10 سال پیش
سلام . استفاده از کد بالا کاری نداشت ولی به هر حال لینک دانلود sourceCode آن را قرار دادم .
Mir Unknown 8 سال پیش
چطوری تاریخ دستی برای تبدیل بدیم؟
حسینی 8 سال پیش
سلام آقای patriot دم شما گرم خیلی مفید بود . جناب Mir Unknown شما می تونید به جای سه متغیر اولیه که از دستگاه گرفته میشه ( year_gregorian و ...) مقادیر دلخواه خودتون رو بذارید و نتیجه بگیرید.
Mir Unknown 8 سال پیش

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

نظرات


پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .