java - ¿Hay alguna biblioteca o algoritmo para el calendario persa(Shamsi o Jalali) en Android?
algorithm persian (11)
Quiero convertir la fecha gregoriana (occidental) a la fecha persa (Shamsi) y viceversa para todas las versiones de Android.
¿Hay alguna biblioteca o algoritmo completo y confiable?
Cree el calculateJalaliDate como una función así; y luego devuelve la fecha de Jalali en String
public String calculateJalaliDate(){
Calendar c = Calendar.getInstance();
String jalaliDate,JalaliMonth;
int jalaliYear,jalaliMonth,calculateMonth,jalaliDay=0,allDays=0;
int day=c.get(Calendar.DAY_OF_MONTH);
int month=c.get(Calendar.MONTH)+1;
int year=c.get(Calendar.YEAR);
switch (month){
case 1: allDays=year*365+31+day;break;
case 2: allDays=year*365+(31+28)+day;break;
case 3: allDays=year*365+(31+28+31)+day;break;
case 4: allDays=year*365+(31+28+31+30)+day;break;
case 5: allDays=year*365+(31+28+31+30+31)+day;break;
case 6: allDays=year*365+(31+28+31+30+31+30)+day;break;
case 7: allDays=year*365+(31+28+31+30+31+30+31)+day;break;
case 8: allDays=year*365+(31+28+31+30+31+30+31+31)+day;break;
case 9: allDays=year*365+(31+28+31+30+31+30+31+31+30)+day;break;
case 10: allDays=year*365+(31+28+31+30+31+30+31+31+30+31)+day;break;
case 11: allDays=year*365+(31+28+31+30+31+30+31+31+30+31+30)+day;break;
case 12: allDays=year*365+(31+28+31+30+31+30+31+31+30+31+30+31)+day;break;
}
//226899
jalaliYear=( allDays - 227139 )/365+1;
calculateMonth=( allDays - 227139 )%365;
if(calculateMonth<32)jalaliMonth=1;
else if((calculateMonth-31)<32){jalaliMonth=2;jalaliDay=calculateMonth-31;}
else if((calculateMonth-62)<32){jalaliMonth=3;jalaliDay=calculateMonth-62;}
else if((calculateMonth-93)<32){jalaliMonth=4;jalaliDay=calculateMonth-93;}
else if((calculateMonth-124)<32){jalaliMonth=5;jalaliDay=calculateMonth-124;}
else if((calculateMonth-155)<32){jalaliMonth=6;jalaliDay=calculateMonth-155;}
else if((calculateMonth-186)<31){jalaliMonth=7;jalaliDay=calculateMonth-186;}
else if((calculateMonth-216)<31){jalaliMonth=8;jalaliDay=calculateMonth-216;}
else if((calculateMonth-246)<31){jalaliMonth=9;jalaliDay=calculateMonth-246;}
else if((calculateMonth-276)<31){jalaliMonth=10;jalaliDay=calculateMonth-276;}
else if((calculateMonth-306)<31){jalaliMonth=11;jalaliDay=calculateMonth-306;}
else {
jalaliMonth=12;
if((jalaliYear%4)==0)jalaliDay=calculateMonth-336;
else jalaliDay=calculateMonth-335;
}
/*switch (jalaliMonth){
case 1:JalaliMonth="فروردین"; break;
case 2:JalaliMonth="اردیبهشت"; break;
case 3:JalaliMonth="خرداد"; break;
case 4:JalaliMonth="تیر"; break;
case 5:JalaliMonth="مرداد"; break;
case 6:JalaliMonth="شهریور"; break;
case 7:JalaliMonth="مهر"; break;
case 8:JalaliMonth="آبان"; break;
case 9:JalaliMonth="آذر"; break;
case 10:JalaliMonth="دی"; break;
case 11:JalaliMonth="بهمن"; break;
case 12:JalaliMonth="اسفند"; break;
}*/
jalaliDate=String.valueOf(jalaliYear)+"/"+String.valueOf(jalaliMonth)+"/"+String.valueOf(jalaliDay);
return jalaliDate;
}
Creo que esta clase de Java es más fácil de usar y más confiable. Lo encontré en un foro iraní , los iraníes usan el calendario de Jalali y lo llaman "Shamsi", que significa calendario solar. esta es la clase de Java:
package MyUtil;
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);
*/
public class CalendarTool {
/**
* JavaSource_Calendar:
* The default constructor uses the current Gregorian date to initialize the
* other private memebers of the class (Iranian and Julian dates).
*/
public CalendarTool()
{
Calendar calendar = new GregorianCalendar();
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
*/
public CalendarTool(int year, int month, int day)
{
setGregorianDate(year,month,day);
}
/**
* getIranianYear:
* Returns the ''year'' part of the Iranian date.
* @return int
*/
public int getIranianYear() {
return irYear;
}
/**
* getIranianMonth:
* Returns the ''month'' part of the Iranian date.
* @return int
*/
public int getIranianMonth() {
return irMonth;
}
/**
* getIranianDay:
* Returns the ''day'' part of the Iranian date.
* @return int
*/
public int getIranianDay() {
return irDay;
}
/**
* getGregorianYear:
* Returns the ''year'' part of the Gregorian date.
* @return int
*/
public int getGregorianYear() {
return gYear;
}
/**
* getGregorianMonth:
* Returns the ''month'' part of the Gregorian date.
* @return int
*/
public int getGregorianMonth() {
return gMonth;
}
/**
* getGregorianDay:
* Returns the ''day'' part of the Gregorian date.
* @return int
*/
public int getGregorianDay() {
return gDay;
}
/**
* getJulianYear:
* Returns the ''year'' part of the Julian date.
* @return int
*/
public int getJulianYear() {
return juYear;
}
/**
* getJulianMonth:
* Returns the ''month'' part of the Julian date.
* @return int
*/
public int getJulianMonth() {
return juMonth;
}
/**
* getJulianDay()
* Returns the ''day'' part of the Julian date.
* @return int
*/
public int getJulianDay() {
return juDay;
}
/**
* getIranianDate:
* Returns a string version of Iranian date
* @return String
*/
public String getIranianDate()
{
return (irYear+"/"+irMonth+"/"+irDay);
}
/**
* getGregorianDate:
* Returns a string version of Gregorian date
* @return String
*/
public String getGregorianDate()
{
return (gYear+"/"+gMonth+"/"+gDay);
}
/**
* getJulianDate:
* Returns a string version of Julian date
* @return String
*/
public String getJulianDate()
{
return (juYear+"/"+juMonth+"/"+juDay);
}
/**
* getWeekDayStr:
* Returns the week day name.
* @return String
*/
public String 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
*/
public String toString()
{
return (getWeekDayStr()+
", Gregorian:["+getGregorianDate()+
"], Julian:["+getJulianDate()+
"], Iranian:["+getIranianDate()+"]");
}
/**
* getDayOfWeek:
* Returns the week day number. Monday=0..Sunday=6;
* @return int
*/
public int getDayOfWeek()
{
return (JDN % 7);
}
/**
* nextDay:
* Go to next julian day number (JDN) and adjusts the other dates.
*/
public void 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
*/
public void nextDay(int days)
{
JDN+=days;
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
/**
* previousDay:
* Go to previous julian day number (JDN) and adjusts the otehr dates.
*/
public void 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
*/
public void 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
*/
public void 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
*/
public void 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
*/
public void 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)
*/
private void IranianCalendar()
{
// Iranian years starting the 33-year rule
int Breaks[]=
{-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 year
if ( (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)
*/
public boolean IsLeap(int irYear1)
{
// Iranian years starting the 33-year rule
int Breaks[]=
{-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 year
if ( (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)
return true;
else
return false;
}
/**
* 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)
*/
private int IranianDateToJDN()
{
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.
*/
private void JDNToIranian()
{
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
*/
private int 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).
*/
private void JDNToJulian()
{
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
*/
private int 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).
*/
private void JDNToGregorian()
{
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;
}
private int irYear; // Year part of a Iranian date
private int irMonth; // Month part of a Iranian date
private int irDay; // Day part of a Iranian date
private int gYear; // Year part of a Gregorian date
private int gMonth; // Month part of a Gregorian date
private int gDay; // Day part of a Gregorian date
private int juYear; // Year part of a Julian date
private int juMonth; // Month part of a Julian date
private int juDay; // Day part of a Julian date
private int leap; // Number of years since the last leap year (0 to 4)
private int JDN; // Julian Day Number
private int march; // The march day of Farvardin the first (First day of jaYear)
} // End of Class ''JavaSource_Calendar
Puede establecer fácilmente el día, mes y año gregorianos y luego llamar al método "getIranianDate ()" para obtener la fecha en formato de cadena, al igual que el código de ejemplo siguiente:
MyUtil.CalendarTool ct = new CalendarTool(2012,10,10);
System.out.println(ct.getIranianDate());
Espero que ayude.
Estoy usando este algoritmo por años y es muy preciso.
Úselo y disfrute! :)
public class Utilities {
private class SolarCalendar {
public String strWeekDay = "";
public String strMonth = "";
int date;
int month;
int year;
public SolarCalendar()
{
Date MiladiDate = new Date();
calcSolarCalendar(MiladiDate);
}
public SolarCalendar(Date MiladiDate)
{
calcSolarCalendar(MiladiDate);
}
private void calcSolarCalendar(Date MiladiDate) {
int ld;
int miladiYear = MiladiDate.getYear() + 1900;
int miladiMonth = MiladiDate.getMonth() + 1;
int miladiDate = MiladiDate.getDate();
int WeekDay = MiladiDate.getDay();
int[] buf1 = new int[12];
int[] buf2 = new int[12];
buf1[0] = 0;
buf1[1] = 31;
buf1[2] = 59;
buf1[3] = 90;
buf1[4] = 120;
buf1[5] = 151;
buf1[6] = 181;
buf1[7] = 212;
buf1[8] = 243;
buf1[9] = 273;
buf1[10] = 304;
buf1[11] = 334;
buf2[0] = 0;
buf2[1] = 31;
buf2[2] = 60;
buf2[3] = 91;
buf2[4] = 121;
buf2[5] = 152;
buf2[6] = 182;
buf2[7] = 213;
buf2[8] = 244;
buf2[9] = 274;
buf2[10] = 305;
buf2[11] = 335;
if ((miladiYear % 4) != 0) {
date = buf1[miladiMonth - 1] + miladiDate;
if (date > 79) {
date = date - 79;
if (date <= 186) {
switch (date % 31) {
case 0:
month = date / 31;
date = 31;
break;
default:
month = (date / 31) + 1;
date = (date % 31);
break;
}
year = miladiYear - 621;
} else {
date = date - 186;
switch (date % 30) {
case 0:
month = (date / 30) + 6;
date = 30;
break;
default:
month = (date / 30) + 7;
date = (date % 30);
break;
}
year = miladiYear - 621;
}
} else {
if ((miladiYear > 1996) && (miladiYear % 4) == 1) {
ld = 11;
} else {
ld = 10;
}
date = date + ld;
switch (date % 30) {
case 0:
month = (date / 30) + 9;
date = 30;
break;
default:
month = (date / 30) + 10;
date = (date % 30);
break;
}
year = miladiYear - 622;
}
} else {
date = buf2[miladiMonth - 1] + miladiDate;
if (miladiYear >= 1996) {
ld = 79;
} else {
ld = 80;
}
if (date > ld) {
date = date - ld;
if (date <= 186) {
switch (date % 31) {
case 0:
month = (date / 31);
date = 31;
break;
default:
month = (date / 31) + 1;
date = (date % 31);
break;
}
year = miladiYear - 621;
} else {
date = date - 186;
switch (date % 30) {
case 0:
month = (date / 30) + 6;
date = 30;
break;
default:
month = (date / 30) + 7;
date = (date % 30);
break;
}
year = miladiYear - 621;
}
}
else {
date = date + 10;
switch (date % 30) {
case 0:
month = (date / 30) + 9;
date = 30;
break;
default:
month = (date / 30) + 10;
date = (date % 30);
break;
}
year = miladiYear - 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;
}
switch (WeekDay) {
case 0:
strWeekDay = "يکشنبه";
break;
case 1:
strWeekDay = "دوشنبه";
break;
case 2:
strWeekDay = "سه شنبه";
break;
case 3:
strWeekDay = "چهارشنبه";
break;
case 4:
strWeekDay = "پنج شنبه";
break;
case 5:
strWeekDay = "جمعه";
break;
case 6:
strWeekDay = "شنبه";
break;
}
}
}
public static String getCurrentShamsidate() {
Locale loc = new Locale("en_US");
Utilities util = new Utilities();
SolarCalendar sc = util.new SolarCalendar();
return String.valueOf(sc.year) + "/" + String.format(loc, "%02d",
sc.month) + "/" + String.format(loc, "%02d", sc.date);
}
}
Hay persianutils proyecto de persianutils que incluye un DateConverter bidireccional; Gregorian <-> Persian (Jalali). Está escrito en Scala, así que supongo que usarlo en un proyecto Java sería bastante fácil.
El algoritmo utilizado es válido para años gregorianos hasta ~ 3790 y años persas hasta ~ 3170.
DESCARGO DE RESPONSABILIDAD: Yo soy el autor de PersianUtils
La última versión v3.10-2015g de mi biblioteca Time4A (una adaptación de Android de Time4J) contiene soporte para el calendario de Jalali. La biblioteca implementa el algoritmo de Borkowski (válido hasta el año gregoriano 2129). En realidad, se admiten aproximadamente 25 idiomas para los meses y eras persas (incluidos el farsi y el pashto, según CLDR-28).
Ejemplos de uso:
// current date
PersianCalendar 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 = new Locale("fa");
System.out.println(f.format(jalali)); // Tuesday, Aban 5, 1394 AP
System.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 AP
System.out.println(f.with(farsi).format(jalali)); // چهارشنبه, فروردین 5, 1394 ه.ش.
// conversion to gregorian date
System.out.println(jalali); // AP-1394-01-05
System.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 part
PlainDate 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 year
System.out.println(CalendarDays.between(gregorianDate, jalali).getAmount()); // 79
Interoperabilidad con java.util.Date en Android
Como Time4A administra su propio conjunto de tipos inmutables y no se basa en el tipo temporal primario de Android, muestro el siguiente puente:
// Time4A => Android
PlainDate gdate = jalali.transform(PlainDate.class);
Moment m1 = gdate.atStartOfDay().inTimezone(ASIA.TEHRAN);
java.util.Date jud = TemporalType.JAVA_UTIL_DATE.from(m1);
// Android => Time4A
java.util.Date input = new java.util.Date();
Moment m2 = TemporalType.JAVA_UTIL_DATE.translate(input);
jalali = m2.toZonalTimestamp(ASIA.TEHRAN).toDate().transform(PersianCalendar.class);
Prueba esto
import java.util.Calendar;
import java.util.Date;
public class PersianCalendar {
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);
int WeekDay = 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};
public PersianCalendar(){
Date gregorianDate = new Date();
calendar.setTime(gregorianDate);
toPersian(gregorianDate);
}
public PersianCalendar(Date gregorianDate){
calendar.setTime(gregorianDate);
toPersian(gregorianDate);
}
private void toPersian(Date gregorianDate)
{
if ((gregorianYear % 4) != 0)
func1();
else
func2();
strMonth = monthNames[month-1];
strWeekDay = weekDayNames[WeekDay];
}
private void 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;
}
}
private void 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;
}
}
}
crear instancia
PersianCalendar sc = new PersianCalendar();
String s= sc.strWeekDay + " " +sc.day + " " +
sc.strMonth + " " + sc.year;
System.out.print(s);
//setTitle(s);
Puede usar esta biblioteca estable y probada con una clase de formateador, Roozh para Java . No está en desuso y siempre se actualiza con funciones geniales que necesita la hora persa.
Usar componentes internacionales para Unicode ( icu4j ). Es parte de Unicode Consortium , es extremadamente confiable y puede usarse en cualquier proyecto de Java (Java EE, Java SE, Android, etc.). Úselo con Gradle , Maven o simplemente downloading el jar.
Puedes esperar funcionalidades de java.util.Calendar
y algunas adicionales de él.
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
...
ULocale locale = new ULocale("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)); // 1395
System.out.println(persianCalendar.get(Calendar.MONTH)); // 3
System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH)); // 10
ADVERTENCIA : Tenga en cuenta que el campo del mes está basado en cero en el calendario de Java, por lo que el calendar.set(1395, 3, 10)
calendario representará el 4º mes de 1395, no el 3er!
Si necesita salidas de texto en persa:
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
...
// full date output in persian
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, locale);
System.out.println(df.format(persianCalendar.getTime()));
// year output in persian
SimpleDateFormat sdf1 = new SimpleDateFormat(SimpleDateFormat.YEAR, locale);
System.out.println(sdf1.format(persianCalendar.getTime()));
// month name output in persian
SimpleDateFormat sdf2 = new SimpleDateFormat(SimpleDateFormat.MONTH, locale);
System.out.println(sdf2.format(persianCalendar.getTime()));
// weekday name output in persian
SimpleDateFormat sdf3 = new SimpleDateFormat(SimpleDateFormat.WEEKDAY, locale);
System.out.println(sdf3.format(persianCalendar.getTime()));
// full date output in YY/MM/dd form
SimpleDateFormat sdf4 = new SimpleDateFormat("YY/MM/dd", locale);
System.out.println(sdf4.format(persianCalendar.getTime()));
Salida:
ه.ش. ۱۳۹۵ تیر ۱۰, پنجشنبه
۱۳۹۵
تیر
پنجشنبه
۹۵/۰۴/۱۰
Si necesita que la salida esté en inglés, cambie el new ULocale("fa_IR@calendar=persian")
al new ULocale("@calendar=persian")
.
Salida:
AP 1395 Tir 10, Thu
1395
Tir
Thu
95/04/10
Otras cosas agradables:
// Get number of days in month
System.out.println(persianCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // 31
// Get first day of week
System.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)); //1395
System.out.println(persianCalendar.get(Calendar.MONTH)); // 5
System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH)); // 10
Para otras funcionalidades, consulte las demostraciones icu4j , especialmente:
- demostración de varios campos de calendario
- lista de los martes y jueves del año en curso
- demo de conversión de número a representación de texto (use
fa_IR
para configuración regional)
También vea Calendar y PersianCalendar API.
Observaciones
Si le preocupa la huella de icu4j (el tamaño del tarro es alto para usted), entonces puede reconstruirlo y simplemente usar el módulo Calendario (2,176KB). Lea sobre esto here .
este método es muy exacto y simplemente también admite años bisiestos
Explique:
paso 1: la hora actual contiene la hora actual
paso 2: crea dos arreglos para el día gregoriano y jalali en meses (g_days_in_month & j_days_in_month)
paso 3: crear variable para el tiempo de diferencia de retención entre calendarios (gy, gm, gd) y la variable g_day_no para días de años.
paso 4: insertar el día del mes y recogerlo con días.
paso 5: convertir días de años a años jalili (jy)
al final: establecer el mes de jalali a partir del número de día, establecer el día de jalali a partir del día de jalali del conjunto de meses.
buena suerte.
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
int Day = (today.monthDay); // Day of the month (0-31)
int Month = (today.month); // Month (0-11)
int Year = (today.year); // Year
String persianDate = GregorianToJalali(Year, Month+1, Day);
private String GregorianToJalali(int g_y, int g_m, int g_d)
{
int[] g_days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] j_days_in_month = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29};
int gy = g_y-1600;
int gm = g_m-1;
int gd = g_d-1;
int g_day_no = 365*gy+div(gy+3,4)-div(gy+99,100)+div(gy+399,400);
for (int i=0; i < gm; ++i)
g_day_no += g_days_in_month[i];
if (gm>1 && ((gy%4==0 && gy%100!=0) || (gy%400==0)))
// leap and after Feb
g_day_no++;
g_day_no += gd;
int j_day_no = g_day_no-79;
int j_np = div(j_day_no, 12053); //12053 = 365*33 + 32/4
j_day_no = j_day_no % 12053;
int jy = 979+33*j_np+4*div(j_day_no,1461); // 1461 = 365*4 + 4/4
j_day_no %= 1461;
if (j_day_no >= 366) {
jy += div(j_day_no-1, 365);
j_day_no = (j_day_no-1)%365;
}
int j;
for (j=0; j < 11 && j_day_no >= j_days_in_month[j]; ++j)
j_day_no -= j_days_in_month[j];
int jm = j+1;
int jd = j_day_no+1;
String Result= jy+"/"+jm+"/"+jd;
return (Result);
}
private int div(float a, float b)
{
return (int)(a/b);
}
Beside Time4A, icu4j, which are too heavy libraries, I written a class to handle Persian calendar accurately and you can find it here: https://github.com/hadilq/java-persian-calendar/blob/master/persian/src/main/java/ir/hadilq/PersianCalendar.java
As you can find it in its tests, this class supports from year 3000 before hijra to 3000 after hijra.
Desarrollé el widget Android Shamsi datepicker con la vista de evento hijri-gerogian- shamsi: https://github.com/irshst/ir.shes.calendar https://github.com/irshst/ir.shes.calendar