모든 Android 버전에서 그레고리 안 (서부) 날짜를 페르시아 (Shamsi) 날짜로 또는 그 반대로 변환하고 싶습니다 .
완전하고 신뢰할 수있는 라이브러리 또는 알고리즘이 있습니까?
답변:
저는이 알고리즘을 수년간 사용하고 있으며 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);
}
}
이 자바 클래스가 사용하기 쉽고 더 안정적이라고 생각합니다. 나는 이란 포럼 에서 그것을 찾았고 ,이란 인들은 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());
도움이되기를 바랍니다.
사용 IBM 의 유니 코드에 대한 국제 구성 요소 ( ICU4J ). Unicode Consortium의 일부 이며 매우 안정적이며 모든 Java 프로젝트 (Java EE, Java SE, Android 등)에서 사용할 수 있습니다. Gradle , Maven 또는 단순히 jar 를 다운로드 하여 사용하십시오 .
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
public class DateTimeUtils {
public static final ULocale PERSIAN_LOCALE = new ULocale("fa_IR@calendar=persian");
public static final ULocale PERSIAN_EN_LOCALE = new ULocale("en@calendar=persian");
public static final ZoneId IRAN_ZONE_ID = ZoneId.of("Asia/Tehran");
public static Calendar fromDateToPersianCalendar(Date date) {
Calendar persianCalendar = Calendar.getInstance(PERSIAN_LOCALE);
persianCalendar.clear();
persianCalendar.setTime(date);
return persianCalendar;
}
/**
* @param date
* @param field example: Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, etc
*/
public static int fromDateToPersianCalendarField(Date date, int field) {
return fromDateToPersianCalendar(date).get(field);
}
public static String fromDateToPersianString(Date date) {
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, PERSIAN_LOCALE);
return df.format(date);
}
public static String fromDateToPersianString(Date date, String pattern) {
return new SimpleDateFormat(pattern, PERSIAN_LOCALE).format(date);
}
public static String fromDateToPersianString(Date date, String pattern, ULocale locale) {
return new SimpleDateFormat(pattern, locale).format(date);
}
/**
* @param month is zero based. (e.g. Farvardin = 0, Ordibehesht = 1, etc.)
*/
public static Date fromPersianDateToDate(int year, int month, int day, int hour, int minutes, int seconds) {
return new Date(fromPersianDate(year, month, day, hour, minutes, seconds));
}
/**
* @param month is zero based. (e.g. Farvardin = 0, Ordibehesht = 1, etc.)
*/
public static String fromPersianDateToPersianString(int year, int month, int day, int hour, int minutes, int seconds) {
return fromDateToPersianString(fromPersianDateToDate(year, month, day, hour, minutes, seconds));
}
/**
* @param month is zero based. (e.g. Farvardin = 0, Ordibehesht = 1, etc.)
*/
public static LocalDateTime fromPersianDateToLocalDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
return fromPersianDateToZonedDateTime(year, month, day, hour, minutes, seconds).toLocalDateTime();
}
/**
* @param month is zero based. (e.g. Farvardin = 0, Ordibehesht = 1, etc.)
*/
public static ZonedDateTime fromPersianDateToZonedDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
return toZonedDateTime(fromPersianDate(year, month, day, hour, minutes, seconds));
}
/**
* @param month is zero based. (e.g. Farvardin = 0, Ordibehesht = 1, etc.)
*/
public static long fromPersianDate(int year, int month, int day, int hour, int minutes, int seconds) {
Calendar persianCalendar = Calendar.getInstance(PERSIAN_LOCALE);
persianCalendar.clear();
persianCalendar.set(year, month, day, hour, minutes, seconds);
return persianCalendar.getTimeInMillis();
}
public static ZonedDateTime toZonedDateTime(Long epochMilli) {
if(epochMilli == null) return null;
return Instant.ofEpochMilli(epochMilli).atZone(IRAN_ZONE_ID);
}
}
용법:
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
import com.ibm.icu.util.Calendar;
public class DateTimeUtilsTest {
public static void main(String[] args) {
System.out.println("Java 7 and before:");
Date date = new Date(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 days
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("\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 string
System.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate, "dd/MM/yy - H:mm:dd")); // to Persian string with custom format
System.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate, "dd/MM/yy - H:mm:dd" , DateTimeUtils.PERSIAN_EN_LOCALE)); // to Persian string with custom format and Latin characters
System.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);
}
}
산출:
Java 7 and before:
Converting Gregorian date to Persian:
1395
3
10
۱۳۹۵ تیر ۱۰, پنجشنبه
Adding 1 month and 5 days:
1395
4
15
۱۳۹۵ مرداد ۱۵, جمعه
Converting Persian date to Gregorian:
Thu Jun 30 09:30:00 IRDT 2016
۱۳۹۵ تیر ۱۰, پنجشنبه
۱۰/۰۴/۹۵ - ۹:۳۰:۱۰
10/04/95 - 9:30:10
Java 8 onward:
2016-06-30T09:30+04:30[Asia/Tehran]
2016-06-30T09:30
java.util.Calendar
다른 기능 외에도 의 모든 기능을 기대할 수 있습니다 .
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
경고 : 월 필드는 Java 달력을 기반으로하는 0이므로 calendar.set(1395, 3, 10)
달력 기준은 3 일이 아닌 1395 년 4 월을 나타냅니다!
페르시아어로 텍스트 출력이 필요한 경우 :
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("en@calendar=persian")
.
산출:
AP 1395 Tir 10, Thu
1395
Tir
Thu
95/04/10
다른 좋은 것들 :
// 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
다른 기능에 대해서는 icu4j 데모를 참조하십시오 .
fa_IR
로케일에 사용 )Calendar 및 PersianCalendar API 도 참조하십시오 .
또는 java.time
같은 클래스 를 사용 하려면이 메서드를 사용하여 페르시아 날짜를 선호하는 클래스로 변환하면됩니다.ZonedDateTime
LocalDateTime
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
...
public static LocalDateTime fromPersianDateToLocalDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
return fromPersianDateToZonedDateTime(year, month, day, hour, minutes, seconds).toLocalDateTime();
}
public static ZonedDateTime fromPersianDateToZonedDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
return toZonedDateTime(fromPersianDate(year, month, day, hour, minutes, seconds));
}
public static long fromPersianDate(int year, int month, int day, int hour, int minutes, int seconds) {
Calendar persianCalendar = Calendar.getInstance(new ULocale("fa_IR@calendar=persian"));
persianCalendar.clear();
persianCalendar.set(year, month, day, hour, minutes, seconds);
return persianCalendar.getTimeInMillis();
}
public static ZonedDateTime toZonedDateTime(Long epochMilli) {
if(epochMilli == null) return null;
return Instant.ofEpochMilli(epochMilli).atZone(ZoneId.of("Asia/Tehran"));
}
icu4j의 jar 크기가 걱정된다면 다시 빌드하고 Calendar 모듈 (2,176KB)을 사용하면됩니다. 더 많은 정보 : ver. 57 이전 버전 , ver. ICU 데이터 빌드 도구를 사용하는 58 이상 .
getActualMaximum(Calendar.DAY_OF_MONTH)
. 사용 방법을 보여주기 위해 답변을 업데이트했습니다.
getActualMaximum(Calendar.DAY_OF_MONTH)
, 현재, 내년의 모든 달을 확인 하고 결과가 정확 했기 때문에 실수가 당신 편이라고 생각 합니다. Java 달력에서 월이 0이라는 것을 알고 있습니까? 월 필드에 5를 넣으면 실제로는 5 일이 아닌 6 일을 의미합니다! 11 (12 개월)도 마찬가지입니다. 그렇지 않은 경우 잘못된 동작을 유발하는 정확한 날짜를 제공 할 수 있습니까?
이 방법은 매우 정확하며 단순히 윤년을 지원합니다.
설명:
1 단계 : 오늘 시간에는 현재 시간이 포함됩니다.
2 단계 : 월 (g_days_in_month & j_days_in_month)에서 그레고리 안 및 잘 랄리 일에 대한 두 개의 배열 생성
3 단계 : 달력 (gy, gm, gd) 간의 보존 차이 시간에 대한 변수를 만들고 연도에 대한 g_day_no 변수를 만듭니다.
4 단계 : 날짜를 입력하고 날짜로 수집합니다.
5 단계 : 일수를 자 릴리 연도로 변환 (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);
}
내 라이브러리 Time4A ( Time4J 의 Android 버전)의 최신 버전 v3.10-2015g 에는 Jalali 캘린더에 대한 지원이 포함되어 있습니다. 라이브러리는 Borkowski 알고리즘을 배포합니다 (그레고리력 2129 년까지 유효). 실제로 페르시아의 달과 시대에 대해 약 25 개의 언어가 지원됩니다 (CLDR-28에 기반한 Farsi 및 Pashto 포함).
사용 예 :
// 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);
ApplicationStarter.initialize(this, ...);
? Time4A- 사용법 섹션의 코드 초기화 예제를 참조하십시오 . 스택 추적은 그 원인을 나타냅니다.
이 시도
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);
이 persianutils의 양방향 DateConverter를 포함하는 프로젝트; Gregorian <-> Persian (Jalali). 그것은 Scala로 작성되었으므로 Java 프로젝트에서 사용하는 것이 매우 쉬울 것이라고 생각합니다.
사용 된 알고리즘은 최대 3790 년의 그레고리력 및 최대 3170 년의 페르시아 년 동안 유효합니다.
면책 조항 : 저는 PersianUtils의 작성자입니다.
포매터 클래스 인 Roozh for Java 와 함께이 안정적이고 테스트 된 라이브러리를 사용할 수 있습니다 . 더 이상 사용되지 않으며 페르시아 날짜 시간에 필요한 멋진 기능으로 항상 업데이트됩니다.
다음과 같은 함수로 calculateJalaliDate를 생성합니다. 그런 다음 Jalali 날짜를 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;
}
hijri-gerogian- shamsi 이벤트보기 : https://github.com/irshst/ir.shes.calendar로 Android Shamsi datepicker 위젯을 개발했습니다.
너무 무거운 라이브러리 인 Time4A, icu4j 외에도 페르시아 달력을 정확하게 처리하기 위해 클래스를 작성했으며 여기에서 찾을 수 있습니다. https://github.com/hadilq/java-persian-calendar/blob/master/persian/src /main/java/ir/hadilq/PersianCalendar.java
테스트에서 알 수 있듯이이 클래스는 hijra 이전 3000 년부터 hijra 이후 3000 년까지 지원합니다.