[fpc-pascal] convert "epoch" to UTC

Mark Morgan Lloyd markMLl.fpc-pascal at telemetry.co.uk
Mon Jan 16 19:38:56 CET 2012


waldo kitty wrote:

> i think i might be able to do something with the JulianToDateTime once i 
> get the base year portion converted to a true julian... i spotted some 
> C# code while doing a bit of research earlier (see below)... it appears 
> to convert the year to a julian year and then add the decimal day 
> portion... this should then be a proper julian date which i should be 
> able to handle ;)

Don't know whether any of this will help

If this is any use...

FUNCTION CalcJD(year, month, day: INTEGER): DOUBLE;

//***********************************************************************/
//* Name:    CalcJD                                                     */
//* Type:    Function                                                   */
//* Purpose: Julian day from calendar day                               */
//* Arguments:                                                          */
//*   year : 4 digit year                                               */
//*   month: January = 1                                                */
//*   day  : 1 - 31                                                     */
//* Return value:                                                       */
//*   The Julian day corresponding to the date                          */
//* Note:                                                               */
//*   Number is returned for start of day.  Fractional days should be   */
//*   added later.                                                      */
//***********************************************************************/

VAR     A, B: INTEGER;
         JD: DOUBLE;

BEGIN
   IF month <= 2 THEN BEGIN
     year -= 1;
     month += 12
   END;
   A:= Floor(year / 100);
   B:= 2 - A + Floor(A / 4);
   JD:= Floor(365.25 * (year + 4716)) + Floor(30.6001 * (month + 1)) + 
day + B - 1524.5;
   RESULT:= JD
END { CalcJD } ;

That was derived from some calculations published by NOAA, it's actually 
sunrise/sunset times and I transcribed it from Javascript a few months 
ago and which appeared to test OK.

Also

FUNCTION jTime(t: Int64): DOUBLE;

// jtime - convert internal date and time to astronomical Julian
// time (i.e. Julian date plus day fraction)

BEGIN
   RESULT:= t;
   RESULT:= (RESULT / 86400.0) + 2440587.5       // (seconds /(seconds 
per day)) + julian date of epoch
END { jTime } ;


FUNCTION jDayToSecs(jday: DOUBLE): Int64;

// jdaytosecs - convert Julian date to a UNIX epoch

BEGIN
   RESULT:= Round((jday - 2440587.5) * 86400)   // (juliandate - jdate 
of unix epoch)*(seconds per julian day)
END { jDayToSecs } ;


PROCEDURE jYear(td: DOUBLE; VAR yy, mm: Int64; VAR dd: DOUBLE);

// jyear - convert Julian date to year, month, day, which are
// returned via integer pointers to integers

VAR     z, a, alpha, b, c, d, e: Int64;
         f: DOUBLE;

BEGIN
   td:= td + 0.5;                       // astronomical to civil
   z:= Floor(td);
   f:= td - z;
   IF z < 2299161 THEN
     a:= z
   ELSE BEGIN
     alpha:= Floor((z - 1867216.25) / 36524.25);
     a:= z + 1 + alpha - Floor(alpha / 4)
   END;
   b:= a + 1524;
   c:= Floor((b - 122.1) / 365.25);
   d:= Floor(365.25 * c);
   e:= Floor((b - d) / 30.6001);

(* Note here: both MoonPhase.pm and moontool.c lose fractional days at 
this     *)
(* point since dd is declared as an integer; Perl programmers might not 
in      *)
(* fact notice this due to loose type handling. I think this is a bug 
since it  *)
(* prevents using non-GMT time ranges. MarkMLl. 
         *)

   dd:= b - d - Floor(30.6001 * e) + f;
   IF e < 14 THEN
     mm:= e - 1
   ELSE
     mm:= e - 13;
   IF mm > 2 THEN
     yy:= c - 4716
   ELSE
     mm:= c - 4715
END { jYear } ;


PROCEDURE jYear(td: DOUBLE; VAR yy, mm, dd: Int64);

// jyear - convert Julian date to year, month, day, which are
// returned via integer pointers to integers

(* This is equivalent to the original jYear() which loses fractional 
days.      *)
(* MarkMLl. 
         *)

VAR     y, m: Int64;
         d: DOUBLE;

BEGIN
   jYear(td, y, m, d);
   yy:= y;
   mm:= m;
   dd:= Trunc(d)
END { jYear } ;

which was transcribed from Perl (originally written in C) Moon phase 
calculations and again I believe tests OK.

-- 
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]



More information about the fpc-pascal mailing list