JD:n laskenta

JD, Julian Date eli Juliaaninen päivämäärä on eräänlainen päivän numero, yksittäinen luku joka ilmaisee ajankohdan. Kolmella desimaalilla JD pystyy ilmaisemaan ajan lähes minuutin tarkkuudella koska vuorokaudessa on vain 1440 minuuttia. Numeroiden määrä kasvaa kuitenkin suureksi koska JD:tä halutaan käyttää jopa tuhansien vuosien pituisille ajoille.

v = vuosi
k = kuukauden numero (1, 2, ... , 12)
p = kuukauden päivän numero (1, 2, ... 28/29/30/31)
u = UT kellonaika desimaalitunteina (0 ... 24)

Tässä oletetaan että juliaaninen kalenteri vaihtui gregoriaaniseksi kalenteriksi kuten katolisissa maissa. Se on jonkinlainen standardi astronomiassa. Täten 4. päivä lokakuuta 1582 oli viimeinen juliaanisen kalenterin päiväys ja sitä seurasi gregoriaanisen kalenterin päiväys 15.10.1582. Päiväyksiä 5.10.1582 ... 14.10.1582 ei tämän käytännön mukaan ole olemassa.

Suomessahan kalenterin vaihdos ei tapahtunut näin yksinkertaisesti, joten 1700-luvun alkua kaukaisempien aikojen laskenta vaatii huolellisuutta jos halutaan noudattaa nimenomaan Suomessa käytettyä ajanlaskutapaa.

int () tarkoittaa seuraavassa luvun kokonaislukuosaa, esim int (12,9) = 12

Positiivisen JD:n voi laskea seuraavalla algoritmilla kaikille vuosille [Meeus].

JOS k > 2 NIIN
  y = v
  m = k
MUUTEN
  y = v - 1
  m = k + 12
LOPPU JOS

JOS gregoriaaninen kalenteri NIIN
  a = int ( y / 100 )
  b = 2 - a + int (a / 4)
MUUTEN (juliaaninen kalenteri)
  b = 0
LOPPU JOS

JD = int (365,25 * (y + 4716)) 
  + int (30,6001 * (m + 1)) 
  + p + b - 1524,5 
  + u / 24

Kannattaa ehkä huomata että termi 365,25 * (y + 4716) on nykyisillä vuosiluvuilla liki kaksi ja puoli miljoonaa.

Seuraavassa vaihtoehtoinen algoritmi [Montenbruck]

JOS k > 2 NIIN
  y = v
  m = k
MUUTEN
  y = v - 1
  m = k + 12
LOPPU JOS

JOS gregoriaaninen kalenteri NIIN
  b = int ( y / 400 ) - int (y / 100)
MUUTEN (juliaaninen kalenteri)
  b = -2
LOPPU JOS

JD = int (365,25 * y) 
  + int (30,6001 * (m + 1)) 
  + p + b + 1720996,5 
  + u / 24

Laskentaa on mahdollista lyhentää jos ei tarvitse mennä kovin kauas nykyhetkestä. Esimerkiksi jos halutaan laskea vain vuoden 1900 helmikuun jälkeisiä aikoja gregoriaanisessa kalenterissa niin seuraava [Almanac for Computers] pitäisi riittää:

JD =  367 * v 
  - int ( 7 * ( v + int ( (k + 9) / 12) ) / 4 )
  + int ( 275 * k / 9 ) + p + 1721013,5 
  + u / 24

Tässäkin kannattaa ohjelmallisen toteutuksen kannalta huomata että termi 367 * v helposti ylittää esim. 16-bittisen kokonaislukualueen. Sekä 367 että vuosi ovat lyhyitä kokonaislukuja, mutta niiden tulo ei välttämättä kelpaa lyhyeksi kokonaisluvuksi.

Päiväyksen ratkaisu JD:stä

Jos tunnetaan JD, niin miten sitten tehdään käänteinen muunnos JD -> päiväys?

int () tarkoittaa luvun kokonaislukuosaa ja frac () tarkoittaa desimaaliosaa. Esim. frac (12,34) = 0,34

Tässä eEräs algoritmi [Meeus]

i = int ( JD + 0,5 )
f = frac ( JD + 0,5 )

JOS i < 2299161 NIIN
  a = i
MUUTEN
  w = int ( ( i - 1867216,25 ) /  36524,25 )
  a = i + 1 + w - int (w / 4)  
LOPPU JOS

b = a + 1524
c = int ( ( b - 122,1 ) / 365,25 )
d = int ( 365,25 * c )
e = int ( ( b - d ) / 30,6001 )

Kuukauden päivä p = b - d - int (30,6001 * e ) + f

Kuukausi k :
JOS e < 14 NIIN
  k = e - 1
MUUTEN ( e = 14 tai 15 )
  k = e - 13
LOPPU JOS

Vuosi v :
JOS k > 2 NIIN
  v = c - 4716
MUUTEN ( k = 1 tai 2)
  v = c - 4715
LOPPU JOS

Vaihtoehtoinen algoritmi [Montenbruck]

a = int ( JD + 0,5 )

JOS a < 2299161 NIIN
  c = a + 1524
MUUTEN
  b = int ( ( a - 1867216,5 ) / 36524,25 )
  c = a + b - int ( b / 4 ) + 1525
LOPPU JOS

d = int ( ( c - 122,1 ) / 365,25 )
e = int ( 365,25 * d )
f = int ( ( c - e ) / 30,6001 )

Päivä p = c - e - int ( 30,6001 * f ) + frac ( JD + 0,5 )

Kuukausi k = f - 1 - 12 * int ( f / 14 )

Vuosi v = d - 4715 - int ( ( 7 + k) / 10 )


Aika

PÄÄSIVU