/*
* Copyright 2001-2005 Stephen Colebourne
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.joda.time.chrono.gj;
/**
* A reference Gregorian chronology implementation, intended for testing
* purposes only. Correctness is favored over performance. The key functions
* for date calculations are based on ones provided in "Calendrical
* Calculations", ISBN 0-521-77752-6.
*
* @author Brian S O'Neill
*/
public final class TestGregorianChronology extends TestGJChronology {
/**
* Constructs with an epoch of 1970-01-01.
*/
public TestGregorianChronology() {
super(1970, 1, 1);
}
public TestGregorianChronology(int epochYear, int epochMonth, int epochDay) {
super(epochYear, epochMonth, epochDay);
}
public String toString() {
return "TestGregorianChronology";
}
long millisPerYear() {
return (long)(365.2425 * MILLIS_PER_DAY);
}
long millisPerMonth() {
return (long)(365.2425 * MILLIS_PER_DAY / 12);
}
boolean isLeapYear(int year) {
if (mod(year, 4) == 0) {
int t = (int)mod(year, 400);
if (t != 100 && t != 200 && t != 300) {
return true;
}
}
return false;
}
/**
* @return days from 0001-01-01
*/
long fixedFromGJ(int year, int monthOfYear, int dayOfMonth) {
long year_m1 = year - 1;
long f = 365 * year_m1 + div(year_m1, 4) - div(year_m1, 100)
+ div(year_m1, 400) + div(367 * monthOfYear - 362, 12) + dayOfMonth;
if (monthOfYear > 2) {
f += isLeapYear(year) ? -1 : -2;
}
return f;
}
/**
* @param date days from 0001-01-01
* @return gj year
*/
int gjYearFromFixed(long date) {
long d0 = date - 1;
long n400 = div(d0, 146097);
long d1 = mod(d0, 146097);
long n100 = div(d1, 36524);
long d2 = mod(d1, 36524);
long n4 = div(d2, 1461);
long d3 = mod(d2, 1461);
long n1 = div(d3, 365);
long year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
if (!(n100 == 4 || n1 == 4)) {
year += 1;
}
int year_i = (int)year;
if (year_i == year) {
return year_i;
} else {
throw new RuntimeException("year cannot be cast to an int: " + year);
}
}
/**
* @param date days from 0001-01-01
* @return gj year, monthOfYear, dayOfMonth
*/
int[] gjFromFixed(long date) {
int year = gjYearFromFixed(date);
long priorDays = date - fixedFromGJ(year, 1, 1);
long correction;
if (date < fixedFromGJ(year, 3, 1)) {
correction = 0;
} else if (isLeapYear(year)) {
correction = 1;
} else {
correction = 2;
}
int monthOfYear = (int)div(12 * (priorDays + correction) + 373, 367);
int day = (int)(date - fixedFromGJ(year, monthOfYear, 1) + 1);
return new int[]{year, monthOfYear, day};
}
long fixedFromISO(int weekyear, int weekOfWeekyear, int dayOfWeek) {
return nthWeekday(weekOfWeekyear, 0, weekyear - 1, 12, 28) + dayOfWeek;
}
/**
* @param date days from 0001-01-01
* @return iso weekyear, weekOfWeekyear, dayOfWeek (1=Monday to 7)
*/
int[] isoFromFixed(long date) {
int weekyear = gjYearFromFixed(date - 3);
if (date >= fixedFromISO(weekyear + 1, 1, 1)) {
weekyear += 1;
}
int weekOfWeekyear = (int)(div(date - fixedFromISO(weekyear, 1, 1), 7) + 1);
int dayOfWeek = (int)amod(date, 7);
return new int[]{weekyear, weekOfWeekyear, dayOfWeek};
}
}