001: /*
002: * Copyright 2001-2005 Stephen Colebourne
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.joda.time.chrono.gj;
017:
018: /**
019: * A reference Gregorian chronology implementation, intended for testing
020: * purposes only. Correctness is favored over performance. The key functions
021: * for date calculations are based on ones provided in "Calendrical
022: * Calculations", ISBN 0-521-77752-6.
023: *
024: * @author Brian S O'Neill
025: */
026: public final class TestGregorianChronology extends TestGJChronology {
027: /**
028: * Constructs with an epoch of 1970-01-01.
029: */
030: public TestGregorianChronology() {
031: super (1970, 1, 1);
032: }
033:
034: public TestGregorianChronology(int epochYear, int epochMonth,
035: int epochDay) {
036: super (epochYear, epochMonth, epochDay);
037: }
038:
039: public String toString() {
040: return "TestGregorianChronology";
041: }
042:
043: long millisPerYear() {
044: return (long) (365.2425 * MILLIS_PER_DAY);
045: }
046:
047: long millisPerMonth() {
048: return (long) (365.2425 * MILLIS_PER_DAY / 12);
049: }
050:
051: boolean isLeapYear(int year) {
052: if (mod(year, 4) == 0) {
053: int t = (int) mod(year, 400);
054: if (t != 100 && t != 200 && t != 300) {
055: return true;
056: }
057: }
058: return false;
059: }
060:
061: /**
062: * @return days from 0001-01-01
063: */
064: long fixedFromGJ(int year, int monthOfYear, int dayOfMonth) {
065: long year_m1 = year - 1;
066: long f = 365 * year_m1 + div(year_m1, 4) - div(year_m1, 100)
067: + div(year_m1, 400) + div(367 * monthOfYear - 362, 12)
068: + dayOfMonth;
069: if (monthOfYear > 2) {
070: f += isLeapYear(year) ? -1 : -2;
071: }
072: return f;
073: }
074:
075: /**
076: * @param date days from 0001-01-01
077: * @return gj year
078: */
079: int gjYearFromFixed(long date) {
080: long d0 = date - 1;
081: long n400 = div(d0, 146097);
082: long d1 = mod(d0, 146097);
083: long n100 = div(d1, 36524);
084: long d2 = mod(d1, 36524);
085: long n4 = div(d2, 1461);
086: long d3 = mod(d2, 1461);
087: long n1 = div(d3, 365);
088: long year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
089: if (!(n100 == 4 || n1 == 4)) {
090: year += 1;
091: }
092:
093: int year_i = (int) year;
094: if (year_i == year) {
095: return year_i;
096: } else {
097: throw new RuntimeException(
098: "year cannot be cast to an int: " + year);
099: }
100: }
101:
102: /**
103: * @param date days from 0001-01-01
104: * @return gj year, monthOfYear, dayOfMonth
105: */
106: int[] gjFromFixed(long date) {
107: int year = gjYearFromFixed(date);
108: long priorDays = date - fixedFromGJ(year, 1, 1);
109: long correction;
110: if (date < fixedFromGJ(year, 3, 1)) {
111: correction = 0;
112: } else if (isLeapYear(year)) {
113: correction = 1;
114: } else {
115: correction = 2;
116: }
117: int monthOfYear = (int) div(
118: 12 * (priorDays + correction) + 373, 367);
119: int day = (int) (date - fixedFromGJ(year, monthOfYear, 1) + 1);
120:
121: return new int[] { year, monthOfYear, day };
122: }
123:
124: long fixedFromISO(int weekyear, int weekOfWeekyear, int dayOfWeek) {
125: return nthWeekday(weekOfWeekyear, 0, weekyear - 1, 12, 28)
126: + dayOfWeek;
127: }
128:
129: /**
130: * @param date days from 0001-01-01
131: * @return iso weekyear, weekOfWeekyear, dayOfWeek (1=Monday to 7)
132: */
133: int[] isoFromFixed(long date) {
134: int weekyear = gjYearFromFixed(date - 3);
135: if (date >= fixedFromISO(weekyear + 1, 1, 1)) {
136: weekyear += 1;
137: }
138: int weekOfWeekyear = (int) (div(date
139: - fixedFromISO(weekyear, 1, 1), 7) + 1);
140: int dayOfWeek = (int) amod(date, 7);
141: return new int[] { weekyear, weekOfWeekyear, dayOfWeek };
142: }
143: }
|