MeeusDateUtil.java
/**
* VStar: a statistical analysis tool for variable star data.
* Copyright (C) 2009 AAVSO (http://www.aavso.org/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.aavso.tools.vstar.util.date;
/**
* This class implements AbstractDateUtil methods using Jean Meeus's
* Astronomical Algorithms 1991, 1st edition, chapter 7.
*/
public class MeeusDateUtil extends AbstractDateUtil {
/**
* Method to convert the integer part of a JD into an ISO-8601 calendar date.
*
* This method determines the Calendar day given the Julian Day. It is not valid
* for negative Julian Days (but is valid for negative year results).
*
* @param jd Julian Day (double)
* @return calendar date string of the form "YYYY-MM-DD" (ISO-8601 format)
*/
public String jdToCalendar(double jd) throws IllegalArgumentException {
YMD ymd = jdToYMD(jd);
StringBuffer yyyymmddBuf = new StringBuffer();
yyyymmddBuf.append(ymd.getYear());
yyyymmddBuf.append("-");
int month = ymd.getMonth();
if (month < 10) yyyymmddBuf.append("0");
yyyymmddBuf.append(month);
yyyymmddBuf.append("-");
int day = (int) ymd.getDay();
if (day < 10) yyyymmddBuf.append("0");
yyyymmddBuf.append(day);
return yyyymmddBuf.toString();
}
/**
* Method to convert the integer part of a JD into a calendar date.
*
* This method determines the Calendar day given the Julian Day. It is not valid
* for negative Julian Days (but is valid for negative year results).
*
* @param jd Julian Day (double)
* @return structure of the form year, month, day
*/
public YMD jdToYMD(double jd) throws IllegalArgumentException {
jd += 0.5;
int z = (int) jd;
double f = jd - z;
int a;
if (z < 2299161) {
a = z;
} else {
int alpha = (int) ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - (int) (alpha / 4);
}
int b = a + 1524;
int c = (int) ((b - 122.1) / 365.25);
int d = (int) (365.25 * c);
int e = (int) ((b - d) / 30.6001);
double day = b - d - (int) (30.6001 * e) + f;
int month;
if (e < 14) {
month = e - 1;
} else if (e == 14 || e == 15) {
month = e - 13;
} else {
throw new IllegalArgumentException("Unable to convert Julian Day '" + jd + "'");
}
int year;
if (month > 2) {
year = c - 4716;
} else if (month == 1 || month == 2) {
year = c - 4715;
} else {
throw new IllegalArgumentException("Unable to convert Julian Day '" + jd + "'");
}
return new YMD(year, month, day);
}
/**
* Method to convert the Julian Day corresponding to the specified year, month,
* and day.
*
* The method determines the Julian Day for any year, including dates prior to
* the start of the Gregorian Calendar. It is not valid for negative Julian Day
* results (but is valid for negative years).
*
* @param year The year.
* @param month The month (1..12).
* @param day The day which may contain a fractional component.
* @return The Julian Day (double)
*/
public double calendarToJD(int year, int month, double day) throws IllegalArgumentException {
int a, b;
double jd;
if (month == 1 || month == 2) {
year--;
month += 12;
}
a = (int) (year / 100);
if (inGregorianCalendar((int) day, month, year)) {
b = 2 - a + (int) (a / 4);
} else {
b = 0;
}
jd = (int) (365.25 * (year + 4716)) + (int) (30.6001 * (month + 1)) + day + b - 1524.5;
return jd;
}
// Helpers
/**
* Is the specified date in the Gregorian Calendar which started the day after
* Oct 4 1582? This day was in fact Oct 15 1582.
*
* @param day The (integer) day.
* @param month The month (1..12).
* @param year The year.
*/
private boolean inGregorianCalendar(int day, int month, int year) {
if (year > 1582)
return true;
else if (year == 1582 && month > 10)
return true;
else if (year == 1582 && month == 10 && day >= 15)
return true;
else
return false;
}
}