12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others. 22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 2005-2011, International Business Machines Corporation and * 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale.Category; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Base class for EthiopicCalendar and CopticCalendar. 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertabstract class CECalendar extends Calendar { 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // jdk1.4.2 serialver 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long serialVersionUID = -999547623066414271L; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final int LIMITS[][] = { 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Minimum Greatest Least Maximum 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Minimum Maximum 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 0, 0, 1, 1 }, // ERA 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1, 1, 5000000, 5000000 }, // YEAR 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 0, 0, 12, 12 }, // MONTH 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1, 1, 52, 53 }, // WEEK_OF_YEAR 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // WEEK_OF_MONTH 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1, 1, 5, 30 }, // DAY_OF_MONTH 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1, 1, 365, 366 }, // DAY_OF_YEAR 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // DAY_OF_WEEK 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { -1, -1, 1, 5 }, // DAY_OF_WEEK_IN_MONTH 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // AM_PM 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // HOUR 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // HOUR_OF_DAY 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // MINUTE 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // SECOND 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // MILLISECOND 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // ZONE_OFFSET 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // DST_OFFSET 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { -5000000, -5000000, 5000000, 5000000 }, // YEAR_WOY 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // DOW_LOCAL 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // JULIAN_DAY 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {/* */}, // MILLISECONDS_IN_DAY 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Constructors... 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a default <code>CECalendar</code> using the current time 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the default time zone with the default <code>FORMAT</code> locale. 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar() { 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> based on the current time 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the given time zone with the default <code>FORMAT</code> locale. 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param zone The time zone for the new calendar. 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(TimeZone zone) { 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(zone, ULocale.getDefault(Category.FORMAT)); 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> based on the current time 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the default time zone with the given locale. 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param aLocale The locale for the new calendar. 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(Locale aLocale) { 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(TimeZone.getDefault(), aLocale); 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> based on the current time 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the default time zone with the given locale. 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale The locale for the new calendar. 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(ULocale locale) { 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(TimeZone.getDefault(), locale); 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> based on the current time 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the given time zone with the given locale. 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param zone The time zone for the new calendar. 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param aLocale The locale for the new calendar. 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(TimeZone zone, Locale aLocale) { 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(zone, aLocale); 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert setTimeInMillis(System.currentTimeMillis()); 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> based on the current time 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the given time zone with the given locale. 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param zone The time zone for the new calendar. 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale The locale for the new calendar. 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(TimeZone zone, ULocale locale) { 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(zone, locale); 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert setTimeInMillis(System.currentTimeMillis()); 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> with the given date set 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the default time zone with the default <code>FORMAT</code> locale. 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param year The value used to set the calendar's {@link #YEAR YEAR} time field. 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param month The value used to set the calendar's {@link #MONTH MONTH} time field. 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The value is 0-based. e.g., 0 for Tishri. 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param date The value used to set the calendar's {@link #DATE DATE} time field. 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(int year, int month, int date) { 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.set(year, month, date); 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> with the given date set 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the default time zone with the default <code>FORMAT</code> locale. 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param date The date to which the new calendar is set. 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(Date date) { 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.setTime(date); 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a <code>CECalendar</code> with the given date 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and time set for the default time zone with the default <code>FORMAT</code> locale. 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param year The value used to set the calendar's {@link #YEAR YEAR} time field. 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param month The value used to set the calendar's {@link #MONTH MONTH} time field. 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The value is 0-based. e.g., 0 for Tishri. 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param date The value used to set the calendar's {@link #DATE DATE} time field. 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param hour The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field. 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param minute The value used to set the calendar's {@link #MINUTE MINUTE} time field. 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param second The value used to set the calendar's {@link #SECOND SECOND} time field. 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected CECalendar(int year, int month, int date, int hour, 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int minute, int second) 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.set(year, month, date, hour, minute, second); 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Calendar framework 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The Coptic and Ethiopic calendars differ only in their epochs. 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This method must be implemented by CECalendar subclasses to 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * return the date offset from Julian. 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract protected int getJDEpochOffset(); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return JD of start of given month/extended year 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int handleComputeMonthStart(int eyear, 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int emonth, 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean useMonth) { 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ceToJD(eyear, emonth, 0, getJDEpochOffset()); 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Calculate the limit for a specified type of limit and field 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int handleGetLimit(int field, int limitType) { 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return LIMITS[field][limitType]; 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // (The following method is not called because all existing subclasses 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // override it. 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:OFF 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return the number of days in the given month of the given extended 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * year of this calendar system. Subclasses should override this 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * method if they can provide a more correct or more efficient 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * implementation than the default implementation in Calendar. 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int handleGetMonthLength(int extendedYear, int month) 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The Ethiopian and Coptic calendars have 13 months, 12 of 30 days each and 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // an intercalary month at the end of the year of 5 or 6 days, depending whether 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the year is a leap year or not. The Leap Year follows the same rules as the 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Julian Calendar so that the extra month always has six days in the year before 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // a Julian Leap Year. 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ((month + 1) % 13 != 0) 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // not intercalary month 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return 30; 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert else 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // intercalary month 5 days + possible leap day 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((extendedYear % 4) / 3) + 5; 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:ON 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Calendar framework 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------- 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert an Coptic/Ethiopic year, month and day to a Julian day 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param year the extended year 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param month the month 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param day the day 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return Julian day 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static int ceToJD(long year, int month, int day, int jdEpochOffset) { 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Julian<->Ethiopic algorithms from: 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // "Calendars in Ethiopia", Berhanu Beyene, Manfred Kudlek, International Conference 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // of Ethiopian Studies XV, Hamburg, 2003 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // handle month > 12, < 0 (e.g. from add/set) 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ( month >= 0 ) { 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert year += month/13; 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert month %= 13; 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++month; 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert year += month/13 - 1; 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert month = month%13 + 12; 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (int) ( 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert jdEpochOffset // difference from Julian epoch to 1,1,1 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + 365 * year // number of days from years 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + floorDivide(year, 4) // extra day of leap year 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + 30 * month // number of days from months (months are 0-based) 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + day - 1 // number of days for present month (1 based) 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ); 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convert a Julian day to an Coptic/Ethiopic year, month and day 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static void jdToCE(int julianDay, int jdEpochOffset, int[] fields) { 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int c4; // number of 4 year cycle (1461 days) 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int[] r4 = new int[1]; // remainder of 4 year cycle, always positive 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert c4 = floorDivide(julianDay - jdEpochOffset, 1461, r4); 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // exteded year 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fields[0] = 4 * c4 + (r4[0]/365 - r4[0]/1460); // 4 * <number of 4year cycle> + <years within the last cycle> 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int doy = (r4[0] == 1460) ? 365 : (r4[0] % 365); // days in present year 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // month 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fields[1] = doy / 30; // 30 -> Coptic/Ethiopic month length up to 12th month 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // day 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fields[2] = (doy % 30) + 1; // 1-based days in a month 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 277