Функция возврата даты Пасхи за данный год
Итак, вот смешная небольшая проблема программирования. Я писал быстрый метод, чтобы определить все праздничные дни в течение определенного года, а затем я начал читать о Пасхе и обнаружил, насколько сумасшедшие * логика заключается в определении его даты - в первое воскресенье после "Пасхальная полнолуния" после равноденствия spring! Кто-нибудь знает о существующей функции для расчета даты Пасхи за данный год?
Конечно, возможно, не все , что трудно; Я просто подумал, что попрошу, если кто-то это сделает. (И это кажется очень вероятным.)
ОБНОВЛЕНИЕ: На самом деле, я действительно ищу дату Страстной пятницы (в пятницу до Пасхи)... Я просто подумал, что Пасха заставит меня туда. А так как я в США, я предполагаю, что ищу католическую Пасху? Но, возможно, кто-то может исправить меня, если я ошибаюсь.
* Под "сумасшедшим" я подразумевал, например, участие. Ничего оскорбительного...
Ответы
Ответ 1
в SQL Server Пасхальное воскресенье будет выглядеть следующим образом: прокрутите вниз в Страстную пятницу
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
Страстная пятница похожа на это, и она использует функцию Пасхи выше
CREATE FUNCTION dbo.GetGoodFriday
(
@Y INT
)
RETURNS SMALLDATETIME
AS
BEGIN
RETURN (SELECT dbo.GetEasterSunday(@Y) - 2)
END
GO
Отсюда: http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
Ответ 2
Python: используя функцию dateutil easter()
.
>>> from dateutil.easter import *
>>> print easter(2010)
2010-04-04
>>> print easter(2011)
2011-04-24
Функции получают в качестве аргумента тип расчета, который вам нравится:
EASTER_JULIAN = 1
EASTER_ORTHODOX = 2
EASTER_WESTERN = 3
Вы можете выбрать тот, который относится к США.
Сокращение двух дней от результата даст вам Страстную пятницу:
>>> from datetime import timedelta
>>> d = timedelta(days=-2)
>>> easter(2011)
datetime.date(2011, 4, 24)
>>> easter(2011)+d
datetime.date(2011, 4, 22)
Как ни странно, кто-то повторял это и опубликовал результаты в статью Википедии об алгоритме:
![alt text]()
Ответ 3
Когда мне пришло в голову написать это (предсказание трафика в зависимости от дня недели и праздника)
Я сдался, пытаясь написать его сам. Я нашел его где-то в сети. Код был общедоступным, но...
вздыхать
убедитесь сами.
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
}
Некоторые вопросы лучше оставить незанятыми.
Мне повезло, что все переходящие праздники в моей стране являются фиксированным смещением от даты Пасхи.
Ответ 4
Функция SQL Server ниже является более общей, чем принятый ответ
Принятый ответ верен только для диапазона (включительно): 1900-04-15 до 2099-04-12
Он использует алгоритм, предоставленный Военно-морской обсерваторией Соединенных Штатов (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