jdk/src/share/classes/java/time/chrono/HijrahChronology.java
author sherman
Tue, 12 Feb 2013 09:25:43 -0800
changeset 15658 55b829ca2334
child 16852 60207b2b4b42
permissions -rw-r--r--
8007392: JSR 310: DateTime API Updates 8007520: Update date/time classes in j.util and j.sql packages 8007572: Replace existing jdk timezone data at <java.home>/lib/zi with JSR310's tzdb Summary: Integration of JSR310 Date/Time API for M7 Reviewed-by: darcy, alanb, naoto Contributed-by: scolebourne@joda.org, roger.riggs@oracle.com, masayoshi.okutsu@oracle.com, patrick.zhang@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     1
/*
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     4
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    10
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    15
 * accompanied this code).
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    16
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    20
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    23
 * questions.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    24
 */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    25
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    26
/*
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    27
 * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    28
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    29
 * All rights reserved.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    30
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    31
 * Redistribution and use in source and binary forms, with or without
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    32
 * modification, are permitted provided that the following conditions are met:
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    33
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    34
 *  * Redistributions of source code must retain the above copyright notice,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    35
 *    this list of conditions and the following disclaimer.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    36
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    37
 *  * Redistributions in binary form must reproduce the above copyright notice,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    38
 *    this list of conditions and the following disclaimer in the documentation
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    39
 *    and/or other materials provided with the distribution.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    40
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    41
 *  * Neither the name of JSR-310 nor the names of its contributors
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    42
 *    may be used to endorse or promote products derived from this software
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    43
 *    without specific prior written permission.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    44
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    45
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    46
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    47
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    48
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    49
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    50
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    51
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    52
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    53
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    54
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    55
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    56
 */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    57
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    58
package java.time.chrono;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    59
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    60
import static java.time.temporal.ChronoField.EPOCH_DAY;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    61
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    62
import java.io.IOException;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    63
import java.io.Serializable;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    64
import java.text.ParseException;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    65
import java.time.Clock;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    66
import java.time.DateTimeException;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    67
import java.time.Instant;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    68
import java.time.LocalDate;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    69
import java.time.ZoneId;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    70
import java.time.temporal.ChronoField;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    71
import java.time.temporal.TemporalAccessor;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    72
import java.time.temporal.ValueRange;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    73
import java.util.Arrays;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    74
import java.util.HashMap;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    75
import java.util.List;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    76
import java.util.Locale;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    77
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    78
/**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    79
 * The Hijrah calendar system.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    80
 * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    81
 * This chronology defines the rules of the Hijrah calendar system.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    82
 * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    83
 * The implementation follows the Freeman-Grenville algorithm (*1) and has following features.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    84
 * <p><ul>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    85
 * <li>A year has 12 months.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    86
 * <li>Over a cycle of 30 years there are 11 leap years.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    87
 * <li>There are 30 days in month number 1, 3, 5, 7, 9, and 11,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    88
 * and 29 days in month number 2, 4, 6, 8, 10, and 12.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    89
 * <li>In a leap year month 12 has 30 days.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    90
 * <li>In a 30 year cycle, year 2, 5, 7, 10, 13, 16, 18, 21, 24,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    91
 * 26, and 29 are leap years.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    92
 * <li>Total of 10631 days in a 30 years cycle.</li>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    93
 * </ul><p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    94
 * <P>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    95
 * The table shows the features described above.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    96
 * <blockquote>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    97
 * <table border="1">
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    98
 *   <caption>Hijrah Calendar Months</caption>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
    99
 *   <tbody>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   100
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   101
 *       <th># of month</th>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   102
 *       <th>Name of month</th>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   103
 *       <th>Number of days</th>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   104
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   105
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   106
 *       <td>1</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   107
 *       <td>Muharram</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   108
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   109
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   110
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   111
 *       <td>2</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   112
 *       <td>Safar</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   113
 *       <td>29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   114
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   115
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   116
 *       <td>3</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   117
 *       <td>Rabi'al-Awwal</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   118
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   119
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   120
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   121
 *       <td>4</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   122
 *       <td>Rabi'ath-Thani</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   123
 *       <td>29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   124
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   125
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   126
 *       <td>5</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   127
 *       <td>Jumada l-Ula</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   128
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   129
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   130
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   131
 *       <td>6</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   132
 *       <td>Jumada t-Tania</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   133
 *       <td>29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   134
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   135
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   136
 *       <td>7</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   137
 *       <td>Rajab</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   138
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   139
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   140
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   141
 *       <td>8</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   142
 *       <td>Sha`ban</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   143
 *       <td>29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   144
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   145
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   146
 *       <td>9</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   147
 *       <td>Ramadan</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   148
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   149
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   150
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   151
 *       <td>10</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   152
 *       <td>Shawwal</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   153
 *       <td>29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   154
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   155
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   156
 *       <td>11</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   157
 *       <td>Dhu 'l-Qa`da</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   158
 *       <td>30</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   159
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   160
 *     <tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   161
 *       <td>12</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   162
 *       <td>Dhu 'l-Hijja</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   163
 *       <td>29, but 30 days in years 2, 5, 7, 10,<br>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   164
 * 13, 16, 18, 21, 24, 26, and 29</td>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   165
 *     </tr>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   166
 *   </tbody>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   167
 * </table>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   168
 * </blockquote>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   169
 * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   170
 * (*1) The algorithm is taken from the book,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   171
 * The Muslim and Christian Calendars by G.S.P. Freeman-Grenville.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   172
 * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   173
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   174
 * <h3>Specification for implementors</h3>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   175
 * This class is immutable and thread-safe.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   176
 *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   177
 * @since 1.8
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   178
 */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   179
public final class HijrahChronology extends Chronology implements Serializable {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   180
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   181
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   182
     * The Hijrah Calendar id.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   183
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   184
    private final String typeId;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   185
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   186
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   187
     * The Hijrah calendarType.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   188
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   189
    private final String calendarType;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   190
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   191
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   192
     * The singleton instance for the era before the current one - Before Hijrah -
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   193
     * which has the value 0.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   194
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   195
    public static final Era ERA_BEFORE_AH = HijrahEra.BEFORE_AH;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   196
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   197
     * The singleton instance for the current era - Hijrah - which has the value 1.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   198
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   199
    public static final Era ERA_AH = HijrahEra.AH;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   200
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   201
     * Serialization version.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   202
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   203
    private static final long serialVersionUID = 3127340209035924785L;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   204
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   205
     * The minimum valid year-of-era.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   206
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   207
    public static final int MIN_YEAR_OF_ERA = 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   208
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   209
     * The maximum valid year-of-era.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   210
     * This is currently set to 9999 but may be changed to increase the valid range
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   211
     * in a future version of the specification.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   212
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   213
    public static final int MAX_YEAR_OF_ERA = 9999;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   214
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   215
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   216
     * Number of Gregorian day of July 19, year 622 (Gregorian), which is epoch day
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   217
     * of Hijrah calendar.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   218
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   219
    private static final int HIJRAH_JAN_1_1_GREGORIAN_DAY = -492148;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   220
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   221
     * 0-based, for number of day-of-year in the beginning of month in normal
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   222
     * year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   223
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   224
    private static final int NUM_DAYS[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   225
        {0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325};
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   226
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   227
     * 0-based, for number of day-of-year in the beginning of month in leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   228
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   229
    private static final int LEAP_NUM_DAYS[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   230
        {0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325};
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   231
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   232
     * 0-based, for day-of-month in normal year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   233
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   234
    private static final int MONTH_LENGTH[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   235
        {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29};
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   236
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   237
     * 0-based, for day-of-month in leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   238
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   239
    private static final int LEAP_MONTH_LENGTH[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   240
        {30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30};
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   241
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   242
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   243
     * <pre>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   244
     *                            Greatest       Least
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   245
     * Field name        Minimum   Minimum     Maximum     Maximum
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   246
     * ----------        -------   -------     -------     -------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   247
     * ERA                     0         0           1           1
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   248
     * YEAR_OF_ERA             1         1        9999        9999
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   249
     * MONTH_OF_YEAR           1         1          12          12
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   250
     * DAY_OF_MONTH            1         1          29          30
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   251
     * DAY_OF_YEAR             1         1         354         355
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   252
     * </pre>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   253
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   254
     * Minimum values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   255
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   256
    private static final int MIN_VALUES[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   257
        {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   258
        0,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   259
        MIN_YEAR_OF_ERA,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   260
        0,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   261
        1,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   262
        0,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   263
        1,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   264
        1
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   265
        };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   266
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   267
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   268
     * Least maximum values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   269
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   270
    private static final int LEAST_MAX_VALUES[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   271
        {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   272
        1,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   273
        MAX_YEAR_OF_ERA,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   274
        11,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   275
        51,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   276
        5,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   277
        29,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   278
        354
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   279
        };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   280
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   281
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   282
     * Maximum values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   283
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   284
    private static final int MAX_VALUES[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   285
        {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   286
        1,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   287
        MAX_YEAR_OF_ERA,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   288
        11,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   289
        52,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   290
        6,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   291
        30,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   292
        355
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   293
        };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   294
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   295
   /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   296
     * Position of day-of-month. This value is used to get the min/max value
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   297
     * from an array.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   298
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   299
    private static final int POSITION_DAY_OF_MONTH = 5;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   300
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   301
     * Position of day-of-year. This value is used to get the min/max value from
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   302
     * an array.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   303
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   304
    private static final int POSITION_DAY_OF_YEAR = 6;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   305
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   306
     * Zero-based start date of cycle year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   307
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   308
    private static final int CYCLEYEAR_START_DATE[] =
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   309
        {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   310
        0,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   311
        354,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   312
        709,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   313
        1063,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   314
        1417,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   315
        1772,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   316
        2126,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   317
        2481,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   318
        2835,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   319
        3189,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   320
        3544,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   321
        3898,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   322
        4252,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   323
        4607,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   324
        4961,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   325
        5315,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   326
        5670,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   327
        6024,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   328
        6379,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   329
        6733,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   330
        7087,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   331
        7442,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   332
        7796,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   333
        8150,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   334
        8505,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   335
        8859,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   336
        9214,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   337
        9568,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   338
        9922,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   339
        10277
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   340
        };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   341
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   342
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   343
     * Holding the adjusted month days in year. The key is a year (Integer) and
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   344
     * the value is the all the month days in year (int[]).
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   345
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   346
    private final HashMap<Integer, int[]> ADJUSTED_MONTH_DAYS = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   347
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   348
     * Holding the adjusted month length in year. The key is a year (Integer)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   349
     * and the value is the all the month length in year (int[]).
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   350
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   351
    private final HashMap<Integer, int[]> ADJUSTED_MONTH_LENGTHS = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   352
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   353
     * Holding the adjusted days in the 30 year cycle. The key is a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   354
     * (Integer) and the value is the all the starting days of the year in the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   355
     * cycle (int[]).
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   356
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   357
    private final HashMap<Integer, int[]> ADJUSTED_CYCLE_YEARS = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   358
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   359
     * Holding the adjusted cycle in the 1 - 30000 year. The key is the cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   360
     * number (Integer) and the value is the starting days in the cycle in the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   361
     * term.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   362
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   363
    private final long[] ADJUSTED_CYCLES;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   364
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   365
     * Holding the adjusted min values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   366
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   367
    private final int[] ADJUSTED_MIN_VALUES;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   368
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   369
     * Holding the adjusted max least max values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   370
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   371
    private final int[] ADJUSTED_LEAST_MAX_VALUES;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   372
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   373
     * Holding adjusted max values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   374
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   375
    private final int[] ADJUSTED_MAX_VALUES;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   376
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   377
     * Holding the non-adjusted month days in year for non leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   378
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   379
    private static final int[] DEFAULT_MONTH_DAYS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   380
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   381
     * Holding the non-adjusted month days in year for leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   382
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   383
    private static final int[] DEFAULT_LEAP_MONTH_DAYS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   384
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   385
     * Holding the non-adjusted month length for non leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   386
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   387
    private static final int[] DEFAULT_MONTH_LENGTHS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   388
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   389
     * Holding the non-adjusted month length for leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   390
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   391
    private static final int[] DEFAULT_LEAP_MONTH_LENGTHS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   392
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   393
     * Holding the non-adjusted 30 year cycle starting day.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   394
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   395
    private static final int[] DEFAULT_CYCLE_YEARS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   396
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   397
     * number of 30-year cycles to hold the deviation data.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   398
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   399
    private static final int MAX_ADJUSTED_CYCLE = 334; // to support year 9999
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   400
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   401
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   402
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   403
     * Narrow names for eras.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   404
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   405
    private static final HashMap<String, String[]> ERA_NARROW_NAMES = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   406
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   407
     * Short names for eras.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   408
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   409
    private static final HashMap<String, String[]> ERA_SHORT_NAMES = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   410
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   411
     * Full names for eras.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   412
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   413
    private static final HashMap<String, String[]> ERA_FULL_NAMES = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   414
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   415
     * Fallback language for the era names.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   416
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   417
    private static final String FALLBACK_LANGUAGE = "en";
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   418
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   419
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   420
     * Singleton instance of the Hijrah chronology.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   421
     * Must be initialized after the rest of the static initialization.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   422
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   423
    public static final HijrahChronology INSTANCE;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   424
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   425
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   426
     * Name data.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   427
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   428
    static {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   429
        ERA_NARROW_NAMES.put(FALLBACK_LANGUAGE, new String[]{"BH", "HE"});
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   430
        ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, new String[]{"B.H.", "H.E."});
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   431
        ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Before Hijrah", "Hijrah Era"});
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   432
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   433
        DEFAULT_MONTH_DAYS = Arrays.copyOf(NUM_DAYS, NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   434
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   435
        DEFAULT_LEAP_MONTH_DAYS = Arrays.copyOf(LEAP_NUM_DAYS, LEAP_NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   436
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   437
        DEFAULT_MONTH_LENGTHS = Arrays.copyOf(MONTH_LENGTH, MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   438
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   439
        DEFAULT_LEAP_MONTH_LENGTHS = Arrays.copyOf(LEAP_MONTH_LENGTH, LEAP_MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   440
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   441
        DEFAULT_CYCLE_YEARS = Arrays.copyOf(CYCLEYEAR_START_DATE, CYCLEYEAR_START_DATE.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   442
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   443
        INSTANCE = new HijrahChronology();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   444
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   445
        String extraCalendars = java.security.AccessController.doPrivileged(
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   446
            new sun.security.action.GetPropertyAction("java.time.chrono.HijrahCalendars"));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   447
        if (extraCalendars != null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   448
            try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   449
                // Split on whitespace
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   450
                String[] splits = extraCalendars.split("\\s");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   451
                for (String cal : splits) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   452
                    if (!cal.isEmpty()) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   453
                        // Split on the delimiter between typeId "-" calendarType
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   454
                        String[] type = cal.split("-");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   455
                        Chronology cal2 = new HijrahChronology(type[0], type.length > 1 ? type[1] : type[0]);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   456
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   457
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   458
            } catch (Exception ex) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   459
                // Log the error
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   460
                // ex.printStackTrace();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   461
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   462
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   463
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   464
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   465
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   466
     * Restricted constructor.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   467
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   468
    private HijrahChronology() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   469
        this("Hijrah", "islamicc");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   470
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   471
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   472
     * Constructor for name and type HijrahChronology.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   473
     * @param id the id of the calendar
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   474
     * @param calendarType the calendar type
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   475
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   476
    private HijrahChronology(String id, String calendarType) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   477
        this.typeId = id;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   478
        this.calendarType = calendarType;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   479
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   480
        ADJUSTED_CYCLES = new long[MAX_ADJUSTED_CYCLE];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   481
        for (int i = 0; i < ADJUSTED_CYCLES.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   482
            ADJUSTED_CYCLES[i] = (10631L * i);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   483
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   484
        // Initialize min values, least max values and max values.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   485
        ADJUSTED_MIN_VALUES = Arrays.copyOf(MIN_VALUES, MIN_VALUES.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   486
        ADJUSTED_LEAST_MAX_VALUES = Arrays.copyOf(LEAST_MAX_VALUES, LEAST_MAX_VALUES.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   487
        ADJUSTED_MAX_VALUES = Arrays.copyOf(MAX_VALUES,MAX_VALUES.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   488
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   489
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   490
            // Implicitly reads deviation data for this HijrahChronology.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   491
            boolean any = HijrahDeviationReader.readDeviation(typeId, calendarType, this::addDeviationAsHijrah);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   492
        } catch (IOException | ParseException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   493
            // do nothing. Log deviation config errors.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   494
            //e.printStackTrace();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   495
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   496
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   497
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   498
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   499
     * Resolve singleton.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   500
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   501
     * @return the singleton instance, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   502
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   503
    private Object readResolve() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   504
        return INSTANCE;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   505
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   506
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   507
    //-----------------------------------------------------------------------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   508
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   509
     * Gets the ID of the chronology - 'Hijrah'.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   510
     * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   511
     * The ID uniquely identifies the {@code Chronology}.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   512
     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   513
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   514
     * @return the chronology ID - 'Hijrah'
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   515
     * @see #getCalendarType()
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   516
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   517
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   518
    public String getId() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   519
        return typeId;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   520
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   521
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   522
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   523
     * Gets the calendar type of the underlying calendar system - 'islamicc'.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   524
     * <p>
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   525
     * The calendar type is an identifier defined by the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   526
     * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   527
     * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   528
     * It can also be used as part of a locale, accessible via
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   529
     * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   530
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   531
     * @return the calendar system type - 'islamicc'
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   532
     * @see #getId()
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   533
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   534
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   535
    public String getCalendarType() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   536
        return calendarType;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   537
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   538
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   539
    //-----------------------------------------------------------------------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   540
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   541
    public HijrahDate date(int prolepticYear, int month, int dayOfMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   542
        return HijrahDate.of(this, prolepticYear, month, dayOfMonth);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   543
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   544
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   545
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   546
    public HijrahDate dateYearDay(int prolepticYear, int dayOfYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   547
        return HijrahDate.of(this, prolepticYear, 1, 1).plusDays(dayOfYear - 1);  // TODO better
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   548
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   549
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   550
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   551
    public HijrahDate date(TemporalAccessor temporal) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   552
        if (temporal instanceof HijrahDate) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   553
            return (HijrahDate) temporal;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   554
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   555
        return HijrahDate.ofEpochDay(this, temporal.getLong(EPOCH_DAY));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   556
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   557
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   558
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   559
    public HijrahDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   560
        return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   561
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   562
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   563
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   564
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   565
    public HijrahDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   566
        return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   567
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   568
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   569
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   570
    public HijrahDate dateNow() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   571
        return dateNow(Clock.systemDefaultZone());
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   572
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   573
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   574
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   575
    public HijrahDate dateNow(ZoneId zone) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   576
        return dateNow(Clock.system(zone));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   577
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   578
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   579
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   580
    public HijrahDate dateNow(Clock clock) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   581
        return date(LocalDate.now(clock));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   582
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   583
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   584
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   585
    public ChronoLocalDateTime<HijrahDate> localDateTime(TemporalAccessor temporal) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   586
        return (ChronoLocalDateTime<HijrahDate>)super.localDateTime(temporal);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   587
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   588
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   589
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   590
    public ChronoZonedDateTime<HijrahDate> zonedDateTime(TemporalAccessor temporal) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   591
        return (ChronoZonedDateTime<HijrahDate>)super.zonedDateTime(temporal);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   592
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   593
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   594
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   595
    public ChronoZonedDateTime<HijrahDate> zonedDateTime(Instant instant, ZoneId zone) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   596
        return (ChronoZonedDateTime<HijrahDate>)super.zonedDateTime(instant, zone);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   597
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   598
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   599
    //-----------------------------------------------------------------------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   600
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   601
    public boolean isLeapYear(long prolepticYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   602
        return isLeapYear0(prolepticYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   603
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   604
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   605
     * Returns if the year is a leap year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   606
     * @param prolepticYear he year to compute from
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   607
     * @return {@code true} if the year is a leap year, otherwise {@code false}
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   608
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   609
    private static boolean isLeapYear0(long prolepticYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   610
        return (14 + 11 * (prolepticYear > 0 ? prolepticYear : -prolepticYear)) % 30 < 11;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   611
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   612
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   613
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   614
    public int prolepticYear(Era era, int yearOfEra) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   615
        if (era instanceof HijrahEra == false) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   616
            throw new DateTimeException("Era must be HijrahEra");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   617
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   618
        return (era == HijrahEra.AH ? yearOfEra : 1 - yearOfEra);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   619
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   620
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   621
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   622
    public Era eraOf(int eraValue) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   623
        switch (eraValue) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   624
            case 0:
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   625
                return HijrahEra.BEFORE_AH;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   626
            case 1:
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   627
                return HijrahEra.AH;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   628
            default:
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   629
                throw new DateTimeException("invalid Hijrah era");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   630
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   631
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   632
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   633
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   634
    public List<Era> eras() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   635
        return Arrays.<Era>asList(HijrahEra.values());
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   636
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   637
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   638
    //-----------------------------------------------------------------------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   639
    @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   640
    public ValueRange range(ChronoField field) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   641
        return field.range();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   642
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   643
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   644
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   645
     * Check the validity of a yearOfEra.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   646
     * @param yearOfEra the year to check
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   647
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   648
    void checkValidYearOfEra(int yearOfEra) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   649
         if (yearOfEra < MIN_YEAR_OF_ERA  ||
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   650
                 yearOfEra > MAX_YEAR_OF_ERA) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   651
             throw new DateTimeException("Invalid year of Hijrah Era");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   652
         }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   653
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   654
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   655
    void checkValidDayOfYear(int dayOfYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   656
         if (dayOfYear < 1  ||
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   657
                 dayOfYear > getMaximumDayOfYear()) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   658
             throw new DateTimeException("Invalid day of year of Hijrah date");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   659
         }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   660
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   661
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   662
    void checkValidMonth(int month) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   663
         if (month < 1 || month > 12) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   664
             throw new DateTimeException("Invalid month of Hijrah date");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   665
         }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   666
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   667
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   668
    void checkValidDayOfMonth(int dayOfMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   669
         if (dayOfMonth < 1  ||
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   670
                 dayOfMonth > getMaximumDayOfMonth()) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   671
             throw new DateTimeException("Invalid day of month of Hijrah date, day "
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   672
                     + dayOfMonth + " greater than " + getMaximumDayOfMonth() + " or less than 1");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   673
         }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   674
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   675
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   676
    //-----------------------------------------------------------------------
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   677
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   678
     * Returns the int array containing the following field from the julian day.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   679
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   680
     * int[0] = ERA
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   681
     * int[1] = YEAR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   682
     * int[2] = MONTH
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   683
     * int[3] = DATE
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   684
     * int[4] = DAY_OF_YEAR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   685
     * int[5] = DAY_OF_WEEK
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   686
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   687
     * @param gregorianDays  a julian day.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   688
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   689
    int[] getHijrahDateInfo(long gregorianDays) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   690
        int era, year, month, date, dayOfWeek, dayOfYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   691
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   692
        int cycleNumber, yearInCycle, dayOfCycle;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   693
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   694
        long epochDay = gregorianDays - HIJRAH_JAN_1_1_GREGORIAN_DAY;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   695
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   696
        if (epochDay >= 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   697
            cycleNumber = getCycleNumber(epochDay); // 0 - 99.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   698
            dayOfCycle = getDayOfCycle(epochDay, cycleNumber); // 0 - 10631.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   699
            yearInCycle = getYearInCycle(cycleNumber, dayOfCycle); // 0 - 29.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   700
            dayOfYear = getDayOfYear(cycleNumber, dayOfCycle, yearInCycle);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   701
            // 0 - 354/355
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   702
            year = cycleNumber * 30 + yearInCycle + 1; // 1-based year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   703
            month = getMonthOfYear(dayOfYear, year); // 0-based month-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   704
            date = getDayOfMonth(dayOfYear, month, year); // 0-based date
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   705
            ++date; // Convert from 0-based to 1-based
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   706
            era = HijrahEra.AH.getValue();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   707
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   708
            cycleNumber = (int) epochDay / 10631; // 0 or negative number.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   709
            dayOfCycle = (int) epochDay % 10631; // -10630 - 0.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   710
            if (dayOfCycle == 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   711
                dayOfCycle = -10631;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   712
                cycleNumber++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   713
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   714
            yearInCycle = getYearInCycle(cycleNumber, dayOfCycle); // 0 - 29.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   715
            dayOfYear = getDayOfYear(cycleNumber, dayOfCycle, yearInCycle);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   716
            year = cycleNumber * 30 - yearInCycle; // negative number.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   717
            year = 1 - year;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   718
            dayOfYear = (isLeapYear(year) ? (dayOfYear + 355)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   719
                    : (dayOfYear + 354));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   720
            month = getMonthOfYear(dayOfYear, year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   721
            date = getDayOfMonth(dayOfYear, month, year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   722
            ++date; // Convert from 0-based to 1-based
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   723
            era = HijrahEra.BEFORE_AH.getValue();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   724
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   725
        // Hijrah day zero is a Friday
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   726
        dayOfWeek = (int) ((epochDay + 5) % 7);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   727
        dayOfWeek += (dayOfWeek <= 0) ? 7 : 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   728
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   729
        int dateInfo[] = new int[6];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   730
        dateInfo[0] = era;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   731
        dateInfo[1] = year;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   732
        dateInfo[2] = month + 1; // change to 1-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   733
        dateInfo[3] = date;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   734
        dateInfo[4] = dayOfYear + 1; // change to 1-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   735
        dateInfo[5] = dayOfWeek;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   736
        return dateInfo;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   737
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   738
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   739
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   740
     * Return Gregorian epoch day from Hijrah year, month, and day.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   741
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   742
     * @param prolepticYear  the year to represent, caller calculated
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   743
     * @param monthOfYear  the month-of-year to represent, caller calculated
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   744
     * @param dayOfMonth  the day-of-month to represent, caller calculated
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   745
     * @return a julian day
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   746
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   747
    long getGregorianEpochDay(int prolepticYear, int monthOfYear, int dayOfMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   748
        long day = yearToGregorianEpochDay(prolepticYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   749
        day += getMonthDays(monthOfYear - 1, prolepticYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   750
        day += dayOfMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   751
        return day;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   752
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   753
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   754
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   755
     * Returns the Gregorian epoch day from the proleptic year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   756
     * @param prolepticYear the proleptic year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   757
     * @return the Epoch day
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   758
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   759
    private long yearToGregorianEpochDay(int prolepticYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   760
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   761
        int cycleNumber = (prolepticYear - 1) / 30; // 0-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   762
        int yearInCycle = (prolepticYear - 1) % 30; // 0-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   763
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   764
        int dayInCycle = getAdjustedCycle(cycleNumber)[Math.abs(yearInCycle)]
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   765
                ;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   766
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   767
        if (yearInCycle < 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   768
            dayInCycle = -dayInCycle;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   769
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   770
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   771
        Long cycleDays;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   772
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   773
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   774
            cycleDays = ADJUSTED_CYCLES[cycleNumber];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   775
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   776
            cycleDays = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   777
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   778
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   779
        if (cycleDays == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   780
            cycleDays = new Long(cycleNumber * 10631);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   781
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   782
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   783
        return (cycleDays.longValue() + dayInCycle + HIJRAH_JAN_1_1_GREGORIAN_DAY - 1);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   784
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   785
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   786
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   787
     * Returns the 30 year cycle number from the epoch day.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   788
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   789
     * @param epochDay  an epoch day
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   790
     * @return a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   791
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   792
    private int getCycleNumber(long epochDay) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   793
        long[] days = ADJUSTED_CYCLES;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   794
        int cycleNumber;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   795
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   796
            for (int i = 0; i < days.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   797
                if (epochDay < days[i]) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   798
                    return i - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   799
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   800
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   801
            cycleNumber = (int) epochDay / 10631;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   802
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   803
            cycleNumber = (int) epochDay / 10631;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   804
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   805
        return cycleNumber;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   806
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   807
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   808
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   809
     * Returns day of cycle from the epoch day and cycle number.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   810
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   811
     * @param epochDay  an epoch day
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   812
     * @param cycleNumber  a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   813
     * @return a day of cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   814
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   815
    private int getDayOfCycle(long epochDay, int cycleNumber) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   816
        Long day;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   817
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   818
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   819
            day = ADJUSTED_CYCLES[cycleNumber];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   820
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   821
            day = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   822
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   823
        if (day == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   824
            day = new Long(cycleNumber * 10631);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   825
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   826
        return (int) (epochDay - day.longValue());
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   827
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   828
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   829
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   830
     * Returns the year in cycle from the cycle number and day of cycle.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   831
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   832
     * @param cycleNumber  a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   833
     * @param dayOfCycle  day of cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   834
     * @return a year in cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   835
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   836
    private int getYearInCycle(int cycleNumber, long dayOfCycle) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   837
        int[] cycles = getAdjustedCycle(cycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   838
        if (dayOfCycle == 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   839
            return 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   840
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   841
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   842
        if (dayOfCycle > 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   843
            for (int i = 0; i < cycles.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   844
                if (dayOfCycle < cycles[i]) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   845
                    return i - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   846
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   847
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   848
            return 29;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   849
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   850
            dayOfCycle = -dayOfCycle;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   851
            for (int i = 0; i < cycles.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   852
                if (dayOfCycle <= cycles[i]) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   853
                    return i - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   854
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   855
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   856
            return 29;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   857
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   858
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   859
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   860
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   861
     * Returns adjusted 30 year cycle starting day as Integer array from the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   862
     * cycle number specified.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   863
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   864
     * @param cycleNumber  a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   865
     * @return an Integer array
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   866
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   867
    int[] getAdjustedCycle(int cycleNumber) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   868
        int[] cycles;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   869
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   870
            cycles = ADJUSTED_CYCLE_YEARS.get(cycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   871
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   872
            cycles = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   873
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   874
        if (cycles == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   875
            cycles = DEFAULT_CYCLE_YEARS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   876
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   877
        return cycles;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   878
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   879
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   880
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   881
     * Returns adjusted month days as Integer array form the year specified.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   882
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   883
     * @param year  a year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   884
     * @return an Integer array
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   885
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   886
    int[] getAdjustedMonthDays(int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   887
        int[] newMonths;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   888
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   889
            newMonths = ADJUSTED_MONTH_DAYS.get(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   890
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   891
            newMonths = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   892
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   893
        if (newMonths == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   894
            if (isLeapYear0(year)) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   895
                newMonths = DEFAULT_LEAP_MONTH_DAYS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   896
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   897
                newMonths = DEFAULT_MONTH_DAYS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   898
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   899
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   900
        return newMonths;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   901
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   902
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   903
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   904
     * Returns adjusted month length as Integer array form the year specified.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   905
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   906
     * @param year  a year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   907
     * @return an Integer array
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   908
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   909
    int[] getAdjustedMonthLength(int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   910
        int[] newMonths;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   911
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   912
            newMonths = ADJUSTED_MONTH_LENGTHS.get(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   913
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   914
            newMonths = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   915
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   916
        if (newMonths == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   917
            if (isLeapYear0(year)) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   918
                newMonths = DEFAULT_LEAP_MONTH_LENGTHS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   919
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   920
                newMonths = DEFAULT_MONTH_LENGTHS;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   921
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   922
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   923
        return newMonths;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   924
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   925
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   926
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   927
     * Returns day-of-year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   928
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   929
     * @param cycleNumber  a cycle number
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   930
     * @param dayOfCycle  day of cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   931
     * @param yearInCycle  year in cycle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   932
     * @return day-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   933
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   934
    private int getDayOfYear(int cycleNumber, int dayOfCycle, int yearInCycle) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   935
        int[] cycles = getAdjustedCycle(cycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   936
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   937
        if (dayOfCycle > 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   938
            return dayOfCycle - cycles[yearInCycle];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   939
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   940
            return cycles[yearInCycle] + dayOfCycle;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   941
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   942
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   943
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   944
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   945
     * Returns month-of-year. 0-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   946
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   947
     * @param dayOfYear  day-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   948
     * @param year  a year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   949
     * @return month-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   950
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   951
    private int getMonthOfYear(int dayOfYear, int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   952
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   953
        int[] newMonths = getAdjustedMonthDays(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   954
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   955
        if (dayOfYear >= 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   956
            for (int i = 0; i < newMonths.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   957
                if (dayOfYear < newMonths[i]) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   958
                    return i - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   959
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   960
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   961
            return 11;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   962
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   963
            dayOfYear = (isLeapYear0(year) ? (dayOfYear + 355)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   964
                    : (dayOfYear + 354));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   965
            for (int i = 0; i < newMonths.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   966
                if (dayOfYear < newMonths[i]) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   967
                    return i - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   968
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   969
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   970
            return 11;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   971
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   972
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   973
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   974
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   975
     * Returns day-of-month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   976
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   977
     * @param dayOfYear  day of  year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   978
     * @param month  month
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   979
     * @param year  year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   980
     * @return day-of-month
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   981
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   982
    private int getDayOfMonth(int dayOfYear, int month, int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   983
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   984
        int[] newMonths = getAdjustedMonthDays(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   985
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   986
        if (dayOfYear >= 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   987
            if (month > 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   988
                return dayOfYear - newMonths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   989
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   990
                return dayOfYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   991
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   992
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   993
            dayOfYear = (isLeapYear0(year) ? (dayOfYear + 355)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   994
                    : (dayOfYear + 354));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   995
            if (month > 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   996
                return dayOfYear - newMonths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   997
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   998
                return dayOfYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
   999
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1000
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1001
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1002
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1003
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1004
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1005
     * Returns month days from the beginning of year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1006
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1007
     * @param month  month (0-based)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1008
     * @parma year  year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1009
     * @return month days from the beginning of year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1010
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1011
    private int getMonthDays(int month, int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1012
        int[] newMonths = getAdjustedMonthDays(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1013
        return newMonths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1014
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1015
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1016
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1017
     * Returns month length.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1018
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1019
     * @param month  month (0-based)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1020
     * @param year  year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1021
     * @return month length
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1022
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1023
    private int getMonthLength(int month, int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1024
      int[] newMonths = getAdjustedMonthLength(year);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1025
      return newMonths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1026
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1027
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1028
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1029
     * Returns year length.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1030
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1031
     * @param year  year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1032
     * @return year length
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1033
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1034
    int getYearLength(int year) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1035
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1036
        int cycleNumber = (year - 1) / 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1037
        int[] cycleYears;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1038
        try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1039
            cycleYears = ADJUSTED_CYCLE_YEARS.get(cycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1040
        } catch (ArrayIndexOutOfBoundsException e) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1041
            cycleYears = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1042
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1043
        if (cycleYears != null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1044
            int yearInCycle = (year - 1) % 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1045
            if (yearInCycle == 29) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1046
                return (int)(ADJUSTED_CYCLES[cycleNumber + 1]
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1047
                        - ADJUSTED_CYCLES[cycleNumber]
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1048
                        - cycleYears[yearInCycle]);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1049
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1050
            return cycleYears[yearInCycle + 1]
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1051
                    - cycleYears[yearInCycle];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1052
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1053
            return isLeapYear0(year) ? 355 : 354;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1054
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1055
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1056
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1057
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1058
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1059
     * Returns maximum day-of-month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1060
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1061
     * @return maximum day-of-month
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1062
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1063
    int getMaximumDayOfMonth() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1064
        return ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1065
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1066
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1067
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1068
     * Returns smallest maximum day-of-month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1069
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1070
     * @return smallest maximum day-of-month
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1071
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1072
    int getSmallestMaximumDayOfMonth() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1073
        return ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1074
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1075
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1076
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1077
     * Returns maximum day-of-year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1078
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1079
     * @return maximum day-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1080
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1081
    int getMaximumDayOfYear() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1082
        return ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1083
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1084
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1085
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1086
     * Returns smallest maximum day-of-year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1087
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1088
     * @return smallest maximum day-of-year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1089
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1090
    int getSmallestMaximumDayOfYear() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1091
        return ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1092
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1093
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1094
    // ----- Deviation handling -----//
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1095
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1096
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1097
     * Adds deviation definition. The year and month specified should be the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1098
     * calculated Hijrah year and month. The month is 1 based. e.g. 9 for
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1099
     * Ramadan (9th month) Addition of anything minus deviation days is
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1100
     * calculated negatively in the case the user wants to subtract days from
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1101
     * the calendar. For example, adding -1 days will subtract one day from the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1102
     * current date.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1103
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1104
     * @param startYear  start year, 1 origin
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1105
     * @param startMonth  start month, 1 origin
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1106
     * @param endYear  end year, 1 origin
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1107
     * @param endMonth  end month, 1 origin
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1108
     * @param offset  offset -2, -1, +1, +2
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1109
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1110
    private void addDeviationAsHijrah(Deviation entry) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1111
        int startYear = entry.startYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1112
        int startMonth = entry.startMonth - 1 ;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1113
        int endYear = entry.endYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1114
        int endMonth = entry.endMonth - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1115
        int offset = entry.offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1116
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1117
        if (startYear < 1) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1118
            throw new IllegalArgumentException("startYear < 1");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1119
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1120
        if (endYear < 1) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1121
            throw new IllegalArgumentException("endYear < 1");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1122
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1123
        if (startMonth < 0 || startMonth > 11) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1124
            throw new IllegalArgumentException(
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1125
                    "startMonth < 0 || startMonth > 11");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1126
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1127
        if (endMonth < 0 || endMonth > 11) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1128
            throw new IllegalArgumentException("endMonth < 0 || endMonth > 11");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1129
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1130
        if (endYear > 9999) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1131
            throw new IllegalArgumentException("endYear > 9999");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1132
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1133
        if (endYear < startYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1134
            throw new IllegalArgumentException("startYear > endYear");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1135
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1136
        if (endYear == startYear && endMonth < startMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1137
            throw new IllegalArgumentException(
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1138
                    "startYear == endYear && endMonth < startMonth");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1139
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1140
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1141
        // Adjusting start year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1142
        boolean isStartYLeap = isLeapYear0(startYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1143
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1144
        // Adjusting the number of month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1145
        int[] orgStartMonthNums = ADJUSTED_MONTH_DAYS.get(startYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1146
        if (orgStartMonthNums == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1147
            if (isStartYLeap) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1148
                orgStartMonthNums = Arrays.copyOf(LEAP_NUM_DAYS, LEAP_NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1149
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1150
                orgStartMonthNums = Arrays.copyOf(NUM_DAYS, NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1151
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1152
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1153
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1154
        int[] newStartMonthNums = new int[orgStartMonthNums.length];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1155
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1156
        for (int month = 0; month < 12; month++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1157
            if (month > startMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1158
                newStartMonthNums[month] = (orgStartMonthNums[month] - offset);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1159
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1160
                newStartMonthNums[month] = (orgStartMonthNums[month]);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1161
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1162
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1163
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1164
        ADJUSTED_MONTH_DAYS.put(startYear, newStartMonthNums);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1165
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1166
        // Adjusting the days of month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1167
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1168
        int[] orgStartMonthLengths = ADJUSTED_MONTH_LENGTHS.get(startYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1169
        if (orgStartMonthLengths == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1170
            if (isStartYLeap) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1171
                orgStartMonthLengths = Arrays.copyOf(LEAP_MONTH_LENGTH, LEAP_MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1172
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1173
                orgStartMonthLengths = Arrays.copyOf(MONTH_LENGTH, MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1174
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1175
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1176
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1177
        int[] newStartMonthLengths = new int[orgStartMonthLengths.length];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1178
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1179
        for (int month = 0; month < 12; month++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1180
            if (month == startMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1181
                newStartMonthLengths[month] = orgStartMonthLengths[month] - offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1182
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1183
                newStartMonthLengths[month] = orgStartMonthLengths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1184
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1185
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1186
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1187
        ADJUSTED_MONTH_LENGTHS.put(startYear, newStartMonthLengths);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1188
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1189
        if (startYear != endYear) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1190
            // System.out.println("over year");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1191
            // Adjusting starting 30 year cycle.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1192
            int sCycleNumber = (startYear - 1) / 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1193
            int sYearInCycle = (startYear - 1) % 30; // 0-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1194
            int[] startCycles = ADJUSTED_CYCLE_YEARS.get(sCycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1195
            if (startCycles == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1196
                startCycles = Arrays.copyOf(CYCLEYEAR_START_DATE, CYCLEYEAR_START_DATE.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1197
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1198
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1199
            for (int j = sYearInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1200
                startCycles[j] = startCycles[j] - offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1201
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1202
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1203
            // System.out.println(sCycleNumber + ":" + sYearInCycle);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1204
            ADJUSTED_CYCLE_YEARS.put(sCycleNumber, startCycles);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1205
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1206
            int sYearInMaxY = (startYear - 1) / 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1207
            int sEndInMaxY = (endYear - 1) / 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1208
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1209
            if (sYearInMaxY != sEndInMaxY) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1210
                // System.out.println("over 30");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1211
                // Adjusting starting 30 * MAX_ADJUSTED_CYCLE year cycle.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1212
                // System.out.println(sYearInMaxY);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1213
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1214
                for (int j = sYearInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1215
                    ADJUSTED_CYCLES[j] = ADJUSTED_CYCLES[j] - offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1216
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1217
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1218
                // Adjusting ending 30 * MAX_ADJUSTED_CYCLE year cycles.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1219
                for (int j = sEndInMaxY + 1; j < ADJUSTED_CYCLES.length; j++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1220
                    ADJUSTED_CYCLES[j] = ADJUSTED_CYCLES[j] + offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1221
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1222
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1223
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1224
            // Adjusting ending 30 year cycle.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1225
            int eCycleNumber = (endYear - 1) / 30;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1226
            int sEndInCycle = (endYear - 1) % 30; // 0-based.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1227
            int[] endCycles = ADJUSTED_CYCLE_YEARS.get(eCycleNumber);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1228
            if (endCycles == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1229
                endCycles = Arrays.copyOf(CYCLEYEAR_START_DATE, CYCLEYEAR_START_DATE.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1230
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1231
            for (int j = sEndInCycle + 1; j < CYCLEYEAR_START_DATE.length; j++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1232
                endCycles[j] = endCycles[j] + offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1233
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1234
            ADJUSTED_CYCLE_YEARS.put(eCycleNumber, endCycles);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1235
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1236
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1237
        // Adjusting ending year.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1238
        boolean isEndYLeap = isLeapYear0(endYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1239
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1240
        int[] orgEndMonthDays = ADJUSTED_MONTH_DAYS.get(endYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1241
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1242
        if (orgEndMonthDays == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1243
            if (isEndYLeap) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1244
                orgEndMonthDays = Arrays.copyOf(LEAP_NUM_DAYS, LEAP_NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1245
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1246
                orgEndMonthDays = Arrays.copyOf(NUM_DAYS, NUM_DAYS.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1247
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1248
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1249
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1250
        int[] newEndMonthDays = new int[orgEndMonthDays.length];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1251
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1252
        for (int month = 0; month < 12; month++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1253
            if (month > endMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1254
                newEndMonthDays[month] = orgEndMonthDays[month] + offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1255
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1256
                newEndMonthDays[month] = orgEndMonthDays[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1257
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1258
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1259
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1260
        ADJUSTED_MONTH_DAYS.put(endYear, newEndMonthDays);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1261
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1262
        // Adjusting the days of month.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1263
        int[] orgEndMonthLengths = ADJUSTED_MONTH_LENGTHS.get(endYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1264
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1265
        if (orgEndMonthLengths == null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1266
            if (isEndYLeap) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1267
                orgEndMonthLengths = Arrays.copyOf(LEAP_MONTH_LENGTH, LEAP_MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1268
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1269
                orgEndMonthLengths = Arrays.copyOf(MONTH_LENGTH, MONTH_LENGTH.length);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1270
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1271
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1272
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1273
        int[] newEndMonthLengths = new int[orgEndMonthLengths.length];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1274
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1275
        for (int month = 0; month < 12; month++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1276
            if (month == endMonth) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1277
                newEndMonthLengths[month] = orgEndMonthLengths[month] + offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1278
            } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1279
                newEndMonthLengths[month] = orgEndMonthLengths[month];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1280
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1281
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1282
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1283
        ADJUSTED_MONTH_LENGTHS.put(endYear, newEndMonthLengths);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1284
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1285
        int[] startMonthLengths = ADJUSTED_MONTH_LENGTHS.get(startYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1286
        int[] endMonthLengths = ADJUSTED_MONTH_LENGTHS.get(endYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1287
        int[] startMonthDays = ADJUSTED_MONTH_DAYS.get(startYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1288
        int[] endMonthDays = ADJUSTED_MONTH_DAYS.get(endYear);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1289
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1290
        int startMonthLength = startMonthLengths[startMonth];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1291
        int endMonthLength = endMonthLengths[endMonth];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1292
        int startMonthDay = startMonthDays[11] + startMonthLengths[11];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1293
        int endMonthDay = endMonthDays[11] + endMonthLengths[11];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1294
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1295
        int maxMonthLength = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1296
        int leastMaxMonthLength = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1297
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1298
        if (maxMonthLength < startMonthLength) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1299
            maxMonthLength = startMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1300
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1301
        if (maxMonthLength < endMonthLength) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1302
            maxMonthLength = endMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1303
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1304
        ADJUSTED_MAX_VALUES[POSITION_DAY_OF_MONTH] = maxMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1305
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1306
        if (leastMaxMonthLength > startMonthLength) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1307
            leastMaxMonthLength = startMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1308
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1309
        if (leastMaxMonthLength > endMonthLength) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1310
            leastMaxMonthLength = endMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1311
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1312
        ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_MONTH] = leastMaxMonthLength;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1313
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1314
        int maxMonthDay = ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1315
        int leastMaxMonthDay = ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1316
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1317
        if (maxMonthDay < startMonthDay) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1318
            maxMonthDay = startMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1319
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1320
        if (maxMonthDay < endMonthDay) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1321
            maxMonthDay = endMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1322
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1323
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1324
        ADJUSTED_MAX_VALUES[POSITION_DAY_OF_YEAR] = maxMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1325
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1326
        if (leastMaxMonthDay > startMonthDay) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1327
            leastMaxMonthDay = startMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1328
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1329
        if (leastMaxMonthDay > endMonthDay) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1330
            leastMaxMonthDay = endMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1331
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1332
        ADJUSTED_LEAST_MAX_VALUES[POSITION_DAY_OF_YEAR] = leastMaxMonthDay;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1333
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1334
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1335
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1336
     * Package private Entry for suppling deviations from the Reader.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1337
     * Each entry consists of a range using the Hijrah calendar,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1338
     * start year, month, end year, end month, and an offset.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1339
     * The offset is used to modify the length of the month +2, +1, -1, -2.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1340
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1341
    static final class Deviation {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1342
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1343
        Deviation(int startYear, int startMonth, int endYear, int endMonth, int offset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1344
            this.startYear = startYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1345
            this.startMonth = startMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1346
            this.endYear = endYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1347
            this.endMonth = endMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1348
            this.offset = offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1349
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1350
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1351
        final int startYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1352
        final int startMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1353
        final int endYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1354
        final int endMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1355
        final int offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1356
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1357
        int getStartYear() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1358
            return startYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1359
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1360
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1361
        int getStartMonth() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1362
            return startMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1363
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1364
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1365
        int getEndYear() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1366
            return endYear;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1367
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1368
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1369
        int getEndMonth() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1370
            return endMonth;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1371
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1372
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1373
        int getOffset() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1374
            return offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1375
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1376
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1377
        @Override
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1378
        public String toString() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1379
            return String.format("[year: %4d, month: %2d, offset: %+d]", startYear, startMonth, offset);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1380
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1381
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1382
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents:
diff changeset
  1383
}