Nicht alle Jahre, die ein Vielfaches von 4 sind, sind Schaltjahre. Ausnahmen sind Vielfache von 100, aber kein Vielfaches von 400. siehe: Wikipedia
Ohne Titel
Mit welchem Datum haben Sie ein Problem?
Bobs
Ich verwende diesen Algorithmus seit 6 Jahren in meinen Anwendungen.
Bobs
26
Sie sollten es für 100 Jahre verwenden, um das Problem zu sehen :)
Ohne Titel
11
Vielleicht könnten Sie den ersten Satz Ihrer Antwort so bearbeiten, dass dort steht "... es ist zwischen 1901 und 2099 sehr genau". Dies kann für viele Anwendungen ausreichend sein. Einige Entwickler sind jedoch möglicherweise an Daten außerhalb dieses Bereichs interessiert, und es wäre schön, sie zu warnen, dass dieser Algorithmus nicht gut genug ist.
Dawood ibn Kareem
31
Ich denke, diese Java-Klasse ist einfacher zu bedienen und zuverlässiger. Ich fand es im iranischen Forum , Iraner benutzen den Jalali-Kalender und nennen ihn "Shamsi", was Solarkalender bedeutet. Dies ist die Java-Klasse:
packageMyUtil;import java.util.Calendar;import java.util.GregorianCalendar;/**
* Title: Calender Conversion class
* Description: Convert Iranian (Jalali), Julian, and Gregorian dates to
* each other
* Public Methods Summary:
* -----------------------
* JavaSource_Calendar();
* JavaSource_Calendar(int year, int month, int day);
* int getIranianYear();
* int getIranianMonth();
* int getIranianDay();
* int getGregorianYear();
* int getGregorianMonth();
* int getGregorianDay();
* int getJulianYear();
* int getJulianMonth();
* int getJulianDay();
* String getIranianDate();
* String getGregorianDate();
* String getJulianDate();
* String getWeekDayStr();
* String toString();
* int getDayOfWeek();
* void nextDay();
* void nextDay(int days);
* void previousDay();
* void previousDay(int days);
* void setIranianDate(int year, int month, int day);
* void setGregorianDate(int year, int month, int day);
* void setJulianDate(int year, int month, int day);
*/publicclassCalendarTool{/**
* JavaSource_Calendar:
* The default constructor uses the current Gregorian date to initialize the
* other private memebers of the class (Iranian and Julian dates).
*/publicCalendarTool(){Calendar calendar =newGregorianCalendar();
setGregorianDate(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH)+1,
calendar.get(Calendar.DAY_OF_MONTH));}/**
* JavaSource_Calendar:
* This constructor receives a Gregorian date and initializes the other private
* members of the class accordingly.
* @param year int
* @param month int
* @param day int
*/publicCalendarTool(int year,int month,int day){
setGregorianDate(year,month,day);}/**
* getIranianYear:
* Returns the 'year' part of the Iranian date.
* @return int
*/publicint getIranianYear(){return irYear;}/**
* getIranianMonth:
* Returns the 'month' part of the Iranian date.
* @return int
*/publicint getIranianMonth(){return irMonth;}/**
* getIranianDay:
* Returns the 'day' part of the Iranian date.
* @return int
*/publicint getIranianDay(){return irDay;}/**
* getGregorianYear:
* Returns the 'year' part of the Gregorian date.
* @return int
*/publicint getGregorianYear(){return gYear;}/**
* getGregorianMonth:
* Returns the 'month' part of the Gregorian date.
* @return int
*/publicint getGregorianMonth(){return gMonth;}/**
* getGregorianDay:
* Returns the 'day' part of the Gregorian date.
* @return int
*/publicint getGregorianDay(){return gDay;}/**
* getJulianYear:
* Returns the 'year' part of the Julian date.
* @return int
*/publicint getJulianYear(){return juYear;}/**
* getJulianMonth:
* Returns the 'month' part of the Julian date.
* @return int
*/publicint getJulianMonth(){return juMonth;}/**
* getJulianDay()
* Returns the 'day' part of the Julian date.
* @return int
*/publicint getJulianDay(){return juDay;}/**
* getIranianDate:
* Returns a string version of Iranian date
* @return String
*/publicString getIranianDate(){return(irYear+"/"+irMonth+"/"+irDay);}/**
* getGregorianDate:
* Returns a string version of Gregorian date
* @return String
*/publicString getGregorianDate(){return(gYear+"/"+gMonth+"/"+gDay);}/**
* getJulianDate:
* Returns a string version of Julian date
* @return String
*/publicString getJulianDate(){return(juYear+"/"+juMonth+"/"+juDay);}/**
* getWeekDayStr:
* Returns the week day name.
* @return String
*/publicString getWeekDayStr(){String weekDayStr[]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};return(weekDayStr[getDayOfWeek()]);}/**
* toString:
* Overrides the default toString() method to return all dates.
* @return String
*/publicString toString(){return(getWeekDayStr()+", Gregorian:["+getGregorianDate()+"], Julian:["+getJulianDate()+"], Iranian:["+getIranianDate()+"]");}/**
* getDayOfWeek:
* Returns the week day number. Monday=0..Sunday=6;
* @return int
*/publicint getDayOfWeek(){return(JDN %7);}/**
* nextDay:
* Go to next julian day number (JDN) and adjusts the other dates.
*/publicvoid nextDay(){
JDN++;JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* nextDay:
* Overload the nextDay() method to accept the number of days to go ahead and
* adjusts the other dates accordingly.
* @param days int
*/publicvoid nextDay(int days){
JDN+=days;JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* previousDay:
* Go to previous julian day number (JDN) and adjusts the otehr dates.
*/publicvoid previousDay(){
JDN--;JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* previousDay:
* Overload the previousDay() method to accept the number of days to go backward
* and adjusts the other dates accordingly.
* @param days int
*/publicvoid previousDay(int days){
JDN-=days;JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* setIranianDate:
* Sets the date according to the Iranian calendar and adjusts the other dates.
* @param year int
* @param month int
* @param day int
*/publicvoid setIranianDate(int year,int month,int day){
irYear =year;
irMonth = month;
irDay = day;
JDN =IranianDateToJDN();JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* setGregorianDate:
* Sets the date according to the Gregorian calendar and adjusts the other dates.
* @param year int
* @param month int
* @param day int
*/publicvoid setGregorianDate(int year,int month,int day){
gYear = year;
gMonth = month;
gDay = day;
JDN = gregorianDateToJDN(year,month,day);JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* setJulianDate:
* Sets the date according to the Julian calendar and adjusts the other dates.
* @param year int
* @param month int
* @param day int
*/publicvoid setJulianDate(int year,int month,int day){
juYear = year;
juMonth = month;
juDay = day;
JDN = julianDateToJDN(year,month,day);JDNToIranian();JDNToJulian();JDNToGregorian();}/**
* IranianCalendar:
* This method determines if the Iranian (Jalali) year is leap (366-day long)
* or is the common year (365 days), and finds the day in March (Gregorian
* Calendar)of the first day of the Iranian year ('irYear').Iranian year (irYear)
* ranges from (-61 to 3177).This method will set the following private data
* members as follows:
* leap: Number of years since the last leap year (0 to 4)
* Gy: Gregorian year of the begining of Iranian year
* march: The March day of Farvardin the 1st (first day of jaYear)
*/privatevoidIranianCalendar(){// Iranian years starting the 33-year ruleintBreaks[]={-61,9,38,199,426,686,756,818,1111,1181,1210,1635,2060,2097,2192,2262,2324,2394,2456,3178};int jm,N,leapJ,leapG,jp,j,jump;
gYear = irYear +621;
leapJ =-14;
jp =Breaks[0];// Find the limiting years for the Iranian year 'irYear'
j=1;do{
jm=Breaks[j];
jump = jm-jp;if(irYear >= jm){
leapJ +=(jump /33*8+(jump %33)/4);
jp = jm;}
j++;}while((j<20)&&(irYear >= jm));
N = irYear - jp;// Find the number of leap years from AD 621 to the begining of the current// Iranian year in the Iranian (Jalali) calendar
leapJ +=(N/33*8+((N %33)+3)/4);if(((jump %33)==4)&&((jump-N)==4))
leapJ++;// And the same in the Gregorian date of Farvardin the first
leapG = gYear/4-((gYear /100+1)*3/4)-150;
march =20+ leapJ - leapG;// Find how many years have passed since the last leap yearif((jump - N)<6)
N = N - jump +((jump +4)/33*33);
leap =(((N+1)%33)-1)%4;if(leap ==-1)
leap =4;}/**
* IsLeap:
* This method determines if the Iranian (Jalali) year is leap (366-day long)
* or is the common year (365 days), and finds the day in March (Gregorian
* Calendar)of the first day of the Iranian year ('irYear').Iranian year (irYear)
* ranges from (-61 to 3177).This method will set the following private data
* members as follows:
* leap: Number of years since the last leap year (0 to 4)
* Gy: Gregorian year of the begining of Iranian year
* march: The March day of Farvardin the 1st (first day of jaYear)
*/publicbooleanIsLeap(int irYear1){// Iranian years starting the 33-year ruleintBreaks[]={-61,9,38,199,426,686,756,818,1111,1181,1210,1635,2060,2097,2192,2262,2324,2394,2456,3178};int jm,N,leapJ,leapG,jp,j,jump;
gYear = irYear1 +621;
leapJ =-14;
jp =Breaks[0];// Find the limiting years for the Iranian year 'irYear'
j=1;do{
jm=Breaks[j];
jump = jm-jp;if(irYear1 >= jm){
leapJ +=(jump /33*8+(jump %33)/4);
jp = jm;}
j++;}while((j<20)&&(irYear1 >= jm));
N = irYear1 - jp;// Find the number of leap years from AD 621 to the begining of the current// Iranian year in the Iranian (Jalali) calendar
leapJ +=(N/33*8+((N %33)+3)/4);if(((jump %33)==4)&&((jump-N)==4))
leapJ++;// And the same in the Gregorian date of Farvardin the first
leapG = gYear/4-((gYear /100+1)*3/4)-150;
march =20+ leapJ - leapG;// Find how many years have passed since the last leap yearif((jump - N)<6)
N = N - jump +((jump +4)/33*33);
leap =(((N+1)%33)-1)%4;if(leap ==-1)
leap =4;if(leap==4|| leap==0)returntrue;elsereturnfalse;}/**
* IranianDateToJDN:
* Converts a date of the Iranian calendar to the Julian Day Number. It first
* invokes the 'IranianCalender' private method to convert the Iranian date to
* Gregorian date and then returns the Julian Day Number based on the Gregorian
* date. The Iranian date is obtained from 'irYear'(1-3100),'irMonth'(1-12) and
* 'irDay'(1-29/31).
* @return long (Julian Day Number)
*/privateintIranianDateToJDN(){IranianCalendar();return(gregorianDateToJDN(gYear,3,march)+(irMonth-1)*31- irMonth/7*(irMonth-7)+ irDay -1);}/**
* JDNToIranian:
* Converts the current value of 'JDN' Julian Day Number to a date in the
* Iranian calendar. The caller should make sure that the current value of
* 'JDN' is set correctly. This method first converts the JDN to Gregorian
* calendar and then to Iranian calendar.
*/privatevoidJDNToIranian(){JDNToGregorian();
irYear = gYear -621;IranianCalendar();// This invocation will update 'leap' and 'march'int JDN1F = gregorianDateToJDN(gYear,3,march);int k = JDN - JDN1F;if(k >=0){if(k <=185){
irMonth =1+ k/31;
irDay =(k %31)+1;return;}else
k -=186;}else{
irYear--;
k +=179;if(leap ==1)
k++;}
irMonth =7+ k/30;
irDay =(k %30)+1;}/**
* julianDateToJDN:
* Calculates the julian day number (JDN) from Julian calendar dates. This
* integer number corresponds to the noon of the date (i.e. 12 hours of
* Universal Time). This method was tested to be good (valid) since 1 March,
* -100100 (of both calendars) up to a few millions (10^6) years into the
* future. The algorithm is based on D.A.Hatcher, Q.Jl.R.Astron.Soc. 25(1984),
* 53-55 slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279.
* @param year int
* @param month int
* @param day int
* @return int
*/privateint julianDateToJDN(int year,int month,int day){return(year +(month -8)/6+100100)*1461/4+(153*((month+9)%12)+2)/5+ day -34840408;}/**
* JDNToJulian:
* Calculates Julian calendar dates from the julian day number (JDN) for the
* period since JDN=-34839655 (i.e. the year -100100 of both calendars) to
* some millions (10^6) years ahead of the present. The algorithm is based on
* D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M.
* Borkowski, Post.Astron. 25(1987), 275-279).
*/privatevoidJDNToJulian(){int j=4* JDN +139361631;int i=((j %1461)/4)*5+308;
juDay =(i %153)/5+1;
juMonth =((i/153)%12)+1;
juYear = j/1461-100100+(8-juMonth)/6;}/**
* gergorianDateToJDN:
* Calculates the julian day number (JDN) from Gregorian calendar dates. This
* integer number corresponds to the noon of the date (i.e. 12 hours of
* Universal Time). This method was tested to be good (valid) since 1 March,
* -100100 (of both calendars) up to a few millions (10^6) years into the
* future. The algorithm is based on D.A.Hatcher, Q.Jl.R.Astron.Soc. 25(1984),
* 53-55 slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279.
* @param year int
* @param month int
* @param day int
* @return int
*/privateint gregorianDateToJDN(int year,int month,int day){int jdn =(year +(month -8)/6+100100)*1461/4+(153*((month+9)%12)+2)/5+ day -34840408;
jdn = jdn -(year +100100+(month-8)/6)/100*3/4+752;return(jdn);}/**
* JDNToGregorian:
* Calculates Gregorian calendar dates from the julian day number (JDN) for
* the period since JDN=-34839655 (i.e. the year -100100 of both calendars) to
* some millions (10^6) years ahead of the present. The algorithm is based on
* D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M.
* Borkowski, Post.Astron. 25(1987), 275-279).
*/privatevoidJDNToGregorian(){int j=4* JDN +139361631;
j = j +(((((4* JDN +183187720)/146097)*3)/4)*4-3908);int i=((j %1461)/4)*5+308;
gDay =(i %153)/5+1;
gMonth =((i/153)%12)+1;
gYear = j/1461-100100+(8-gMonth)/6;}privateint irYear;// Year part of a Iranian dateprivateint irMonth;// Month part of a Iranian dateprivateint irDay;// Day part of a Iranian dateprivateint gYear;// Year part of a Gregorian dateprivateint gMonth;// Month part of a Gregorian dateprivateint gDay;// Day part of a Gregorian dateprivateint juYear;// Year part of a Julian dateprivateint juMonth;// Month part of a Julian dateprivateint juDay;// Day part of a Julian dateprivateint leap;// Number of years since the last leap year (0 to 4)privateint JDN;// Julian Day Numberprivateint march;// The march day of Farvardin the first (First day of jaYear)}// End of Class 'JavaSource_Calendar
Sie können den Gregorianischen Tag, den Monat und das Jahr einfach festlegen und dann die Methode "getIranianDate ()" aufrufen, um das Datum im Zeichenfolgenformat abzurufen, genau wie im folgenden Beispielcode:
Ich denke, es gibt einen Fehler! Wenn Sie das heutige Datum (das Datum, an dem ich diesen Kommentar veröffentliche) konvertieren, ist es '1396/01/20', aber es ist '1395/12/20'
Mohsen Abasi
Es gibt eine falsche Antwort.
Meysam Mohammadi
Sie können mir helfen, es zu bearbeiten und den Fehler zu beheben.
Reza Ameri
Der Code funktioniert sowohl für den 10. April 17 als auch für den 14. April 18
MMG
Ich denke, ein Problem ist, dass Tage von Monaten nicht begrenzt sind, zum Beispiel April ist 30 Tage, aber die Code-Antwort für den 31. April und es ist die gleiche wie vom 1. Mai
MMG
20
Verwenden Sie die internationalen Komponenten von IBM für Unicode ( icu4j ). Es ist Teil des Unicode-Konsortiums , äußerst zuverlässig und kann in jedem Java-Projekt (Java EE, Java SE, Android usw.) verwendet werden. Verwenden Sie es mit Gradle , Maven oder einfach durch Herunterladen des Glases.
import java.time.LocalDateTime;import java.time.ZonedDateTime;import java.util.Date;import com.ibm.icu.util.Calendar;publicclassDateTimeUtilsTest{publicstaticvoid main(String[] args){System.out.println("Java 7 and before:");Date date =newDate(1467262800000L);System.out.println("Converting Gregorian date to Persian:");Calendar persianCalendar =DateTimeUtils.fromDateToPersianCalendar(date);System.out.println(persianCalendar.get(Calendar.YEAR));System.out.println(persianCalendar.get(Calendar.MONTH));System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH));System.out.println(DateTimeUtils.fromDateToPersianString(persianCalendar.getTime()));System.out.println("\nAdding 1 month and 5 days:");
persianCalendar.add(Calendar.MONTH,1);// add a month
persianCalendar.add(Calendar.DAY_OF_MONTH,5);// add 5 daysSystem.out.println(persianCalendar.get(Calendar.YEAR));System.out.println(persianCalendar.get(Calendar.MONTH));System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH));System.out.println(DateTimeUtils.fromDateToPersianString(persianCalendar.getTime()));System.out.println("\nConverting Persian date to Gregorian:");Date gregorianDate =DateTimeUtils.fromPersianDateToDate(1395,3,10,9,30,0);System.out.println(gregorianDate);System.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate));// to Persian stringSystem.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate,"dd/MM/yy - H:mm:dd"));// to Persian string with custom formatSystem.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate,"dd/MM/yy - H:mm:dd",DateTimeUtils.PERSIAN_EN_LOCALE));// to Persian string with custom format and Latin charactersSystem.out.println("\n"+"Java 8 onward:");ZonedDateTime gregorianZonedDateTime =DateTimeUtils.fromPersianDateToZonedDateTime(1395,3,10,9,30,0);System.out.println(gregorianZonedDateTime);LocalDateTime gregorianLocalDateTime =DateTimeUtils.fromPersianDateToLocalDateTime(1395,3,10,9,30,0);System.out.println(gregorianLocalDateTime);}}
Ausgabe:
Java7 and before:ConvertingGregorian date to Persian:1395310۱۳۹۵تیر۱۰,پنجشنبهAdding1 month and 5 days:1395415۱۳۹۵مرداد۱۵,جمعهConvertingPersian date to Gregorian:ThuJun3009:30:00 IRDT 2016۱۳۹۵تیر۱۰,پنجشنبه۱۰/۰۴/۹۵-۹:۳۰:۱۰10/04/95-9:30:10Java8 onward:2016-06-30T09:30+04:30[Asia/Tehran]2016-06-30T09:30
Genauer:
Java 7 und früher:
Sie können alle Funktionen java.util.Calendarzusätzlich zu einigen anderen erwarten :
import com.ibm.icu.util.Calendar;import com.ibm.icu.util.ULocale;...ULocale locale =newULocale("fa_IR@calendar=persian");Calendar persianCalendar =Calendar.getInstance(locale);
persianCalendar.clear();
persianCalendar.set(1395,3,10);// Tir(4th month) 10th 1395 equivalent to June 30th 2016
java.util.Date gregorianDate = persianCalendar.getTime();System.out.println(gregorianDate);// Thu Jun 30 00:00:00 IDT 2016// Gregorian to Persian
java.util.Calendar gregorianCal = java.util.GregorianCalendar.getInstance();
gregorianCal.set(2016, java.util.Calendar.JUNE,30);
persianCalendar.setTime(gregorianCal.getTime());System.out.println(persianCalendar.get(Calendar.YEAR));// 1395System.out.println(persianCalendar.get(Calendar.MONTH));// 3System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH));// 10
WARNUNG : Beachten Sie, dass das Monatsfeld im Java-Kalender Null ist, sodass der calendar.set(1395, 3, 10)Kalender den 4. Monat von 1395 darstellt, nicht den 3.!
Wenn Sie Textausgaben in Persisch benötigen:
import com.ibm.icu.text.DateFormat;import com.ibm.icu.text.SimpleDateFormat;...// full date output in persianDateFormat df =DateFormat.getDateInstance(DateFormat.FULL, locale);System.out.println(df.format(persianCalendar.getTime()));// year output in persianSimpleDateFormat sdf1 =newSimpleDateFormat(SimpleDateFormat.YEAR, locale);System.out.println(sdf1.format(persianCalendar.getTime()));// month name output in persianSimpleDateFormat sdf2 =newSimpleDateFormat(SimpleDateFormat.MONTH, locale);System.out.println(sdf2.format(persianCalendar.getTime()));// weekday name output in persianSimpleDateFormat sdf3 =newSimpleDateFormat(SimpleDateFormat.WEEKDAY, locale);System.out.println(sdf3.format(persianCalendar.getTime()));// full date output in YY/MM/dd formSimpleDateFormat sdf4 =newSimpleDateFormat("YY/MM/dd", locale);System.out.println(sdf4.format(persianCalendar.getTime()));
Ausgabe:
ه.ش.۱۳۹۵تیر۱۰,پنجشنبه۱۳۹۵تیرپنجشنبه۹۵/۰۴/۱۰
Wenn Sie eine Ausgabe in Englisch benötigen, wechseln Sie new ULocale("fa_IR@calendar=persian")zu new ULocale("en@calendar=persian").
Ausgabe:
AP 1395Tir10,Thu1395TirThu95/04/10
Andere schöne Dinge:
// Get number of days in monthSystem.out.println(persianCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 31// Get first day of weekSystem.out.println(persianCalendar.getFirstDayOfWeek());// 7 (Saturday according to docs)// Add some amount of time
persianCalendar.add(Calendar.MONTH,2);System.out.println(persianCalendar.get(Calendar.YEAR));//1395System.out.println(persianCalendar.get(Calendar.MONTH));// 5System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH));// 10
Weitere Funktionen finden Sie unter icu4j-Demos , insbesondere:
Um java.timeKlassen wie ZonedDateTimeoder zu verwenden LocalDateTime, können Sie einfach diese Methoden verwenden, um ein persisches Datum in bevorzugte Klassen zu konvertieren:
Wenn Sie sich Sorgen über die JAR-Größe von icu4j machen, können Sie diese neu erstellen und einfach das Kalendermodul (2.176 KB) verwenden. Weitere Infos: ver. 57 oder früher , ver. 58 oder höher mit dem ICU Data Build Tool .
@deadManN Ich habe meine Antwort aktualisiert. Ich hoffe es ist hilfreich.
Omid
1
@deadManN Wenn Sie mit daysInMonth die maximale Anzahl von Tagen in einem bestimmten Monat meinen, können Sie das, wonach Sie suchen, durch Aufrufen erreichen getActualMaximum(Calendar.DAY_OF_MONTH). Ich habe meine Antwort aktualisiert, um zu zeigen, wie man sie benutzt.
Omid
1
Ich denke, der Fehler liegt bei Ihnen, weil ich getActualMaximum(Calendar.DAY_OF_MONTH)alle Monate des vorherigen, aktuellen und nächsten Jahres überprüft habe und das Ergebnis korrekt war. Ist Ihnen bekannt, dass der Monat in Java-Kalendern Null ist? Wenn Sie 5 in das Monatsfeld eingeben, bedeutet dies tatsächlich, dass der 6. Monat nicht der 5. ist! Gleiches gilt für 11 (12. Monat). Wenn dies nicht der Fall ist, können Sie bitte genaue Daten angeben, die zu falschem Verhalten führen?
Omid
1
Soweit ich weiß, ist das einzige "Unkonventionelle", dass Monate auf Null basieren, nichts weiter zu befürchten. (Eigentlich ist es nicht unkonventionell, weil der Monat in gewisser Weise eine Aufzählung ist!)
Omid
1
Die beste Antwort! Weil Sie darauf hingewiesen haben: "Es ist Teil des Unicode-Konsortiums, äußerst zuverlässig und kann in jedem Java-Projekt verwendet werden." Beachten Sieandroid.icu auch, dass Android ab Android 7.0 (API-Stufe 24) eine Teilmenge der ICU4J-APIs verfügbar macht, die App-Entwickler unter dem Paket verwenden können . Details finden Sie hier .
Mir-Ismaili
11
Diese Methode ist sehr genau und unterstützt einfach auch Schaltjahre
Erklären:
Schritt 1: Die heutige Zeit enthält die aktuelle Zeit
Schritt 2: Erstellen Sie zwei Arrays für Gregorian und Jalali Tag in Monaten (g_days_in_month & j_days_in_month)
Schritt 3: Erstellen Sie eine Variable für die Aufbewahrungsdifferenzzeit zwischen Kalendern (gy, gm, gd) und der Variablen g_day_no für Tage von Jahren.
Schritt 4: Tag des Monats einfügen und mit Tagen sammeln.
Schritt 5: Konvertieren Sie Tage von Jahren in Jalili-Jahre (jy)
am Ende: Jalali-Monat ab Tagesnummer einstellen, Jalali-Tag ab Jalali-Tag des Monats einstellen.
Sie sollten versuchen, Ihre Antwort zu erklären, anstatt nur einen Codeblock zu veröffentlichen.
RyPeck
10
Die neueste Version v3.10-2015g meiner Bibliothek Time4A (eine Android-Anpassung von Time4J) enthält Unterstützung für den Jalali-Kalender. Die Bibliothek verwendet den Algorithmus von Borkowski (gültig bis zum gregorianischen Jahr 2129). Tatsächlich werden ungefähr 25 Sprachen für persische Monate und Epochen unterstützt (einschließlich Farsi und Pashto, basierend auf CLDR-28).
Anwendungsbeispiele:
// current datePersianCalendar jalali =SystemClock.inLocalView().now(PersianCalendar.axis());System.out.println(jalali);// AP-1394-08-04// tomorrow
jalali = jalali.plus(CalendarDays.ONE);System.out.println(jalali);// AP-1394-08-05// localized format of tomorrow (English and Farsi)ChronoFormatter<PersianCalendar> f =ChronoFormatter.ofStyle(DisplayMode.FULL,Locale.ENGLISH,PersianCalendar.axis());Locale farsi =newLocale("fa");System.out.println(f.format(jalali));// Tuesday, Aban 5, 1394 APSystem.out.println(f.with(farsi).format(jalali));// سهشنبه, آبان 5, 1394 ه.ش.// shift back to month Farvardin and format the result
jalali = jalali.with(PersianCalendar.MONTH_OF_YEAR,PersianMonth.FARVARDIN);System.out.println(f.format(jalali));// Wednesday, Farvardin 5, 1394 APSystem.out.println(f.with(farsi).format(jalali));// چهارشنبه, فروردین 5, 1394 ه.ش.// conversion to gregorian dateSystem.out.println(jalali);// AP-1394-01-05System.out.println(jalali.transform(PlainDate.class));// 2015-03-25// create new year in persian calendar and show gregorian counter part
jalali =PersianCalendar.of(1394,PersianMonth.FARVARDIN,1);System.out.println(jalali.transform(PlainDate.class));// 2015-03-21// create new year in gregorian calendar and show persian counter partPlainDate gregorianDate =PlainDate.of(2015,Month.JANUARY,1);System.out.println(gregorianDate.transform(PersianCalendar.class));// AP-1393-10-11// delta between gregorian new year and persian new yearSystem.out.println(CalendarDays.between(gregorianDate, jalali).getAmount());// 79
Interoperabilität mit java.util.Date unter Android
Da Time4A seine eigenen unveränderlichen Typen verwaltet und nicht auf dem primären zeitlichen Typ von Android basiert, zeige ich folgende Brücke:
+1 für die Verwendung der Borkowski- Methode für höchste Genauigkeit. Ich habe die persische Chronologie (n) für Joda Time geschrieben . Jalali basiert auf der Beobachtung der Frühlingsäquinoktienzeit auf einer Länge. Omar Khayyam (erweitert von Borkowski) hat eine schnelle Formel aus Äquinoktienvorhersagen für ~ 450 Jahre abgeleitet. Die Einschränkung; Khayyam verwendete Teheran Länge anstelle des IRST verwendet jetzt, so 1 oder 2 Schaltjahre können in den nächsten 3k aus sein. Meno, bitte fügen Sie auf der Projektseite ein Tutorial zum Hinzufügen eines Chronos zu Time4A hinzu.
Zubin Kavarana
@ZubinKavarana Danke für deinen Kommentar. Ich habe in der Tat ausdrücklich als JUnit-Test bestätigt, dass meine Anpassung von Borkowski für einen bestimmten Jahresbereich (~ 450 Jahre) genau mit Khayyam übereinstimmt. Über das Tutorial: Gute Idee, aber eine Frage: Was meinst du mit "Chrono hinzufügen"? Ich möchte mein vorhandenes Tutorial um eine Seite über die Verwendung verschiedener Kalender erweitern. Dort finden Sie auch einen Online-Javadoc .
Meno Hochschild
@ZubinKavarana Wenn Sie sagen möchten, wie Sie einen neuen Kalender hinzufügen, indem Sie "Chrono hinzufügen" sagen, kann ich dies tun, indem Sie dem oben genannten Tutorial eine zusätzliche Seite hinzufügen. Haben Sie Ideen, Vorschläge oder Pläne zum Hinzufügen eines weiteren Kalenders? Sie können auch ein Problem im time4j-github-issue-tracker öffnen, um diese Diskussion fortzusetzen.
Meno Hochschild
Ich habe gerade Ihr Beispiel implementiert und erhalte diese beiden Fehlerzeilen: bei net.time4j.base.ResourceLoader.getInstance (unbekannte Quelle), bei net.time4j.SystemClock. <Clinit> (unbekannte Quelle). Wie kann ich Fehler in der Bibliothek debuggen und die Ursache dafür finden?
Eftekhari
1
@Eftekhari Hast du deine App mit richtig initialisiert ApplicationStarter.initialize(this, ...);? Siehe auch Beispiel für eine Code-Initialisierung im Abschnitt Time4A - Verwendung. Ihr Stacktrace zeigt diese Ursache an.
Meno Hochschild
5
Versuche dies
import java.util.Calendar;import java.util.Date;publicclassPersianCalendar{String[] weekDayNames ={"شنبه","یکشنبه","دوشنبه","سه شنبه","چهارشنبه","پنج شنبه","جمعه"};String[] monthNames ={"فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"};String strWeekDay ="";String strMonth ="";int day;int month;int year;int ld;Calendar calendar =Calendar.getInstance();int gregorianYear =calendar.get(Calendar.YEAR);int gregorianMonth = calendar.get(Calendar.MONTH)+1;int gregorianDate = calendar.get(Calendar.DATE);intWeekDay= calendar.get(Calendar.DAY_OF_WEEK);int[] buf1 ={0,31,59,90,120,151,181,212,243,273,304,334};int[] buf2 ={0,31,60,91,121,152,182,213,244,274,305,335};publicPersianCalendar(){Date gregorianDate =newDate();
calendar.setTime(gregorianDate);
toPersian(gregorianDate);}publicPersianCalendar(Date gregorianDate){
calendar.setTime(gregorianDate);
toPersian(gregorianDate);}privatevoid toPersian(Date gregorianDate){if((gregorianYear %4)!=0)
func1();else
func2();
strMonth = monthNames[month-1];
strWeekDay = weekDayNames[WeekDay];}privatevoid func1(){
day = buf1[gregorianMonth -1]+ gregorianDate;if(day >79){
day = day -79;if(day <=186){int day2 = day;
month =(day2 /31)+1;
day =(day2 %31);if(day2 %31==0){
month--;
day =31;}
year = gregorianYear -621;}else{int day2 = day -186;
month =(day2 /30)+7;
day =(day2 %30);if(day2 %30==0){
month =(day2 /30)+6;
day =30;}
year = gregorianYear -621;}}else{
ld = gregorianYear >1996&& gregorianYear %4==1?11:10;int day2 = day + ld;
month =(day2 /30)+10;
day =(day2 %30);if(day2 %30==0){
month--;
day =30;}
year = gregorianYear -622;}}privatevoid func2(){
day = buf2[gregorianMonth -1]+ gregorianDate;
ld = gregorianYear >=1996?79:80;if(day > ld){
day = day - ld;if(day <=186){int day2 = day;
month =(day2 /31)+1;
day =(day2 %31);if(day2 %31==0){
month--;
day =31;}
year = gregorianYear -621;}else{int day2 = day -186;
month =(day2 /30)+7;
day =(day2 %30);if(day2 %30==0){
month--;
day =30;}
year = gregorianYear -621;}}else{int day2 = day +10;
month =(day2 /30)+10;
day =(day2 %30);if(day2 %30==0){
month--;
day =30;}
year = gregorianYear -622;}}}
Es gibt ein persianutils- Projekt, das einen bidirektionalen DateConverter enthält. Gregorianischer <-> Perser (Jalali). Es ist in Scala geschrieben, daher wäre die Verwendung in einem Java-Projekt recht einfach.
Der verwendete Algorithmus gilt für gregorianische Jahre bis ~ 3790 und persische Jahre bis ~ 3170.
HAFTUNGSAUSSCHLUSS: Ich bin der Autor von PersianUtils
Sie können diese stabile und getestete Bibliothek mit der Formatierungsklasse Roozh für Java verwenden . Es ist nicht veraltet und wird immer mit coolen Funktionen aktualisiert, die die persische Datums- und Uhrzeitangabe benötigt.
Antworten:
Ich benutze diesen Algorithmus seit Jahren und er ist zwischen 1901 und 2099 sehr genau.
Verwenden Sie es und genießen Sie! :) :)
quelle
Ich denke, diese Java-Klasse ist einfacher zu bedienen und zuverlässiger. Ich fand es im iranischen Forum , Iraner benutzen den Jalali-Kalender und nennen ihn "Shamsi", was Solarkalender bedeutet. Dies ist die Java-Klasse:
Sie können den Gregorianischen Tag, den Monat und das Jahr einfach festlegen und dann die Methode "getIranianDate ()" aufrufen, um das Datum im Zeichenfolgenformat abzurufen, genau wie im folgenden Beispielcode:
Ich hoffe, es hilft.
quelle
Verwenden Sie die internationalen Komponenten von IBM für Unicode ( icu4j ). Es ist Teil des Unicode-Konsortiums , äußerst zuverlässig und kann in jedem Java-Projekt (Java EE, Java SE, Android usw.) verwendet werden. Verwenden Sie es mit Gradle , Maven oder einfach durch Herunterladen des Glases.
TL; DR
Verwendung:
Ausgabe:
Genauer:
Java 7 und früher:
Sie können alle Funktionen
java.util.Calendar
zusätzlich zu einigen anderen erwarten :WARNUNG : Beachten Sie, dass das Monatsfeld im Java-Kalender Null ist, sodass der
calendar.set(1395, 3, 10)
Kalender den 4. Monat von 1395 darstellt, nicht den 3.!Wenn Sie Textausgaben in Persisch benötigen:
Ausgabe:
Wenn Sie eine Ausgabe in Englisch benötigen, wechseln Sie
new ULocale("fa_IR@calendar=persian")
zunew ULocale("en@calendar=persian")
.Ausgabe:
Andere schöne Dinge:
Weitere Funktionen finden Sie unter icu4j-Demos , insbesondere:
fa_IR
für Gebietsschema)Siehe auch Kalender- und PersianCalendar- API.
Ab Java 8:
Um
java.time
Klassen wieZonedDateTime
oder zu verwendenLocalDateTime
, können Sie einfach diese Methoden verwenden, um ein persisches Datum in bevorzugte Klassen zu konvertieren:Anmerkungen zur Glasgröße
Wenn Sie sich Sorgen über die JAR-Größe von icu4j machen, können Sie diese neu erstellen und einfach das Kalendermodul (2.176 KB) verwenden. Weitere Infos: ver. 57 oder früher , ver. 58 oder höher mit dem ICU Data Build Tool .
quelle
getActualMaximum(Calendar.DAY_OF_MONTH)
. Ich habe meine Antwort aktualisiert, um zu zeigen, wie man sie benutzt.getActualMaximum(Calendar.DAY_OF_MONTH)
alle Monate des vorherigen, aktuellen und nächsten Jahres überprüft habe und das Ergebnis korrekt war. Ist Ihnen bekannt, dass der Monat in Java-Kalendern Null ist? Wenn Sie 5 in das Monatsfeld eingeben, bedeutet dies tatsächlich, dass der 6. Monat nicht der 5. ist! Gleiches gilt für 11 (12. Monat). Wenn dies nicht der Fall ist, können Sie bitte genaue Daten angeben, die zu falschem Verhalten führen?android.icu
auch, dass Android ab Android 7.0 (API-Stufe 24) eine Teilmenge der ICU4J-APIs verfügbar macht, die App-Entwickler unter dem Paket verwenden können . Details finden Sie hier .Diese Methode ist sehr genau und unterstützt einfach auch Schaltjahre
Erklären:
Schritt 1: Die heutige Zeit enthält die aktuelle Zeit
Schritt 2: Erstellen Sie zwei Arrays für Gregorian und Jalali Tag in Monaten (g_days_in_month & j_days_in_month)
Schritt 3: Erstellen Sie eine Variable für die Aufbewahrungsdifferenzzeit zwischen Kalendern (gy, gm, gd) und der Variablen g_day_no für Tage von Jahren.
Schritt 4: Tag des Monats einfügen und mit Tagen sammeln.
Schritt 5: Konvertieren Sie Tage von Jahren in Jalili-Jahre (jy)
am Ende: Jalali-Monat ab Tagesnummer einstellen, Jalali-Tag ab Jalali-Tag des Monats einstellen.
Viel Glück.
quelle
Die neueste Version v3.10-2015g meiner Bibliothek Time4A (eine Android-Anpassung von Time4J) enthält Unterstützung für den Jalali-Kalender. Die Bibliothek verwendet den Algorithmus von Borkowski (gültig bis zum gregorianischen Jahr 2129). Tatsächlich werden ungefähr 25 Sprachen für persische Monate und Epochen unterstützt (einschließlich Farsi und Pashto, basierend auf CLDR-28).
Anwendungsbeispiele:
Interoperabilität mit java.util.Date unter Android
Da Time4A seine eigenen unveränderlichen Typen verwaltet und nicht auf dem primären zeitlichen Typ von Android basiert, zeige ich folgende Brücke:
quelle
ApplicationStarter.initialize(this, ...);
? Siehe auch Beispiel für eine Code-Initialisierung im Abschnitt Time4A - Verwendung. Ihr Stacktrace zeigt diese Ursache an.Versuche dies
Instanz erstellen
quelle
Es gibt ein persianutils- Projekt, das einen bidirektionalen DateConverter enthält. Gregorianischer <-> Perser (Jalali). Es ist in Scala geschrieben, daher wäre die Verwendung in einem Java-Projekt recht einfach.
Der verwendete Algorithmus gilt für gregorianische Jahre bis ~ 3790 und persische Jahre bis ~ 3170.
HAFTUNGSAUSSCHLUSS: Ich bin der Autor von PersianUtils
quelle
Sie können diese stabile und getestete Bibliothek mit der Formatierungsklasse Roozh für Java verwenden . Es ist nicht veraltet und wird immer mit coolen Funktionen aktualisiert, die die persische Datums- und Uhrzeitangabe benötigt.
quelle
Erstellen Sie das berechneJalaliDate als Funktion wie folgt; und geben Sie dann das Jalali-Datum in String zurück
quelle
Ich habe ein Android Shamsi Datepicker-Widget mit der Ereignisansicht hijri - gerogian - shamsi entwickelt: https://github.com/irshst/ir.shes.calendar
quelle
Neben Time4A, icu4j, die zu schwere Bibliotheken sind, habe ich eine Klasse geschrieben, um den persischen Kalender genau zu handhaben. Sie finden sie hier: https://github.com/hadilq/java-persian-calendar/blob/master/persian/src /main/java/ir/hadilq/PersianCalendar.java
Wie Sie in seinen Tests finden können, unterstützt diese Klasse vom Jahr 3000 vor der Hijra bis 3000 nach der Hijra.
quelle