All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.icu.util.PersianCalendar Maven / Gradle / Ivy

There is a newer version: 2.12.15
Show newest version
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 1996-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.util;

import java.util.Date;
import java.util.Locale;

import com.ibm.icu.util.ULocale.Category;

/**
 * PersianCalendar is a subclass of Calendar that
 * that implements the Persian calendar.  It is used as the main civil
 * calendar in Iran and Afghanistan, and by Iranians and Afghans worldwide.
 * 

* The Persian calendar is solar, and is similar to the Gregorian calendar * in various ways, except its leap year rule, which is determined * astronomically. The Persian year starts around the March equinox. *

* The modern Persian calendar (used in Iran since 1925 CE and in * Afghanistan since 1957 CE), has the lengths of the months fixed. The * first six months are 31 days each, the next five months are 30 days each, * and the final month is 29 days in non-leap years and 30 days in leap * ones. Historically, the lengths of the month differed in different * years, but they were finally fixed at the times mentioned above. Partial * information is available about the historical lengths. *

* The official rule for determination of the beginning of the Persian year * is locale dependent, but at the same time, it has not specified a locale. * Iranians around the world traditionally follow the calendar authorities * of Iran, which haven't officially specified the locale. Some * calendarists use some point in Tehran as the locale, while others have * tried the more neutral 52.5 degrees east meridian. It is not clear which * locale should be used for the Persian calendar of Afghanistan, but it is * expected that for about one year in every twenty-four years, the Afghan * calendar may become different from the Iranian one. *

* The exact locale to be used for the Iranian calendar starts to make a * difference at around 2090 CE. The specific arithmetic method implemented * here, commonly known as the 33-year cycle rule, matches the astronomical * calendar at least for the whole period that the calendar has been both * well-defined and official, from 1925 to around 2090 CE. The other * commonly known algorithm, the 2820-year cycle, has been incorrectly * designed to follow the tropical year instead of the spring equinoctial * year, and fails to match the astronomical one as early as 2025 CE. *

* This class should not be subclassed.

*

* PersianCalendar usually should be instantiated using * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a * ULocale with the tag "@calendar=persian".

* * @see com.ibm.icu.util.GregorianCalendar * @see com.ibm.icu.util.Calendar * * @author Roozbeh Pournader * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public class PersianCalendar extends Calendar { private static final long serialVersionUID = -6727306982975111643L; //------------------------------------------------------------------------- // Constants... //------------------------------------------------------------------------- private static final int[][] MONTH_COUNT = { //len len2 st { 31, 31, 0 }, // Farvardin { 31, 31, 31 }, // Ordibehesht { 31, 31, 62 }, // Khordad { 31, 31, 93 }, // Tir { 31, 31, 124 }, // Mordad { 31, 31, 155 }, // Shahrivar { 30, 30, 186 }, // Mehr { 30, 30, 216 }, // Aban { 30, 30, 246 }, // Azar { 30, 30, 276 }, // Dey { 30, 30, 306 }, // Bahman { 29, 30, 336 } // Esfand // len length of month // len2 length of month in a leap year // st days in year before start of month }; private static final int PERSIAN_EPOCH = 1948320; //------------------------------------------------------------------------- // Constructors... //------------------------------------------------------------------------- /** * Constructs a default PersianCalendar using the current time * in the default time zone with the default FORMAT locale. * @see Category#FORMAT * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar() { this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); } /** * Constructs a PersianCalendar based on the current time * in the given time zone with the default FORMAT locale. * @param zone the given time zone. * @see Category#FORMAT * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(TimeZone zone) { this(zone, ULocale.getDefault(Category.FORMAT)); } /** * Constructs a PersianCalendar based on the current time * in the default time zone with the given locale. * * @param aLocale the given locale. * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(Locale aLocale) { this(TimeZone.getDefault(), aLocale); } /** * Constructs a PersianCalendar based on the current time * in the default time zone with the given locale. * * @param locale the given ulocale. * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(ULocale locale) { this(TimeZone.getDefault(), locale); } /** * Constructs a PersianCalendar based on the current time * in the given time zone with the given locale. * * @param zone the given time zone. * @param aLocale the given locale. * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(TimeZone zone, Locale aLocale) { super(zone, aLocale); setTimeInMillis(System.currentTimeMillis()); } /** * Constructs a PersianCalendar based on the current time * in the given time zone with the given locale. * * @param zone the given time zone. * @param locale the given ulocale. * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(TimeZone zone, ULocale locale) { super(zone, locale); setTimeInMillis(System.currentTimeMillis()); } /** * Constructs a PersianCalendar with the given date set * in the default time zone with the default FORMAT locale. * * @param date The date to which the new calendar is set. * @see Category#FORMAT * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(Date date) { super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); this.setTime(date); } /** * Constructs a PersianCalendar with the given date set * in the default time zone with the default FORMAT locale. * * @param year the value used to set the {@link #YEAR YEAR} time field in the calendar. * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar. * Note that the month value is 0-based. e.g., 0 for Farvardin. * @param date the value used to set the {@link #DATE DATE} time field in the calendar. * @see Category#FORMAT * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(int year, int month, int date) { super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); this.set(Calendar.YEAR, year); this.set(Calendar.MONTH, month); this.set(Calendar.DATE, date); } /** * Constructs a PersianCalendar with the given date * and time set for the default time zone with the default FORMAT locale. * * @param year the value used to set the {@link #YEAR YEAR} time field in the calendar. * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar. * Note that the month value is 0-based. e.g., 0 for Farvardin. * @param date the value used to set the {@link #DATE DATE} time field in the calendar. * @param hour the value used to set the {@link #HOUR_OF_DAY HOUR_OF_DAY} time field * in the calendar. * @param minute the value used to set the {@link #MINUTE MINUTE} time field * in the calendar. * @param second the value used to set the {@link #SECOND SECOND} time field * in the calendar. * @see Category#FORMAT * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public PersianCalendar(int year, int month, int date, int hour, int minute, int second) { super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); this.set(Calendar.YEAR, year); this.set(Calendar.MONTH, month); this.set(Calendar.DATE, date); this.set(Calendar.HOUR_OF_DAY, hour); this.set(Calendar.MINUTE, minute); this.set(Calendar.SECOND, second); } //------------------------------------------------------------------------- // Minimum / Maximum access functions //------------------------------------------------------------------------- private static final int LIMITS[][] = { // Minimum Greatest Least Maximum // Minimum Maximum { 0, 0, 0, 0}, // ERA { -5000000, -5000000, 5000000, 5000000}, // YEAR { 0, 0, 11, 11}, // MONTH { 1, 1, 52, 53}, // WEEK_OF_YEAR {/* */}, // WEEK_OF_MONTH { 1, 1, 29, 31}, // DAY_OF_MONTH { 1, 1, 365, 366}, // DAY_OF_YEAR {/* */}, // DAY_OF_WEEK { -1, -1, 5, 5}, // DAY_OF_WEEK_IN_MONTH {/* */}, // AM_PM {/* */}, // HOUR {/* */}, // HOUR_OF_DAY {/* */}, // MINUTE {/* */}, // SECOND {/* */}, // MILLISECOND {/* */}, // ZONE_OFFSET {/* */}, // DST_OFFSET { -5000000, -5000000, 5000000, 5000000}, // YEAR_WOY {/* */}, // DOW_LOCAL { -5000000, -5000000, 5000000, 5000000}, // EXTENDED_YEAR {/* */}, // JULIAN_DAY {/* */}, // MILLISECONDS_IN_DAY }; /** * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected int handleGetLimit(int field, int limitType) { return LIMITS[field][limitType]; } //------------------------------------------------------------------------- // Assorted calculation utilities // /** * Determine whether a year is a leap year in the Persian calendar */ private final static boolean isLeapYear(int year) { int[] remainder = new int[1]; floorDivide(25 * year + 11, 33, remainder); return remainder[0] < 8; } //---------------------------------------------------------------------- // Calendar framework //---------------------------------------------------------------------- /** * Return the length (in days) of the given month. * * @param extendedYear The Persian year * @param month The Persian month, 0-based * * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected int handleGetMonthLength(int extendedYear, int month) { // If the month is out of range, adjust it into range, and // modify the extended year value accordingly. if (month < 0 || month > 11) { int[] rem = new int[1]; extendedYear += floorDivide(month, 12, rem); month = rem[0]; } return MONTH_COUNT[month][isLeapYear(extendedYear)?1:0]; } /** * Return the number of days in the given Persian year * * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected int handleGetYearLength(int extendedYear) { return isLeapYear(extendedYear) ? 366 : 365; } //------------------------------------------------------------------------- // Functions for converting from field values to milliseconds.... //------------------------------------------------------------------------- /** * Return JD of start of given month/year * * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) { // If the month is out of range, adjust it into range, and // modify the extended year value accordingly. if (month < 0 || month > 11) { int[] rem = new int[1]; eyear += floorDivide(month, 12, rem); month = rem[0]; } int julianDay = PERSIAN_EPOCH - 1 + 365 * (eyear - 1) + floorDivide(8 * eyear + 21, 33); if (month != 0) { julianDay += MONTH_COUNT[month][2]; } return julianDay; } //------------------------------------------------------------------------- // Functions for converting from milliseconds to field values //------------------------------------------------------------------------- /** * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected int handleGetExtendedYear() { int year; if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) { year = internalGet(EXTENDED_YEAR, 1); // Default to year 1 } else { year = internalGet(YEAR, 1); // Default to year 1 } return year; } /** * Override Calendar to compute several fields specific to the Persian * calendar system. These are: * *
  • ERA *
  • YEAR *
  • MONTH *
  • DAY_OF_MONTH *
  • DAY_OF_YEAR *
  • EXTENDED_YEAR
* * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this * method is called. * * @internal * @deprecated This API is ICU internal only. */ @Deprecated protected void handleComputeFields(int julianDay) { int year, month, dayOfMonth, dayOfYear; long daysSinceEpoch = julianDay - PERSIAN_EPOCH; year = 1 + (int) floorDivide(33 * daysSinceEpoch + 3, 12053); long farvardin1 = 365L * (year - 1L) + floorDivide(8L * year + 21, 33L); dayOfYear = (int)(daysSinceEpoch - farvardin1); // 0-based if (dayOfYear < 216) { // Compute 0-based month month = dayOfYear / 31; } else { month = (dayOfYear - 6) / 30; } dayOfMonth = dayOfYear - MONTH_COUNT[month][2] + 1; ++dayOfYear; // Make it 1-based now internalSet(ERA, 0); internalSet(YEAR, year); internalSet(EXTENDED_YEAR, year); internalSet(MONTH, month); internalSet(DAY_OF_MONTH, dayOfMonth); internalSet(DAY_OF_YEAR, dayOfYear); } /** * {@inheritDoc} * * @internal * @deprecated This API is ICU internal only. */ @Deprecated public String getType() { return "persian"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy