
com.ghasemkiani.util.icu.PersianCalendar Maven / Gradle / Ivy
Show all versions of persiancalendar Show documentation
/*
PersianCalendar.java
2005-01-11 17:49:03
Copyright � Ghasem Kiani
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
HISTORY:
Version 2.1 2005-03-18:
Improved documentation. Some i18n enhancements.
Version 2.0 2005-02-21:
First release.
*/
package com.ghasemkiani.util.icu;
import com.ibm.icu.util.Calendar;
import java.util.Date;
import java.util.Locale;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import static com.ghasemkiani.util.PersianCalendarUtils.*;
import static com.ghasemkiani.util.PersianCalendarHelper.*;
import com.ghasemkiani.util.PersianCalendarConstants;
import com.ghasemkiani.util.icu.PersianDateFormat;
/**
This is an arithmetic implementation of the Persian Calendar
(also known as the Iranian or Jalali Calendar) based on the calendar
framework of ICU4J (IBM's International Components for Unicode for
Java), version 3.2.
ICU4J is copyright International Business Machines Corporation (IBM).
Please see the file icu4j_3_2_license.html
included with
this software package for information about ICU4J license.
An astronomical version of the Persian Calendar may be implemented in
a future release.
Usage Example
The following code snippet shows how to use the {@link com.ghasemkiani.util.icu.PersianCalendar}
class:
import java.util.Date;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.text.DateFormat;
import com.ghasemkiani.util.icu.PersianCalendar;
// ...
PersianCalendar pc = new PersianCalendar(TimeZone.getTimeZone("Asia/Tehran"));
DateFormat df = pc.getDateTimeFormat(DateFormat.FULL, DateFormat.DEFAULT, new ULocale("fa", "IR", ""));
String result = df.format(new Date());
// ...
Some possible results are shown below:
possible results
Locale
Formatted String
فارسی
جمعه، ۷ اسفند ۱۳۸۳ ۱۲:۰۰:۳۹
فارسی (افغانستان)
جمعه، ۷ حوت ۱۳۸۳ ۱۲:۰۰:۳۹
العربية
الجمعة, ٧ إسفند, ١٣٨٣ ١٢:٠٠:٣٩ م
English
Friday, Esfand 7, 1383 12:00:39 PM
Français
vendredi 7 Esfand 1383 12:00:39
Deutsch
Freitag, 7. Esfand 1383 12:00:39
Русский
7 Эсфанд 1383 г. 12:00:39
Türkçe
07 Isfend 1383 Cuma 12:00:39
Esperanto
vendredo, 7-a de esfando 1383 12:00:39
@author Ghasem Kiani
@version 2.1
*/
public class PersianCalendar extends Calendar implements PersianCalendarConstants
{
private static String copyright = "Copyright \u00a9 2005, Ghasem Kiani. All Rights Reserved.";
/**
Before Hijra Era.
*/
public static final int BH = 0;
/**
After Hijra Era.
*/
public static final int AH = 1;
/**
Constructs a Persian calendar with the default time zone and locale.
*/
public PersianCalendar()
{
this(TimeZone.getDefault(), ULocale.getDefault());
}
/**
Constructs a Persian calendar with the specified time zone and the default locale.
@param zone the desired timezone.
*/
public PersianCalendar(TimeZone zone)
{
this(zone, ULocale.getDefault());
}
/**
Constructs a Persian calendar with the default time zone and the specified locale.
@param aLocale the desired locale.
*/
public PersianCalendar(Locale aLocale)
{
this(ULocale.forLocale(aLocale));
}
/**
Constructs a Persian calendar with the default time zone and the specified locale.
@param locale the desired locale.
*/
public PersianCalendar(ULocale locale)
{
this(TimeZone.getDefault(), locale);
}
/**
Constructs a Persian calendar with the specified time zone and locale.
@param zone the desired timezone.
@param aLocale the desired locale.
*/
public PersianCalendar(TimeZone zone, Locale aLocale)
{
this(zone, ULocale.forLocale(aLocale));
}
/**
Constructs a Persian calendar with the specified time zone and locale.
@param zone the desired timezone.
@param locale the desired locale.
*/
public PersianCalendar(TimeZone zone, ULocale locale)
{
super(zone, locale);
setTimeInMillis(System.currentTimeMillis());
}
/**
Constructs a Persian calendar with the default time zone and locale
and sets its time to the specified date-time.
@param date the date of this calendar object.
*/
public PersianCalendar(Date date)
{
super(TimeZone.getDefault(), ULocale.getDefault());
setTime(date);
}
/**
Constructs a Persian calendar with the default time zone and locale
and sets its time to the specified date.
@param year the Persian year.
@param month the Persian month (zero-based).
@param date the Persian day of month.
*/
public PersianCalendar(int year, int month, int date)
{
super(TimeZone.getDefault(), ULocale.getDefault());
set(ERA, AH);
set(YEAR, year);
set(MONTH, month);
set(DATE, date);
}
/**
Constructs a Persian calendar with the default time zone and locale
and sets its time to the specified time.
@param year the Persian year.
@param month the Persian month (zero-based).
@param date the Persian day of month.
@param hour the hours part of time.
@param minute the minutes part of time.
@param second the seconds part of time.
*/
public PersianCalendar(int year, int month, int date, int hour, int minute, int second)
{
super(TimeZone.getDefault(), ULocale.getDefault());
set(ERA, AH);
set(YEAR, year);
set(MONTH, month);
set(DATE, date);
set(HOUR_OF_DAY, hour);
set(MINUTE, minute);
set(SECOND, second);
}
private static final int LIMITS[][] =
{
// Minimum, GreatestMinimum, LeastMaximum, Maximum
{ 0, 0, 1, 1 }, // ERA
{ 1, 1, 5000000, 5000000 }, // YEAR
{ 0, 0, 11, 11 }, // MONTH
{ 1, 1, 51, 52 }, // WEEK_OF_YEAR
{ 0, 0, 5, 6 }, // WEEK_OF_MONTH
{ 1, 1, 29, 31 }, // DAY_OF_MONTH
{ 1, 1, 365, 366 }, // DAY_OF_YEAR
{ /* */ }, // DAY_OF_WEEK
{ -1, -1, 4, 5 }, // DAY_OF_WEEK_IN_MONTH
{ /* */ }, // AM_PM
{ /* */ }, // HOUR
{ /* */ }, // HOUR_OF_DAY
{ /* */ }, // MINUTE
{ /* */ }, // SECOND
{ /* */ }, // MILLISECOND
{ /* */ }, // ZONE_OFFSET
{ /* */ }, // DST_OFFSET
{ -5000001, -5000001, 5000001, 5000001 }, // YEAR_WOY
{ /* */ }, // DOW_LOCAL
{ -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR
{ /* */ }, // JULIAN_DAY
{ /* */ }, // MILLISECONDS_IN_DAY
};
protected int handleGetLimit(int field, int limitType)
{
return LIMITS[field][limitType];
}
protected int handleGetMonthLength(int extendedYear, int month)
{
if(month < 6) return 31;
if(month < 11) return 30;
return isLeapYear(extendedYear)? 30: 29;
}
protected int handleGetYearLength(int extendedYear)
{
return isLeapYear(extendedYear)? 366: 365;
}
protected int handleComputeMonthStart(int extendedYear, int month, boolean useMonth)
{
return (int)pj(extendedYear, month, 0);
}
protected int handleGetExtendedYear()
{
int year;
if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR)
{
year = internalGet(EXTENDED_YEAR, 1);
}
else
{
int era = internalGet(ERA, AH);
if (era == BH)
{
year = 1 - internalGet(YEAR, 1); // Convert to extended year
}
else
{
year = internalGet(YEAR, 1);
}
}
return year;
}
protected void handleComputeFields(int julianDay)
{
long r = jp(julianDay);
int year = (int)y(r);
int month = m(r);
int day = d(r);
internalSet(ERA, year > 0? AH: BH);
internalSet(YEAR, year > 0? year: 1 - year);
internalSet(EXTENDED_YEAR, year);
internalSet(MONTH, month);
internalSet(DAY_OF_MONTH, day);
internalSet(DAY_OF_YEAR, day + month * 30 + Math.min(6, month));
}
protected DateFormat handleGetDateFormat(String pattern, ULocale locale)
{
return new PersianDateFormat(pattern, locale);
}
/**
Adds the specified amount to the specified field of this calendar.
This is overriden to correct the behavior at the end of the leap years.
@param field the field index.
@param amount the amount to add.
*/
public void add(int field, int amount)
{
switch (field)
{
case MONTH:
{
int month = get(MONTH);
int extendedYear = get(EXTENDED_YEAR);
if (amount > 0)
{
extendedYear += amount / 12;
month += amount % 12;
if(month > 11)
{
month -= 12;
extendedYear++;
}
}
else
{
amount = -amount;
extendedYear -= amount / 12;
month -= amount % 12;
if(month < 0)
{
month += 12;
extendedYear--;
}
}
set(EXTENDED_YEAR, extendedYear);
set(MONTH, month);
pinField(DAY_OF_MONTH);
break;
}
default:
super.add(field, amount);
break;
}
}
/**
Type of this calendar.
Type is used for loading resources. Since there is no calendar data for
this type ("persian"), the CalendarData
will use the fallback type
("gregorian"). This is fine, just the month names and era names must
be changed. This is taken care of by {@link PersianDateFormatSymbols},
which uses a java resource bundle in its turn.
@return type of this calendar ("persian").
*/
public String getType()
{
return "persian";
}
}