Función para devolver la fecha de la Pascua del año

Así que, aquí está un poco raro desafío de programación. Yo estaba escribiendo un método rápido para determinar todo el mercado de vacaciones por un año en particular, y entonces comencé a la lectura sobre la semana santa y descubrió cuán loco* la lógica es para determinar su fecha–el primer domingo después de la Pascual Luna Llena tras el equinoccio de primavera! ¿Alguien sabe de una función existente para calcular la fecha de la Pascua para un año determinado?

Concedido, es probable que no todos los que difícil de hacer; yo sólo pensé en preguntar en caso de que alguien ya ha hecho esto. (Y que parece muy probable.)

ACTUALIZACIÓN: en Realidad, estoy realmente buscando la fecha de Buen viernes (el viernes antes de de Pascua)… me di cuenta de Pascua me llevaría allí. Y ya que estoy en los estados UNIDOS, supongo que estoy buscando la Católica, la Pascua? Pero tal vez alguien puede corregirme en que si estoy equivocado.

*Por «loco» quiero decir, como, involucrados. No es nada ofensivo…

  • Que La Pascua? Católicos, Ortodoxos, o Copto?
  • ¿Cuál es el primer año para el que se debe trabajar correctamente?
  • Otro buen reportaje sobre «el cálculo de la pascua»: simple-talk.com/community/blogs/philfactor/archive/2009/01/18/… . Y en T-SQL, de todas las cosas.
  • Excelente pregunta. Estoy realmente avergonzado yo no especificar esto en el principio; en realidad, sin embargo, realmente no soy interesado en semana santa tanto como el viernes santo, cuya fecha sólo pasa a depender de la Pascua. Voy a actualizar a la pregunta.
  • Ja, buena pregunta. Sin duda, algunos de ANUNCIO del año… 😉
  • «Hay muchos indicios de que el único importante de la aplicación de la aritmética en Europa durante la Edad Media fue el cálculo de la Pascua de la fecha.» – Knuth
  • dateutil apoya julian, ortodoxa y occidental.

InformationsquelleAutor Dan Tao | 2010-02-03

6 Kommentare

  1. 13

    en SQL Server domingo de Pascua tendría este aspecto, desplácese hacia abajo para el viernes santo

    CREATE FUNCTION dbo.GetEasterSunday 
    ( @Y INT ) 
    RETURNS SMALLDATETIME 
    AS 
    BEGIN 
        DECLARE     @EpactCalc INT,  
            @PaschalDaysCalc INT, 
            @NumOfDaysToSunday INT, 
            @EasterMonth INT, 
            @EasterDay INT 
    
        SET @EpactCalc = (24 + 19 * (@Y % 19)) % 30 
        SET @PaschalDaysCalc = @EpactCalc - (@EpactCalc /28) 
        SET @NumOfDaysToSunday = @PaschalDaysCalc - ( 
            (@Y + @Y /4 + @PaschalDaysCalc - 13) % 7 
        ) 
    
        SET @EasterMonth = 3 + (@NumOfDaysToSunday + 40) /44 
    
        SET @EasterDay = @NumOfDaysToSunday + 28 - ( 
            31 * (@EasterMonth /4) 
        ) 
    
        RETURN 
        ( 
            SELECT CONVERT 
            (  SMALLDATETIME, 
                     RTRIM(@Y)  
                + RIGHT('0'+RTRIM(@EasterMonth), 2)  
                + RIGHT('0'+RTRIM(@EasterDay), 2)  
            ) 
        ) 
    
    END 
    GO
    

    Buen viernes es como este y los usos de la semana santa de la función por encima de

    CREATE FUNCTION dbo.GetGoodFriday 
    ( 
        @Y INT 
    ) 
    RETURNS SMALLDATETIME 
    AS 
    BEGIN 
        RETURN (SELECT dbo.GetEasterSunday(@Y) - 2) 
    END 
    GO
    

    Desde aquí: http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html

    • Yo creo fueron los primeros que realmente publicar el código que hace esto. Felicitaciones, mi amigo… y gracias.
    • Esto sólo funciona para los años 1900 – 2199. Antes de 1900 y después de 2199, se desvía de la NOAA en la Pascua de secuencia de comandos de cálculo. La ventaja de este script es que es corto y dulce. Aquí está NOAA script Gracias por publicar esto.
    • La desviación entre la versión simplificada de esta respuesta y la NOAA versión, de hecho, comienza a partir de 1899 (3 de abril de 1899 (simple) vs Apr 2 1899 (NOAA)). Pero difieren tan pronto como 2100 (Mar 27 2100 (Simple) vs 28 de Marzo de 2100 (NOAA)) voy a publicar una respuesta con la NOAA algoritmo en algún momento en el día de hoy.
  2. 30

    Python: el uso de dateutil del pascua() función.

    >>> from dateutil.easter import *
    >>> print easter(2010)
    2010-04-04
    >>> print easter(2011)
    2011-04-24
    

    Las funciones que se obtiene, como argumento, el tipo de cálculo que te gusta:

    EASTER_JULIAN   = 1
    EASTER_ORTHODOX = 2
    EASTER_WESTERN  = 3
    

    Usted puede elegir la correspondiente a la de NOSOTROS.

    La reducción de dos días a partir de que el resultado iba a dar un Buen viernes:

    >>> from datetime import timedelta
    >>> d = timedelta(days=-2)
    >>> easter(2011)
    datetime.date(2011, 4, 24)
    >>> easter(2011)+d
    datetime.date(2011, 4, 22)
    

    Por extraño que parezca, alguien estaba repitiendo esto, y publicó los resultados en Artículo de Wikipedia sobre el algoritmo:

    Función para devolver la fecha de la Pascua del año

  3. 4

    Cuando me llegó a escribir esto (tráfico de predicción basados en los días de semana y de vacaciones),
    Me di por vencido en tratar de escribir por mí mismo. Lo he encontrado en algún lugar de la red. El código era de dominio público, pero…

    suspiro

    ver por ti mismo.

    void dateOfEaster(struct tm* p)
    {
        int Y = p->tm_year;
        int a = Y % 19;
        int b = Y /100;
        int c = Y % 100;
        int d = b /4;
        int e = b % 4;
        int f = (b + 8) /25;
        int g = (b - f + 1) /3;
        int h = (19 * a + b - d - g + 15) % 30;
        int i = c /4;
        int k = c % 4;
        int L = (32 + 2 * e + 2 * i - h - k) % 7;
        int m = (a + 11 * h + 22 * L) /451;
        p->tm_mon = ((h + L - 7 * m + 114) /31 ) - 1;
        p->tm_mday = ((h + L - 7 * m + 114) % 31) + 1;
        p->tm_hour = 12;
        const time_t tmp = mktime(p);
        *p = *localtime(&tmp);  //recover yday from mon+mday
    }
    

    Algunas preguntas son mejor dejarlas sin contestar.

    Me siento afortunado de que el movimiento de las vacaciones en mi país son una compensación fija a partir de la fecha de la Pascua.

  4. 1

    La función de SQL Server a continuación es más general que el aceptado respuesta

    La aceptada respuesta es correcta sólo para el rango (inclusive) : 1900-04-15 a 2099-04-12

    Utiliza el algoritmo proporcionado por El Observatorio Naval de los Estados unidos (USNO)

    http://aa.usno.navy.mil/faq/docs/easter.php

    CREATE FUNCTION dbo.GetEasterSunday (@Y INT)
    RETURNS DATETIME
    AS
        BEGIN 
    
            -- Source of algorithm : http://aa.usno.navy.mil/faq/docs/easter.php
    
            DECLARE @c INT = @Y /100
            DECLARE @n INT = @Y - 19 * (@Y /19)
            DECLARE @k INT = (@c - 17) /25
            DECLARE @i INT = @c - @c /4 - (@c - @k) /3 + 19 * @n + 15
            SET @i = @i - 30 * (@i /30)
            SET @i = @i - (@i /28) * (1 - (@i /28) * (29 /(@i + 1)) * ((21 - @n) /11))
            DECLARE @j INT = @Y + @Y /4 + @i + 2 - @c + @c /4
            SET @j = @j - 7 * (@j /7)
            DECLARE @l INT = @i - @j
            DECLARE @m INT = 3 + (@l + 40) /44
            DECLARE @d INT = @l + 28 - 31 * (@m /4)
    
            RETURN 
        ( 
            SELECT CONVERT 
            (  DATETIME, 
                     RTRIM(@Y)  
                + RIGHT('0'+RTRIM(@m), 2)  
                + RIGHT('0'+RTRIM(@d), 2)  
        ) 
        )
        END 
    
    
    GO
    
  5. 1

    El código de abajo, determina la Pascua a través de powershell:

    function Get-DateOfEaster {
        param(
            [Parameter(ValueFromPipeline)]
            $theYear=(Get-Date).Year
            )
    
        if($theYear -lt 1583) {
            return $null
        } else {
    
            # Step 1: Divide the theYear by 19 and store the
            # remainder in variable A.  Example: If the theYear
            # is 2000, then A is initialized to 5.
    
            $a = $theYear % 19
    
            # Step 2: Divide the theYear by 100.  Store the integer
            # result in B and the remainder in C.
    
            $c = $theYear % 100
            $b = ($theYear -$c) /100
    
            # Step 3: Divide B (calculated above).  Store the
            # integer result in D and the remainder in E.
    
            $e = $b % 4
            $d = ($b - $e) /4
    
            # Step 4: Divide (b+8)/25 and store the integer
            # portion of the result in F.
    
            $f = [math]::floor(($b + 8) /25)
    
            # Step 5: Divide (b-f+1)/3 and store the integer
            # portion of the result in G.
    
            $g = [math]::floor(($b - $f + 1) /3)
    
            # Step 6: Divide (19a+b-d-g+15)/30 and store the
            # remainder of the result in H.
    
            $h = (19 * $a + $b - $d - $g + 15) % 30
    
            # Step 7: Divide C by 4.  Store the integer result
            # in I and the remainder in K.
    
            $k = $c % 4
            $i = ($c - $k) /4
    
            # Step 8: Divide (32+2e+2i-h-k) by 7.  Store the
            # remainder of the result in L.
    
            $l = (32 + 2 * $e + 2 * $i - $h - $k) % 7
    
            # Step 9: Divide (a + 11h + 22l) by 451 and
            # store the integer portion of the result in M.
    
            $m = [math]::floor(($a + 11 * $h + 22 * $l) /451)
    
            # Step 10: Divide (h + l - 7m + 114) by 31.  Store
            # the integer portion of the result in N and the
            # remainder in P.
    
            $p = ($h + $l - 7 * $m + 114) % 31
            $n = (($h + $l - 7 * $m + 114) - $p) /31
    
            # At this point p+1 is the day on which Easter falls.
            # n is 3 for March and 4 for April.
    
            $DateTime = New-Object DateTime $theyear, $n, ($p+1), 0, 0, 0, ([DateTimeKind]::Utc)
            return $DateTime
        }
    }
    
    $eastersunday=Get-DateOfEaster 2015
    Write-Host $eastersunday
    
  6. 0

    VB .NET Funciones de los griegos Ortodoxos y Católicos de Pascua:

    Public Shared Function OrthodoxEaster(ByVal Year As Integer) As Date
        Dim a = Year Mod 19
        Dim b = Year Mod 7
        Dim c = Year Mod 4
        Dim d = (19 * a + 16) Mod 30
        Dim e = (2 * c + 4 * b + 6 * d) Mod 7
        Dim f = (19 * a + 16) Mod 30
        Dim key = f + e + 3
        Dim month = If((key > 30), 5, 4)
        Dim day = If((key > 30), key - 30, key)
        Return New DateTime(Year, month, day)
    End Function
    
    Public Shared Function CatholicEaster(ByVal Year As Integer) As DateTime
        Dim month = 3
        Dim a = Year Mod 19 + 1
        Dim b = Year /100 + 1
        Dim c = (3 * b) /4 - 12
        Dim d = (8 * b + 5) /25 - 5
        Dim e = (5 * Year) /4 - c - 10
        Dim f = (11 * a + 20 + d - c) Mod 30
        If f = 24 Then f += 1
        If (f = 25) AndAlso (a > 11) Then f += 1
        Dim g = 44 - f
        If g < 21 Then g = g + 30
        Dim day = (g + 7) - ((e + g) Mod 7)
        If day > 31 Then
            day = day - 31
            month = 4
        End If
        Return New DateTime(Year, month, day)
    End Function
    

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea