Files
wavelog/predict/Predict/Time.php
2024-08-10 11:19:05 +02:00

230 lines
7.7 KiB
PHP

<?php
/*
* Functions from sgp_time.c and time-tools.c (except where noted)
* ported to PHP by Bill Shupp
*/
require_once realpath(__DIR__ . "/../Predict.php");
require_once realpath(__DIR__ . "/../Predict/Math.php");
/*
* Unit SGP_Time
* Author: Dr TS Kelso
* Original Version: 1992 Jun 02
* Current Revision: 2000 Jan 22
* Modified for Y2K: 1999 Mar 07
* Version: 2.05
* Copyright: 1992-1999, All Rights Reserved
* Version 1.50 added Y2K support. Due to limitations in the current
* format of the NORAD two-line element sets, however, only dates
* through 2056 December 31/2359 UTC are valid.
* Version 1.60 modifies Calendar_Date to ensure date matches time
* resolution and modifies Time_of_Day to make it more robust.
* Version 2.00 adds Julian_Date, Date_Time, and Check_Date to support
* checking for valid date/times, permitting the use of Time_to_UTC and
* Time_from_UTC for UTC/local time conversions.
* Version 2.05 modifies UTC_offset to allow non-integer offsets.
*
* Ported to C by: Neoklis Kyriazis April 9 2001
*/
class Predict_Time
{
/* The function Julian_Date_of_Epoch returns the Julian Date of */
/* an epoch specified in the format used in the NORAD two-line */
/* element sets. It has been modified to support dates beyond */
/* the year 1999 assuming that two-digit years in the range 00-56 */
/* correspond to 2000-2056. Until the two-line element set format */
/* is changed, it is only valid for dates through 2056 December 31. */
public static function Julian_Date_of_Epoch($epoch)
{
$year = 0;
/* Modification to support Y2K */
/* Valid 1957 through 2056 */
$day = self::modf($epoch * 1E-3, $year) * 1E3;
if ($year < 57) {
$year = $year + 2000;
} else {
$year = $year + 1900;
}
/* End modification */
return self::Julian_Date_of_Year($year) + $day;
}
/* Equivalent to the C modf function */
public static function modf($x, &$ipart) {
$ipart = (int)$x;
return $x - $ipart;
}
/* The function Julian_Date_of_Year calculates the Julian Date */
/* of Day 0.0 of {year}. This function is used to calculate the */
/* Julian Date of any date by using Julian_Date_of_Year, DOY, */
/* and Fraction_of_Day. */
public static function Julian_Date_of_Year($year)
{
/* Astronomical Formulae for Calculators, Jean Meeus, */
/* pages 23-25. Calculate Julian Date of 0.0 Jan year */
$year = $year - 1;
$i = (int) ($year / 100);
$A = $i;
$i = (int) ($A / 4);
$B = (int) (2 - $A + $i);
$i = (int) (365.25 * $year);
$i += (int) (30.6001 * 14);
$jdoy = $i + 1720994.5 + $B;
return $jdoy;
}
/* The function ThetaG calculates the Greenwich Mean Sidereal Time */
/* for an epoch specified in the format used in the NORAD two-line */
/* element sets. It has now been adapted for dates beyond the year */
/* 1999, as described above. The function ThetaG_JD provides the */
/* same calculation except that it is based on an input in the */
/* form of a Julian Date. */
public static function ThetaG($epoch, Predict_DeepArg $deep_arg)
{
/* Reference: The 1992 Astronomical Almanac, page B6. */
// double year,day,UT,jd,TU,GMST,_ThetaG;
/* Modification to support Y2K */
/* Valid 1957 through 2056 */
$year = 0;
$day = self::modf($epoch * 1E-3, $year) * 1E3;
if ($year < 57) {
$year += 2000;
} else {
$year += 1900;
}
/* End modification */
$UT = fmod($day, $day);
$jd = self::Julian_Date_of_Year($year) + $day;
$TU = ($jd - 2451545.0) / 36525;
$GMST = 24110.54841 + $TU * (8640184.812866 + $TU * (0.093104 - $TU * 6.2E-6));
$GMST = Predict_Math::Modulus($GMST + Predict::secday * Predict::omega_E * $UT, Predict::secday);
$deep_arg->ds50 = $jd - 2433281.5 + $UT;
return Predict_Math::FMod2p(6.3003880987 * $deep_arg->ds50 + 1.72944494);
}
/* See the ThetaG doc block above */
public static function ThetaG_JD($jd)
{
/* Reference: The 1992 Astronomical Almanac, page B6. */
$UT = Predict_Math::Frac($jd + 0.5);
$jd = $jd - $UT;
$TU = ($jd - 2451545.0) / 36525;
$GMST = 24110.54841 + $TU * (8640184.812866 + $TU * (0.093104 - $TU * 6.2E-6));
$GMST = Predict_Math::Modulus($GMST + Predict::secday * Predict::omega_E * $UT, Predict::secday);
return Predict::twopi * $GMST / Predict::secday;
}
/**
* Read the system clock and return the current Julian day. From phpPredict
*
* @return float
*/
public static function get_current_daynum() {
// Gets the current decimal day number from microtime
list($usec, $sec) = explode(' ', microtime());
return self::unix2daynum($sec, $usec);
}
/**
* Converts a standard unix timestamp and optional
* milliseconds to a daynum
*
* @param int $sec Seconds from the unix epoch
* @param int $usec Optional milliseconds
*
* @return float
*/
public static function unix2daynum($sec, $usec = 0)
{
$time = ((($sec + $usec) / 86400.0) - 3651.0);
return $time + 2444238.5;
}
/* The function Delta_ET has been added to allow calculations on */
/* the position of the sun. It provides the difference between UT */
/* (approximately the same as UTC) and ET (now referred to as TDT).*/
/* This function is based on a least squares fit of data from 1950 */
/* to 1991 and will need to be updated periodically. */
public static function Delta_ET($year)
{
/* Values determined using data from 1950-1991 in the 1990
Astronomical Almanac. See DELTA_ET.WQ1 for details. */
$delta_et = 26.465 + 0.747622 * ($year - 1950) +
1.886913 * sin(Predict::twopi * ($year - 1975) / 33);
return $delta_et;
}
/**
* Converts a daynum to a unix timestamp. From phpPredict.
*
* @param float $dn Julian Daynum
*
* @return float
*/
public static function daynum2unix($dn) {
// Converts a daynum to a UNIX timestamp
return (86400.0 * ($dn - 2444238.5 + 3651.0));
}
/**
* Converts a daynum to a readable time format.
*
* @param float $dn The julian date
* @param float $offset Offset in hours compared to UTC
* @param string $format The date() function's format string. Defaults to m-d-Y H:i:s
*
* @return string
*/
public static function daynum2readable($dn, $offset = 0.0, $format = 'm-d-Y H:i:s')
{
// Calc the unix timestamp
$unix = self::daynum2unix($dn);
// Create a DateTime object based on the unix timestamp
$date = new DateTime("@" . round($unix));
// Use the offset to adjust the time
$secondsOffset = $offset * 3600;
$date->modify("$secondsOffset seconds");
// Format and return the date
return $date->format($format);
}
/**
* Returns the unix timestamp of a TLE's epoch
*
* @param Predict_TLE $tle The TLE object
*
* @return int
*/
public static function getEpochTimeStamp(Predict_TLE $tle)
{
$year = $tle->epoch_year;
$day = $tle->epoch_day;
$sec = round(86400 * $tle->epoch_fod);
$zone = new DateTimeZone('UTC');
$date = new DateTime();
$date->setTimezone($zone);
$date->setDate($year, 1, 1);
$date->setTime(0, 0, 0);
return $date->format('U') + (86400 * $day) + $sec - 86400;
}
}