<?php

//  #######################################################################
//	$Id: CalDate.inc,v 1.4 2005/10/06 17:55:04 hiram Exp $

//  #######################################################################
//	CalDate - pass in a pointer to a UTInstant
//	which has its julian decimal date set.  This routine
//	will calculate and set all the other elements of the
//	hash.  As a convenience, it will also return the year,
//	an integer.
//

function CalDate($date) {

//		These locals are all integers except for $frac
//	$jd, $ka, $kb, $kc, $kd, $ke, $ialp, $frac);
//		Thus, to be safe, we will cat (int) around all calculations
//		that should result in (int)

	$jd = (int)($date['J_DATE'] + 0.5);	// integer julian date
	$frac = $date['J_DATE'] + 0.5 - $jd + 1.0e-10; // fraction of day
	$ka = (int)($jd);
	
	if ( $jd >= 2299161 ) {
		$ialp = (int)(( $jd - 1867216.25 ) / ( 36524.25 ));
		$ka = (int)($jd + 1 + $ialp - ( $ialp >> 2 ));
	}
	$kb = (int)($ka + 1524);
	$kc = (int)(( $kb - 122.1 ) / 365.25);
	$kd = (int)($kc * 365.25);
	$ke = (int)(( $kb - $kd ) / 30.6001);

	$date['DAY'] = $kb - $kd - (int)( $ke * 30.6001 );

	if ( $ke > 13 ) {	$date['MONTH'] = (int)($ke - 13); }
	else {		$date['MONTH'] = (int)($ke - 1); }

	if ( ($date['MONTH'] == 2) && ($date['DAY'] > 28) ) {
		$date['DAY'] = 29;
	}

	if ( ($date['MONTH'] == 2) && ($date['DAY'] == 29) && ($ke == 3) ){
					 $date['YEAR'] = (int)($kc - 4716);
	} elseif ( $date['MONTH'] > 2 ) { $date['YEAR'] = (int)($kc - 4716);
	} else {			 $date['YEAR'] = (int)($kc - 4715); }

	$date['D_HOUR'] = $frac * 24.0;	//  d_hour includes min, sec as fraction
	$date['HOUR'] = (int)($date['D_HOUR']);	//	integer hour
	$date['D_MINUTE'] =		//  d_minute includes sec as fraction
		( $date['D_HOUR'] - $date['HOUR'] ) * 60.0;
	$date['MINUTE'] = (int)($date['D_MINUTE']);	//	integer minute
	$date['SECOND'] =		//  float second, int() it if you want
		( $date['D_MINUTE'] - $date['MINUTE'] ) * 60.0;
	$date['WEEKDAY'] = (int)(($jd + 1) % 7);	//	day of week
	if ( $date['YEAR'] == (($date['YEAR'] >> 2) << 2) ) {
		$date['DAY_OF_YEAR'] =
			(int)( ( 275 * $date['MONTH'] ) / 9)
			- (int)(($date['MONTH'] + 9) / 12)
			+ $date['DAY'] - 30;
	} else {
		$date['DAY_OF_YEAR'] =
			(int)( ( 275 * $date['MONTH']) / 9)
			- ((($date['MONTH'] + 9) / 12) << 1)
			+ $date['DAY'] - 30;
	}
	return( $date['YEAR'] );
}	//	end of	 int CalDate( date )

//###########################################################################
//
//	JulDate - computes the julian decimal date from
//		the gregorian (or Julian) calendar date.
//	for astronomical purposes, The Gregorian calendar reform occurred
//	on 15 Oct. 1582.  This is 05 Oct 1582 by the julian calendar.
//
//	Single argument input: pointer to a hash that is a UTInstant
//		The elements that must be set are:
//		YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
//		(if they have not been set, they appear as zero here)
//
//	Output result will be the setting of the UTInstant elements:
//		J_DATE, D_HOUR, D_MINUTE, WEEKDAY, DAY_OF_YEAR
//		and for convenience, the J_DATE value will be returned.
//
//	Reference: Astronomial formulae for calculators, meeus, p 23
//	from fortran program by F. Espenak - April 1982 Page 276,
//	50 Year canon of solar eclipses: 1986-2035
//

function JulDate($date) {
//		These locals are all integers except for $frac and $gyr
//	$iy0, $im0, $ia, $ib, $jd, $frac, $gyr
//		Thus, to be safer, we will use int() around all calculations
//			for the integers

//	the fraction of a day

	$frac = ($date['HOUR']/ 24.0)
		+ ($date['MINUTE'] / 1440.0)
		+ ($date['SECOND'] / 86400.0);

//	convert the cal date to format YYYY.MMDDdd
	$gyr = $date['YEAR']
		+ (0.01 * $date['MONTH'])
		+ (0.0001 * $date['DAY'])
		+ (0.0001 * $frac) + 1.0e-9;

//	conversion factors
	if ( $date['MONTH'] <= 2 ) {
		$iy0 = (int)($date['YEAR'] - 1);
		$im0 = (int)($date['MONTH'] + 12);
	} else {
		$iy0 = (int)($date['YEAR']);
		$im0 = (int)($date['MONTH']);
	}

	$ia = (int)($iy0 / 100);
	$ib = (int)(2 - $ia + ($ia >> 2));
//	calculate julian date
	if ( $date['YEAR'] <= 0 ) {
		$jd = (int)( (365.25 * $iy0) - 0.75 )
			+ (int)( (30.6001 * ($im0 + 1) ) )
			+ (int)( $date['DAY'] + 1720994 );
	} else {
		$jd = (int)(365.25 * $iy0)
			+ (int)( 30.6001 * ($im0 + 1) )
			+ (int)( $date['DAY'] + 1720994 );
	}
	if ( $gyr >= 1582.1015 ) {	//	on or after 15 October 1582
		$jd += $ib;
	}
	$date['J_DATE'] = $jd + $frac + 0.5;
	$jd = (int)( $date['J_DATE'] + 0.5 );
	$date['WEEKDAY'] = (int)( ($jd + 1) % 7 );
	return( $date['J_DATE'] );
}	//	end of	JulDate

// ########################################################################
//	FormatCalDate - pass in a pointer to a UTInstant
//	Will format and return a string in standard format:
//	YYYY/MM/DD HH:MM:SS
function FormatCalDate($t) {

	return(sprintf("%d/%02d/%02d %02d:%02d:%02d",
		$t['YEAR'], $t['MONTH'], $t['DAY'], $t['HOUR'],
		$t['MINUTE'], (int)($t['SECOND'] + 0.5)) );
}

?>
