我希望将所有Android版本的 Gregorian (西部)日期转换为波斯语(Shamsi)日期,反之亦然。
是否有完整可靠的库或算法?
答案 0 :(得分:69)
我使用这种算法多年,在1901年到2099年之间非常准确。
使用它并享受! :)
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);
}
}
答案 1 :(得分:30)
我认为这个java类更容易使用,更可靠。 我在Iranian forum找到了它,伊朗人使用Jalali Calendar并将其称为“Shamsi”,这意味着太阳历。这是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
您可以轻松设置公历日,月和年,然后调用“getIranianDate()”方法以字符串格式获取日期,就像下面的示例代码一样:
MyUtil.CalendarTool ct = new CalendarTool(2012,10,10);
System.out.println(ct.getIranianDate());
我希望它有所帮助。
答案 2 :(得分:14)
使用 IBM 的 Unicode国际组件(icu4j)。它是Unicode Consortium的一部分,非常可靠,可以在任何Java项目(Java EE,Java SE,Android等)中使用。将其与Gradle,Maven或简称为downloading jar一起使用。
你可以期待String class_ = elem.getElementsByTagName("class").item(0).
getChildNodes().item(1).getNodeName();
的功能和其他一些功能。
java.util.Calendar
警告:请注意,基于Java日历的月份字段为零,因此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
日历将代表1395的第4个月,而不是第3个月!
如果你需要波斯文本输出:
calendar.set(1395, 3, 10)
输出:
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()));
如果您需要输出为英语,请将ه.ش. ۱۳۹۵ تیر ۱۰, پنجشنبه
۱۳۹۵
تیر
پنجشنبه
۹۵/۰۴/۱۰
更改为new ULocale("fa_IR@calendar=persian")
。
输出:
new ULocale("@calendar=persian")
其他好东西:
AP 1395 Tir 10, Thu
1395
Tir
Thu
95/04/10
有关其他功能,请参阅icu4j demos,特别是:
// 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
进行区域设置)另请参阅Calendar和PersianCalendar API。
如果您关注icu4j的jar大小,那么您可以重建它并只使用Calendar模块(2,176KB)。更多信息:ver. 57 or earlier,ver. 58 or later。
答案 3 :(得分:11)
这种方法非常精确,也简单地支持闰年
说明:
第1步: 今天的时间包含当前时间
第2步: 为gregorian和jalali创建两个月的数组(g_days_in_month&amp; j_days_in_month)
第3步: 为日历之间的保留差异时间创建变量 (GY,GM,GD) 和变量g_day_no为几天。
第4步: 插入日期并收集日期。
第5步: 将岁月转换为jalili年(jy)
最后: 从日期编号设置jalali月, 从jalali日月阵列开始设置jalali日。
祝你好运。 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);
}
答案 4 :(得分:8)
我的库Time4A的最新版本v3.10-2015g(Time4J的Android改编版)包含对Jalali日历的支持。该库部署了Borkowski的算法(有效期至格里高利2129年)。实际上,波斯语月和时代(包括基于CLDR-28的波斯语和普什图语)支持大约25种语言。
用法示例:
// 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
Android上与java.util.Date的互操作性
由于Time4A管理自己的一组不可变类型,并且不是基于Android的主要时间类型,我将展示以下桥梁:
// 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);
答案 5 :(得分:5)
试试这个
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;
}
}
}
创建实例
PersianCalendar sc = new PersianCalendar();
String s= sc.strWeekDay + " " +sc.day + " " +
sc.strMonth + " " + sc.year;
System.out.print(s);
//setTitle(s);
答案 6 :(得分:2)
有persianutils个项目,其中包含一个双向DateConverter;格里高利&lt; - &gt;波斯语(Jalali)。它是用Scala编写的,所以我想在Java项目中使用它会很容易。
所使用的算法适用于高达约3790的格里高利年和高达约3170的波斯年。
免责声明:我是PersianUtils的作者
答案 7 :(得分:2)
您可以将此稳定且经过测试的库与格式化程序类Roozh for Java一起使用。它并没有被弃用,并且总是使用波斯日期时间所需的很酷功能进行更新。
答案 8 :(得分:2)
像这样的函数创建calculateJalaliDate; 然后在String
中返回Jalali日期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;
}
答案 9 :(得分:1)
我开发了带有hijri - gerogian- shamsi事件视图的Android Shamsi datepicker小部件: https://github.com/irshst/ir.shes.calendar