Mostrando entradas con la etiqueta My Family Server. Mostrar todas las entradas
Mostrando entradas con la etiqueta My Family Server. Mostrar todas las entradas

viernes, 18 de marzo de 2016

Cálculo de las fases lunares



Poniéndole el lazo al calendario de MyFamilyServer (V2) incluí en el calendario la posibilidad de ver las temperaturas y precipitaciones previstas para los próximos días, el santo del día y también la fase en la que estará la luna.

Hoy escribo acerca del cálculo de la fase de la luna.

Solo os presento cálculo, ya que la presentación de la luna como un icono (una fuente) ya está explicado en publicaciones anteriores de este blog.

Me he basado únicamente en dos datos que (según mi información) son correctos y con esos dos datos he realizado todos los cálculos.

  • Primer dato: Una fecha /hora en la que ha habido luna llena.
  • Segundo dato: Cuánto tiempo dura un ciclo lunar completo.
Primer dato. Cuándo ha sido luna llena. He tomado la primera luna llena de 2016, Ha habido luna llena el 24 de enero de 2016 a las 02:46:20.
Segundo dato. Cuánto dura un ciclo lunar. Un ciclo lunar completo dura 29 días, 12 horas, 43 minutos y 12 segundos.

Con estos dos datos la cosa es sencilla, a partir del 24 de enero, cada 29 días y medio tendremos luna llena de nuevo.

Los cálculos los realizo en segundos, que es la forma natural de trabajar con fechas para el servidor.

El cálculo es el siguiente:

Ha habido luna llena el 24 de enero de 2016 a las 02:46:20

A partir de esta momento, cada 29 días, 12 horas, 43 minutos y 12 segundos sera de nuevo luna llena.

    29 días en segundos es:    29 * 24 * 60 * 60 = 2.505.600
    12 horas en segundos es:         12 * 60 * 60 =      43.200
    43 minutos en segundos es:             43 * 60 =        2.580
    12 segundos en segundos:                       12 =             12
                                                                  + _____________
    Resultado:                        Cada ciclo lunar son  2.551.392 segundos.

Debemos también conocer cuántos segundos han pasado desde el 24 de enero hasta la fecha en la que queremos conocer la fase lunar. Esto es una simple resta (recordar que estamos operando en segundos y obtenemos el resultado en segundos).

El resultado de esa resta es el número de segundos entre la luna llena que conocemos y la fecha actual. Ahora dividimos esa cantidad de segundos entre el tiempo que dura un ciclo lunar (también en segundos) y nos quedamos con el resto de la división. Con esa operación no sé (no me interesa) cuántos ciclos lunares completos han pasado pero SI sé cuánto tiempo en segundos ha pasado del ultimo ciclo lunar (el de la fecha que queremos conocer).

Supongamos que quiero dividir el ciclo lunar en 8 fases:

Luna-llena, Luna-gibosa-menguante, Cuarto-menguante, Luna-menguante, Luna-nueva, Luna-nueva-visible, Cuarto-creciente y Luna-gibosa-creciente.

A partir del resto de la división anterior, si el resto que he obtenido está comprendido entre 1 y 318.924 segundos estamos en la primera fase.
Si el resto que he obtenido está comprendido entre 318.925 y 637.858 estamos en la segunda fase.
Si el resto que he obtenido está comprendido entre 637.859 y 956.782 estamos en la tercera fase y así sucesivamente.

Básicamente esto es todo, hay una operación más que es restar algo de tiempo al inicio, ya tengo el momento exacto de luna llena del 24 de enero, debo restarle la mitad del tiempo de una fase (159.462 segundos) para considerar que la fase de luna llena comienza media fase antes y termina media fase después.

Ahora os muestro el código utilizado para el cálculo, curiosamente es más fácil codificarlo que explicarlo. Veréis que el código es sencillo.



function calcula_fase_lunar($fecha){
#   $lunallena = mktime(hora, minuto, segundo, mes, dia , año );
    $lunallena = mktime(02, 46, 20, 01, 24, 2016);
#   24 de enero de 2016 a las 02:46:20
#   inicio de la luna llena es :
    $iniciolunallena = $lunallena - 159462;
    $fecha = strtotime($fecha);
    $year = date('Y', $fecha);
    $month = date('n', $fecha);
    $day = date('j', $fecha);
    $estanoche = mktime(23, 50, 00, $month, $day, $year);
#   calculamos la luna que de esta noche. El dia entregado a las 23:50:00
    $segundosentrelllen = $estanoche - $iniciolunallena;
#   Segundos entre luna llena y esta noche
#   resto de la division entre el tiempo de un ciclo y los segundos desde luna llena hasta ahora
    $resto = $segundosentrelllen % 2551392;
#   Si es entre      1 y 318924  - Primera fase
#   Si es entre 318924 y 637858  - Segunda fase
#   Si es entre 637858 y 956782  - Tercera fase y asi sucesivamente
    for ($fase = 0; $fase <= 8; $fase++) {
        if ($resto >= 318924) {
            $resto = $resto - 318924;
        } else {
            break;
        }
    }
#  ahora ponemos el calculo en letras (el array debe estar bien ordenado)
    $fase_array = array(
        'Luna-llena', 'Luna-gibosa-menguante', 'Cuarto-menguante', 'Luna-menguante',
        'Luna-nueva', 'Luna-nueva-visible', 'Cuarto-creciente', 'Luna-gibosa-creciente'
    );
    $fase = $fase_array[$fase];
    return $fase;
}

Es así de fácil, ya podéis calcular la fase lunar y utilizarla en cualquier sitio con un sencillo cálculo matemático.

La verdad es que no sé si hay desviaciones a largo plazo, yo lo he validado con fechas de los próximos 10 años y me ha resultado correcto. Si conocéis mejoras en el calculo, no dejéis de comentar.

miércoles, 9 de marzo de 2016

Incorporar el santoral a tu web



En anteriores publicaciones he explicado como incorporar datos del tiempo o de la fase lunar a tu web (o a tu calendario).
Yo, para completar mi calendario le he incorporado el santo del día.
He realizado varios intentos buscando algún API del santoral (un sitio donde un ordenador pueda hacer una llamada pasando algo de información -la fecha por ejemplo- y recibir el santo correspondiente a esa fecha) y no lo he conseguido, no he encontrado ningún API del santoral, SI he encontrado varios widgets y he sacado la información de los mismos.

En este articulo te explico como extraer la información del widget del santoral para integrarla en tu web o tu calendario, y además podrás utilizar esta idea para trabajar con cualquiera otra integración.

A modo de ejemplo, aquí tienes varias direcciones de componentes para integrar en tu web el santo del día:




Si lo que necesitas es un widget, encontrarás documentación fácil en las webs respectivas de cómo integrarlo, en este post quiero explicar como trabajar con el contenido que te proporcionan para extraerlo y darle otros usos.

Esta función recupera el string (el nombre) del widget que proporciona santopedia.com.


function recuperar_santoral($fecha) {
    # Aqui voy a recuperar el santoral desde http://www.santopedia.com
    $url = "http://www.santopedia.com/widget.html";
    $widgetsantoral = file_get_contents($url);
    $posini = strpos($widgetsantoral, 'target="_blank">');
    if (!($posini === false)) {
        $santo = substr($widgetsantoral, $posini + 16, 150);
        $posfin = strpos($santo, '</a>');
        if (!($posfin === false)) {
            $santo = substr($santo, 0, $posfin);
        }
    }
    return $santo;
}

Vamos a explicarlo un poco:
En la definición de la función recibo una fecha (que no utilizo para nada, ya que el widget te da el santo de hoy, sin que le pases parámetros).
Defino la variable $url con la url que voy a invocar.
y utilizo la instrucción 'file_get_content'. Con esta instrucción en vez de presentar en pantalla el resultado que me entrega el widget, lo que hago es almacenarlo en una variable, ahora busco dentro del contenido de esa variable el santo de hoy.
Hay que analizar el contenido (hay que poner la url en el navegador, ejecutarlo y con el widget en pantalla seleccionar 'view page source').

Esto es lo que presenta el widget:










Y esta es la información que te entrega 'view page source':




















Entre la información, hay que buscar dentro del <body> el texto que estamos buscando, en este caso 'San Juan de Dios', e identificar el string constante anterior que le precede. El string que encuentras delante es 'target="_blank">'.
Con esto ya sabemos donde buscar.
A continuación identificar el string constante que encuentras detrás de 'San Juan de Dios' , que es '</a>' y ya lo tenemos.
Ahora identifico en que posición aparece el string anterior y recorto a partir de ese punto (16 caracteres más ya que mi string de búsqueda es de 16 caracteres), Elimino también los caracteres a partir de </a> y finalmente en la variable $santo me queda el texto 'San Juan de Dios'.

Los comandos clave que he utilizado son sencillos: 
  • file_get_contents para obtener y mantener la información que me entrega la web del santoral.
  • strpos para identificar en que posición esta la información que busco.
  • substr para recortar de toda la página la información necesaria.

¿Como he utilizado esta función?:
Estoy presentando, en la cabecera de mi calendario diario, algo de información adicional (Santoral, fase lunar, tiempo actual), esta información la presento en un cuadro, justo por encima de la agenda del día.
En el calendario es configurable qué información se presenta en este cuadro.
Toda la información la compongo en una variable llamada '$contenido' que finalmente presento en pantalla.

Así es como incorporo el santo del día a mi cabecera del calendario:


$santo = recuperar_santoral($identificador);
$contenido = $contenido . '. Santo de hoy: ' .
      '<acronym title="Informacion gracias a www.santopedia.com">' .
      $santo . ' </acronym>';
Es importante, SI, es importante, mantener la información de la fuente o vínculos que el widget nos estaba entregando, nuestra intención no es robar la información, solo es adaptarla a nuestro formato, por lo tanto debemos presentarla en nuestra pantalla también con la referencia a su origen, tal como nos la han entregado en el widget. En este caso he definido el santo como un acrónimo, con esta definición aparece subrayado (seleccionable) y al poner el ratón encima nos muestra la información contenida en title. Esta información es importante mantenerla.

Cualquier duda... comentar.