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, int epochDay) { 035 super(epochYear, epochMonth, epochDay); 036 } 037 038 public String toString() { 039 return "TestGregorianChronology"; 040 } 041 042 long millisPerYear() { 043 return (long)(365.2425 * MILLIS_PER_DAY); 044 } 045 046 long millisPerMonth() { 047 return (long)(365.2425 * MILLIS_PER_DAY / 12); 048 } 049 050 boolean isLeapYear(int year) { 051 if (mod(year, 4) == 0) { 052 int t = (int)mod(year, 400); 053 if (t != 100 && t != 200 && t != 300) { 054 return true; 055 } 056 } 057 return false; 058 } 059 060 /** 061 * @return days from 0001-01-01 062 */ 063 long fixedFromGJ(int year, int monthOfYear, int dayOfMonth) { 064 long year_m1 = year - 1; 065 long f = 365 * year_m1 + div(year_m1, 4) - div(year_m1, 100) 066 + div(year_m1, 400) + div(367 * monthOfYear - 362, 12) + dayOfMonth; 067 if (monthOfYear > 2) { 068 f += isLeapYear(year) ? -1 : -2; 069 } 070 return f; 071 } 072 073 /** 074 * @param date days from 0001-01-01 075 * @return gj year 076 */ 077 int gjYearFromFixed(long date) { 078 long d0 = date - 1; 079 long n400 = div(d0, 146097); 080 long d1 = mod(d0, 146097); 081 long n100 = div(d1, 36524); 082 long d2 = mod(d1, 36524); 083 long n4 = div(d2, 1461); 084 long d3 = mod(d2, 1461); 085 long n1 = div(d3, 365); 086 long year = 400 * n400 + 100 * n100 + 4 * n4 + n1; 087 if (!(n100 == 4 || n1 == 4)) { 088 year += 1; 089 } 090 091 int year_i = (int)year; 092 if (year_i == year) { 093 return year_i; 094 } else { 095 throw new RuntimeException("year cannot be cast to an int: " + year); 096 } 097 } 098 099 /** 100 * @param date days from 0001-01-01 101 * @return gj year, monthOfYear, dayOfMonth 102 */ 103 int[] gjFromFixed(long date) { 104 int year = gjYearFromFixed(date); 105 long priorDays = date - fixedFromGJ(year, 1, 1); 106 long correction; 107 if (date < fixedFromGJ(year, 3, 1)) { 108 correction = 0; 109 } else if (isLeapYear(year)) { 110 correction = 1; 111 } else { 112 correction = 2; 113 } 114 int monthOfYear = (int)div(12 * (priorDays + correction) + 373, 367); 115 int day = (int)(date - fixedFromGJ(year, monthOfYear, 1) + 1); 116 117 return new int[]{year, monthOfYear, day}; 118 } 119 120 long fixedFromISO(int weekyear, int weekOfWeekyear, int dayOfWeek) { 121 return nthWeekday(weekOfWeekyear, 0, weekyear - 1, 12, 28) + dayOfWeek; 122 } 123 124 /** 125 * @param date days from 0001-01-01 126 * @return iso weekyear, weekOfWeekyear, dayOfWeek (1=Monday to 7) 127 */ 128 int[] isoFromFixed(long date) { 129 int weekyear = gjYearFromFixed(date - 3); 130 if (date >= fixedFromISO(weekyear + 1, 1, 1)) { 131 weekyear += 1; 132 } 133 int weekOfWeekyear = (int)(div(date - fixedFromISO(weekyear, 1, 1), 7) + 1); 134 int dayOfWeek = (int)amod(date, 7); 135 return new int[]{weekyear, weekOfWeekyear, dayOfWeek}; 136 } 137 }