La fecha juliana astronómica

Descripción general

La fecha juliana astronómica es una forma de medir el tiempo que tienen los astrónomos. En el 1582, José Scaliger de Leyden fijó una escala continua de tiempo fijando su origen en el 1 de enero del año 4713 a. C. a las 12h del mediodía (en esta época el día empezaba a mediodía y no como es costumbre ahora, en que el día comienza a medianoche) y contando los días solares correlativamente. Este número se llama fecha juliana.

[TOC] Tabla de Contenidos


↑↑↑

La fecha juliana astronómica


↑↑↑

Introducción

La fecha juliana astronómica es una forma de medir el tiempo que tienen los astrónomos. Se basa en contar los días transcurridos desde el 1 de enero de -4713 a las 12:00 horas.

Para hacer los cálculos, el problema estriba en que ha habido varios ajustes del calendario y no es tan fácil contar el número de días desde esa fecha que se toma como origen


↑↑↑

Una pequeña historia de correcciones

En tiempo de Julio César, (año 60 A/C.) era tal el desorden que existía en el calendario, que el año civil tenía 90 días de diferencia con el año trópico, de manera que los meses habían cambiado de estaciones y así, las fiestas de verano se celebraban en otoño y las de invierno en primavera, etc.

A fin de arreglar esta anormalidad y armonizar el año civil con el trópico, consultó Julio César a Soanígenen, célebre astrónomo egipcio; se estableció definitivamente la duración del año en 365+1/4 días y para tener un número cabal de días, se decidió que los años comunes constaran de 365 días, intercalando cada 4 años uno de 366 días o año bisiesto.

Se ordenó que el año debía empezar el 1 de Enero, dándose a los meses la denominación actual, con excepción de Julio, nombre que se puso después al mes Quintilis para honrar la memoria de Julio César, y de Agosto, que correspondió al mes Sixtilis , para recordar al Emperador Augusto.

Además se estableció que los año bisiesto serían aquellos cuyas dos últimas cifras fuesen divisibles por 4.

Al año en que se hizo esta reforma hubo que agregarle 90 días, para que los meses estuviesen de acuerdo con las estaciones; se le llamó "año de confusiones", constó por lo tanto de 15 meses y fue al año 45 A/C

La Reforma Juliana produjo que al cabo de 400 años las estaciones se anticiparon en 3 dias. 2 hrs. 43 min. Y 20 segs. Por esta razón se fueron acumulando los errores en el Calendario Romano y el año 1.500 D.C., el sol estaba en el equinocio el 10 de Marzo en vez del 20.

El año 1582, en la celebración del Concilio de Trento, EL Papa Gregorio XIII acordó efectuar la reforma que tomó el nombre de Corrección Gregoriana, para lo cual dispuso:

  1. Suprimirle 10 días al mes de octubre de 1582, cantidad en que estaban adelantadas las estaciones, tal que el 5 de Octubre se llamó 15
  2. Suprimir 3 años bisiestos cada 400 años y que estos tres bisiestos fuesen los años principio de siglo cuyas dos primeras cifras no fuesen divisibles por 4. Por esta razón no fue bisiesto el año 1900, pero lo será el año 2000.

Este es el calendario que seguimos en la actualidad, con excepción de los rusos y griegos cismáticos, quienes por motivos religiosos siguen usando el calendario romano.

La corrección Gregoriana sólo tiene un error en exceso de un día en 3600 años, lo que se remediará fácilmente suprimiendo un bisiesto cada 4000 años.


↑↑↑

A modo de resumen

El año Civil consta de 365 días medios, pero como el año trópico tiene 365 días, 5 horas, 48 minutos y 47,5 seg., resulta que el año Civil es corto en las 5 hrs. 48 min. 47,5 seg., lo que hace que al cabo de 4 años esté atrasado en 23 hrs. 15 min. 10 seg.- Este defecto se compenso agregando 24 horas a uno de los años civiles de cada período de 4. dicho año consta de 366 días y se llama "año bisiesto"; los otros tres del mismo período tienen 365 días y se llaman "años comunes". pero de esta forma se tiene un exceso cada 4 años de 44 min. 50 segs., que el cabo de 400 años suman 3 días. 2 hrs. 43 min. 20 seg. Para corregir este error fue necesario hacer comunes tres años bisiestos cada 400 años y aún cuando todavía queda un error en exceso de 2 hrs. 43 min. 20 segs., éste error sólo viene a representar un día cada 4.000 años.


↑↑↑

La fecha juliana astronómica

En el 1582, José Scaliger de Leyden fijó una escala continua de tiempo fijando su origen en el 1 de enero del año 4713 a. C. a las 12h del mediodía (en esta época el día empezaba a mediodía y no como es costumbre ahora, en que el día comienza a medianoche) y contando los días solares correlativamente. Este número se llama fecha juliana.

La fecha juliana (JD) es una cuenta continua de días y fracciones de estos contados desde el mismo período inicial.

Por ejemplo: El día 11 de julio de 1997 a las 12 h TU se completa el día 2.450.641

Por ejemplo: la fecha Juliana 2451545.0 TT (Tiempo Terrestre), o 1 de enero de 2000, mediodía TT. Es equivalente al 1 de enero de 2000.

La parte fraccional da la hora del día desde el amanecer UT como una fracción decimal de un día en el que 0,5 sería la medianoche UT.

Esta fecha es usada ampliamente para indicar un instante en el tiempo estándar para la medición de las posiciones de los cuerpos celestes y otros eventos estelares. Por ejemplo, aunque imperceptible a simple vista, las estrellas se mueven en el espacio, y es necesario, para describir su posición en el firmamento, especificar la fecha a la que se refiere dicha posición.

También se usa (usaba) por los informáticos para restar sin problemas dos fechas para lo cual se transforman las fechas a Juliana, se restan y el resultado es una fecha juliana astronómica que representa en días, horas, minutos, la diferencia entre las dos fechas. Un proceso parecido se puede usar para sumar un periodo de tiempo a una fecha dada. En la actualidad, estos procedimientos están un poco obsoletos porque .NET tiene funciones que directamente realizan estas tareas y no hay necesidad de hacer transformaciones.


↑↑↑

Los cálculos

He buscado las formulas que permitan hacer los cálculos que permitan transformar una fecha del calendario Gregoriano, a su correspondiente numero del calendario Juliano astronómico, pero no ha sido fácil. He encontrado varias formulas, pero no consigo que los resultados sean coherentes. Muchas de ellas se deben a que toma como origen los calendarios Julianos que aun se utilizan por el mundo, y en otras, no he conseguido averiguar la razón. Al final, he encontrado una página creada por el Ministerio de Educación Nacional de Francia, que hacia estos cálculos http://www.imcce.fr/en/grandpublic/temps/jour_julien.php, y después de estudiar las formulas (escritas en Java Script) he conseguido transformarlas a Visual Basic .NET y que funcionen.

No me preguntes por el porqué de los cálculos porque no lo sé, solamente te puedo decir que funcionan perfectamente tanto al derecho como en los cálculos inversos.

A la hora de escribir el código hay un problema que consiste en que cuando se transforma una fecha Gregoriana se obtiene un numero [Decimal], pero cuando se transforma una fecha juliana Astronómica se obtiene seis (6) datos diferentes, (año, mes, día, hora, minutos, segundos). Por esa razón he creado una estructura que contiene esa información (Siete (7) datos en total, los seis de la fecha Gregoriana y el numero de la fecha Juliana Astronómica) y que es devuelva por las funciones que realizan el cálculo.


↑↑↑

Estructura para recoger los resultados

''' <summary>
'''  Contiene los datos (Datos iniciales y resultado transformado) 
'''  de transformar una fecha gregoriana en juliana astronómica y viceversa
''' </summary>
''' <remarks>
''' Solo hay datos, no se hacen cálculos
''' Se emplea por las funciones que hacen los cálculos de transformación 
'''  para devolver los resultados 
''' </remarks>
Public Structure JulianaAstronomicaDatos


    Private _Año As Integer
    Private _Mes As Integer
    Private _Dia As Integer
    Private _Hora As Integer
    Private _Minutos As Integer
    Private _Segundos As Integer
    Private _JulianaAstronomica As Decimal


    ''' <summary>
    '''    Devuelve el año de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Año As Integer
        Get
            Return _Año
        End Get
    End Property
    ''' <summary>
    '''    Devuelve el mes de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Mes As Integer
        Get
            Return _Mes
        End Get
    End Property
    ''' <summary>
    '''    Devuelve el dia de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Dia As Integer
        Get
            Return _Dia
        End Get
    End Property
    ''' <summary>
    '''    Devuelve la hora de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Hora As Integer
        Get
            Return _Hora
        End Get
    End Property
    ''' <summary>
    '''    Devuelve los minutos de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Minutos As Integer
        Get
            Return _Minutos
        End Get
    End Property
    ''' <summary>
    '''    Devuelve los segundos de la fecha tratada
    ''' </summary>
    Public ReadOnly Property Segundos As Integer
        Get
            Return _Segundos
        End Get
    End Property
    ''' <summary>
    '''    Devuelve la fecha en formato Juliano astronómico
    ''' </summary>
    Public ReadOnly Property JulianaAstronomica As Decimal
        Get
            Return _JulianaAstronomica
        End Get
    End Property



    ''' <summary>
    '''   Constructor de la estructura
    ''' </summary>
    ''' <param name="YY"> Fecha Gregoriana: El año </param>
    ''' <param name="MM"> Fecha Gregoriana: El mes</param>
    ''' <param name="DD"> Fecha Gregoriana: El dia</param>
    ''' <param name="HR"> Fecha Gregoriana: La hora</param>
    ''' <param name="Min">Fecha Gregoriana: Los minutos</param>
    ''' <param name="SS"> Fecha Gregoriana: Los segundos</param>
    ''' <param name="fechaJulianaAstronomica">El numero que representa la fecha Juliana astronomica</param>
    ''' <remarks></remarks>
    Public Sub New( _
                   ByVal YY As Integer, ByVal MM As Integer, ByVal DD As Integer, _
                   ByVal HR As Integer, ByVal Min As Integer, ByVal SS As Integer, _
                   ByVal fechaJulianaAstronomica As Decimal)

        _Año = YY
        _Mes = MM
        _Dia = DD
        _Hora = HR
        _Minutos = Min
        _Segundos = SS
        _JulianaAstronomica = fechaJulianaAstronomica

    End Sub

End Structure


↑↑↑

Código To Juliana Astronómica

''' <summary>
'''    Calcula la fecha Juliana Astronomica correspondiente a la 
'''    fecha del calendario Gregoriano pasada en los parametros. 
''' </summary>
''' <param name="año">  El año </param>
''' <param name="mes">  Mes (del 1 al 12). </param>
''' <param name="dia">  Día (del 1 al número de días del mes). </param>
''' <param name="hora"> Horas (de 0 a 23). </param>
''' <param name="min">  Minutos (de 0 a 59). </param>
''' <param name="seg">  Segundos (de 0 a 59). </param>
''' <param name="mls">  Milisegundos (de 0 a 999). </param>
''' <returns> 
'''      Un numero decimal que contiene la fecha juliana astronomica calculada
''' </returns>
''' <remarks>       
''' <para>Calcula un numero (decimal) con el valor Gregoriano Astronomico de la 
'''       fecha recibida. Ejemplo. 2000-01-01T12:00:00 es 2451545,0 </para>
 ''' <code>  
'''    <para>Está traducida de una funcion en JavaScript encontrada en la pagina</para>
'''    <para>http://www.imcce.fr/en/grandpublic/temps/jour_julien.php</para>
''' </code>
''' </remarks>
''' <autor>   Joaquin medina Serrano: joaquin@medina.name</autor>
''' <rights>  Licencia Creative Commons Compartir-Igual 3.0</rights>
''' <Creacion>2010/08/18T18:19:00</Creacion>
Private Overloads Shared Function GregorianoToJulianoAstronomico( _
                 ByVal año As Integer, ByVal mes As Integer, ByVal dia As Integer, _
                 ByVal hora As Integer, ByVal min As Integer, ByVal seg As Integer, ByVal mls As Integer) _
                 As Decimal

    '------------------------------------------------------
    ' Control de datos
    '------------------------------------------------------

    If mes < 1 OrElse mes > 12 Then
        Throw New ArgumentOutOfRangeException("mes", mes, "El rango de los meses es [1 hasta 12]")
    End If

    If dia < 1 Then
        Throw New ArgumentOutOfRangeException( _
            "dia", dia, "El dia o puede ser menor de 1. El rango de los dias del mes es [1 hasta 31]")
    End If
    If mes = 2 Then
        If año Mod 4 = 0 _
                  And (año Mod 100 <> 0 Or año Mod 400 = 0) Then
            If dia > 29 Then
                Throw New ArgumentOutOfRangeException( _
                    "dia", dia, "(Año Bisiesto) El rango del mes de febrero es [1 hasta 29]")
            End If
        Else
            If dia > 28 Then
                Throw New ArgumentOutOfRangeException( _
                    "dia", dia, "(Año normal) El rango del mes de febrero es [1 hasta 28]")
            End If
        End If
    End If
    If (mes = 4 OrElse mes = 6 OrElse mes = 9 OrElse mes = 11) AndAlso dia > 30 Then
        Throw New ArgumentOutOfRangeException("dia", dia, "El rango de este mes es [1 hasta 30]")
    End If
    If (mes = 1 OrElse mes = 3 OrElse mes = 5 OrElse mes = 7 OrElse _
        mes = 8 OrElse mes = 10 OrElse mes = 12) AndAlso dia > 31 Then
        Throw New ArgumentOutOfRangeException("dia", dia, "El rango de este mes es [1 hasta 31]")
    End If

    If hora < 0 OrElse hora > 23 Then
        Throw New ArgumentOutOfRangeException("hora", hora, "El rango de las horas es [0 hasta 23]")
    End If

    If min < 0 OrElse min > 59 Then
        Throw New ArgumentOutOfRangeException("min", min, "El rango de los minutos es [0 hasta 59]")
    End If

    If seg < 0 OrElse seg > 59 Then
        Throw New ArgumentOutOfRangeException("seg", seg, "El rango de los segundos es [0 hasta 59]")
    End If

    If mls < 0 OrElse mls > 999 Then
        Throw New ArgumentOutOfRangeException("mls", mls, "El rango de los milisegundos es [0 hasta 999]")
    End If

    '------------------------------------------------------
    ' Calculos
    Dim auxHora As Decimal = Convert.ToDecimal(hora + (min / 60) + (seg / 3600) + (mls / 3600000))
    Dim GGG As Integer = 1

    If (año < 1582) Then GGG = 0
    If (año <= 1582 And mes < 10) Then GGG = 0
    If (año <= 1582 And mes = 10 And dia < 5) Then GGG = 0

    Dim JD As Decimal = Convert.ToDecimal(-1 * Math.Floor(7 * (Math.Floor((mes + 9) / 12) + año) / 4))
    Dim S As Integer = 1
    If ((mes - 9) < 0) Then S = -1
    Dim A As Integer = Math.Abs(mes - 9)

    Dim J1 As Integer = Convert.ToInt32(Math.Floor(año + (S * Math.Floor(A / 7))))
    J1 = Convert.ToInt32(-1 * Math.Floor((Math.Floor(J1 / 100) + 1) * 3 / 4))
    JD = Convert.ToDecimal(JD + Math.Floor((275 * mes) / 9) + dia + (GGG * J1))
    JD = Convert.ToDecimal(JD + 1721027 + (2 * GGG) + (367 * año) - 0.5)
    JD = Convert.ToDecimal(JD + (auxHora / 24))
    ' ---------------------------------------
    Return JD
    ' ---------------------------------------
End Function


↑↑↑

Código To Fecha gregoriana

''' <summary>
'''    Calcula la fecha del calendario Gregoriano correspondiente a la 
'''    fecha Juliana Astronomica pasada en el parametro. 
''' </summary>
''' <param name="FechaJulianaAstronomica">
'''        La fecha Juliana astronomica de la que queremos conocer 
'''        su equivalente en el calendario Gregoriano
''' </param>
''' <returns> 
'''      Una estructura [JulianaAstronomicaDatos] con los datos, tanto los 
'''      iniciales del calculo como el resultado de los mismos
''' </returns>
''' <remarks>       
''' <para> Esta funcion es la que hace el trabajo y realiza los calculos</para>
''' <para> Calcula la fecha del calendario Gregoriano correspondiente un numero 
'''        (decimal) con el valor Gregoriano Astronomico paraso por parametro
'''        Ejemplo. la fecha Juliana astronomica [2451545,0]  se corresponde con 
'''        la fecha del calendario Gregoriano siguiente [2000-01-01T12:00:00]
''' </para>
''' <para> Los rangos de las horas son : Hora: [0-23]; Minutos [0-59]; Segundos [0-59]</para>
''' <code>    
'''    <para>Está copiada (traducida y modificada) de una funcion en JavaScript encontrada en la pagina</para>
'''    <para>http://www.imcce.fr/en/grandpublic/temps/jour_julien.php</para>
''' </code>
''' <autor>   Joaquin medina Serrano: joaquin@medina.name</autor>
''' <rights>  Licencia Creative Commons Compartir-Igual 3.0</rights>
''' <Creacion>2010/08/18T18:19:00</Creacion>
''' </remarks>
   Private Shared Function JulianoAstronomicoToGregoriano(ByVal FechaJulianaAstronomica As Decimal) As JulianaAstronomicaDatos

    Dim resultado As JulianaAstronomicaDatos
    Try

        Dim JD As Decimal = FechaJulianaAstronomica

        Dim Z As Integer = Convert.ToInt32(Math.Floor(JD + 0.5)) ' tiene la fecha
        Dim F As Decimal = Convert.ToDecimal(JD + 0.5 - Z) ' tiene la hora

        Dim I As Decimal = Decimal.Zero
        Dim A As Decimal = Decimal.Zero

        If (Z < 2299161) Then
            A = Z
        Else
            I = Convert.ToDecimal(Math.Floor((Z - 1867216.25) / 36524.25))
            A = Z + 1 + I - Math.Floor(I / 4)
        End If

        ' fecha
        Dim B As Decimal = A + 1524
        Dim C As Decimal = Convert.ToDecimal(Math.Floor((B - 122.1) / 365.25))   ' aqui
        Dim D As Decimal = Convert.ToDecimal(Math.Floor(365.25 * C))
        Dim T As Decimal = Convert.ToDecimal(Math.Floor((B - D) / 30.6001))
        ' 
        Dim RJ As Decimal = Convert.ToDecimal(B - D - Math.Floor(30.6001 * T) + F)
        Dim JJ As Decimal = Math.Floor(RJ)
        Dim RH As Decimal = (RJ - Math.Floor(RJ)) * 24
        '----------------------------------------------------
        Dim auxHora As Decimal = Math.Floor(RH) ' contiene la hora con decimales
        '
        Dim Hora As Integer = Convert.ToInt32(auxHora)

        Dim Min As Integer = Convert.ToInt32(Math.Floor((RH - auxHora) * 60))

        '
        ' aqui se calculan los segundos y decimas de segundo ( los milisegundos)
        Dim auxSec As Decimal = Convert.ToInt32(((RH - auxHora) * 60 - Min) * 60)
        ' los segundos son la parte entera
        Dim Seg As Integer = Convert.ToInt32(Math.Truncate(auxSec))
        '
        ' los milisegundos es la parte decimal, pero dentro del rango [1 - 999]
        Dim Mls As Integer = Convert.ToInt32(Math.Round(((auxSec - Seg) * 1000), 3))

        '------------------------------------
        Dim dia As Integer = Convert.ToInt32(JJ)

        Dim Mes As Integer = 0
        If (T < 14) Then
            Mes = Convert.ToInt32(T - 1)
        Else
            If ((T = 14) Or (T = 15)) Then Mes = Convert.ToInt32(T - 13)
        End If

        Dim Año As Integer = 0
        If (Mes > 2) Then
            Año = Convert.ToInt32(C - 4716)
        Else
            If ((Mes = 1) Or (Mes = 2)) Then Año = Convert.ToInt32(C - 4715)
        End If
        '----------------------------------------------
        ' correccion de valores
        ' los rangos de las horas son
        ' Hora     rango [0-23]
        ' Minutos  rango [0-59]
        ' Segundos rango [0-59]
        '--------------------------------
        ' PROBLEMA DETECTADO
        ' hay ocasiones en los que los valores calculados de
        ' los segundos, etc estan por encima de los valores  
        ' superiores del rango  60 segundos
        '--------------------------------

        If Mls > 1000 Then
            Mls = Mls - 1000
            Seg += 1
        End If

        If Seg > 59 Then
            Seg = Seg - 60
            Min += 1
        End If

        If Min > 59 Then
            Min = Min - 60
            Min += 1
        End If

        If Hora > 23 Then
            Hora = Hora - 24
            dia += 1
        End If

        ' el mes (Primera vuelta) me aseguro en su valor
        If Mes > 12 Then
            Mes = 1
            Año += 1
            If Año = 0 Then Año = 1
        End If

        If dia > FechaHoraDatosEstructura.DiasDelMes(Año, Mes) Then
            dia = dia - FechaHoraDatosEstructura.DiasDelMes(Año, Mes)
            Mes += 1
        End If

        ' el mes segunda vuelta
        If Mes > 12 Then
            Mes = 1
            Año += 1
            If Año = 0 Then Año = 1
        End If


        ' ---------------------------------------
        ' Resultados a la estructura
        resultado = New FechaHoraDatosEstructura(Año, Mes, dia, Hora, Min, Seg, Mls)

    Catch ex As Exception
        Throw
    End Try

    ' Devolver resultados
    Return resultado
    ' ---------------------------------------
End Function


↑↑↑

Descargas

Todas estas funciones las he incluido en una clase que he llamado [JulianaAstronomica]


↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquin Medina Serrano
Ésta página es española