Author Topic: Распределение даты по дням недели  (Read 393 times)

0 Members and 1 Guest are viewing this topic.

Offline RawonaM

  • Posts: 43519
Я читал, что парадоксальным образом первое января чаще других дней недели выпадает на воскресенье.
А в чем парадоскальность? Тем более, что это неправда. Заинтересовало, скриптик написал:

Code: [Select]
>>> import datetime
>>> count = {}
>>> for year in range(1, 2020):
...     weekday = datetime.datetime(year, 1, 1).weekday()
...     count[weekday] = count[weekday]+1 if weekday in count else 1
...
>>> count
{0: 283, 1: 294, 2: 287, 3: 288, 4: 292, 5: 282, 6: 293}

На вторник больше всего.

А вот почему на субботу всего 282 раза, а на вторник 294 раза? Вроде должно одинаково выпадать. Каждый год на один вперед сдвигается, а каждый високосный еще на один, должно быть примерно одинаково.

В годах 1 по 9999 такое распределение:
Code: [Select]
{0: 2800, 1: 2900, 2: 2850, 3: 2850, 4: 2899, 5: 2798, 6: 2900}

Очевидно связано с тем, что дней недели 7, а високосные года каждые четыре.

Offline злой

  • Posts: 12681
  • Gender: Male
В годах 1 по 9999 такое распределение:
Code: [Select]
{0: 2800, 1: 2900, 2: 2850, 3: 2850, 4: 2899, 5: 2798, 6: 2900}

Очевидно связано с тем, что дней недели 7, а високосные года каждые четыре.

Может если сделать 100 тысяч лет, то воскресенье ещё на один день чаще будет выпадать?
Почему в списке Сводеша нет слова "любовь"?   Mike Validation

Offline Hellerick

  • Posts: 28580
  • Gender: Male
La calendario de Gregorio ave un sicle de 400 anios = 146074 dias = 20871 semanas. Esamina un periodo plu longa no es razonable.

У Григорианского календаря цикл 400 лет = 146097 дней = 20871 недель. Более долгий период проверять не имеет смысла.

{0: 56, 1: 58, 2: 57, 3: 57, 4: 58, 5: 56, 6: 58}

Offline RawonaM

  • Posts: 43519
Может если сделать 100 тысяч лет, то воскресенье ещё на один день чаще будет выпадать?

Да нет, цикл состоит из 28 (=4х7) лет:
Code: [Select]
0 1 2 3 в 5 6 0 1 в 3 4 5 6 в 1 2 3 4 в 6 0 1 2 в 4 5 6 0 в 2 3 4 5 в (0 1 2 3 в ...)
Дальше все повторяется. Достаточно посчитать распределение за первые 28 лет и дальше уже все понятно хоть до бесконечности.

Code: [Select]
{0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 3, 6: 4}
То есть все по 4 и только суббота 3 раза.

Если вы работаете в месте, где нужно сманипулировать данные, то можно взять с середины цикла по середину цикла, так, как вам будет удобно, и результат получится.

Code: [Select]
>>> for year in range(6, 13+28*10):
...     weekday = datetime.datetime(year, 1, 1).weekday()
...     count[weekday] = count[weekday]+1 if weekday in count else 1
...
>>> count
{0: 41, 1: 44, 2: 40, 3: 44, 4: 44, 5: 42, 6: 45}

Вот если брать с 6 года по 12-ый, а потом добавить любое произвольное количество циклов для красоты, то выйдет на 1 больше. :)

Offline Hellerick

  • Posts: 28580
  • Gender: Male
Да нет, цикл состоит из 28 (=4х7) лет:

Lo es la calendario de Julio. Me suspeta ce ante la anio 1582 python trata datos como julian.

Это юлианский календарь. Подозреваю, что до 1582 года питон трактует даты как юлианские.

Offline RawonaM

  • Posts: 43519
Вот если брать с 6 года по 12-ый, а потом добавить любое произвольное количество циклов для красоты, то выйдет на 1 больше.
Нет, там я все равно ошибся, не тот результат подсунул, но принцип понятен. Что-то меня эта задачка слишком увлекла, надо отвлечся :)

Offline злой

  • Posts: 12681
  • Gender: Male
Вот если брать с 6 года по 12-ый, а потом добавить любое произвольное количество циклов для красоты, то выйдет на 1 больше.
Нет, там я все равно ошибся, не тот результат подсунул, но принцип понятен. Что-то меня эта задачка слишком увлекла, надо отвлечся :)
Я давным-давно читал, что стандартная юниксовая программа date знает, что в 1500-каком-то году у англичан был переход с юлианского на григорианский календарь, и показывает дни недели с учётом того, что несколько дней выпало. Возможно, на ваш алгоритм этот факт оказывает влияние, я не знаю, что за datetime в Питоне.
Почему в списке Сводеша нет слова "любовь"?   Mike Validation

Offline Hellerick

  • Posts: 28580
  • Gender: Male
Я давным-давно читал, что стандартная юниксовая программа date знает, что в 1500-каком-то году у англичан был переход с юлианского на григорианский календарь, и показывает дни недели с учётом того, что несколько дней выпало. Возможно, на ваш алгоритм этот факт оказывает влияние, я не знаю, что за datetime в Питоне.

La engleses ave lo en anio 1752. En anio 1500-e-alga lo ia es aveda par la paises catolica. En cuando en la SU/Rusia la abitua es retrotiva cambia tota la datas a la stilo nova, en la paises ueste la abitua scrive la datas seguente la calendario asetada alora.

У англичан это было в 1752 году. В 1500-каком-то было у католических стран. Если в СССР/России принято задним числом переводить все даты на новый стиль, в западных странах принято даты указывать по действовавшему на тот момент календарю.

Offline RawonaM

  • Posts: 43519
Вчера не давала мне покоя эта задачка, много мы ошибок наделали.

Да нет, цикл состоит из 28 (=4х7) лет:
...
То есть все по 4 и только суббота 3 раза.
На самом деле каждый по 4 (ошибся конечным индексом).
Итак повторяется каждые 28 лет, то есть в Юлианском календаре распределение 100% равномерное. Очевидно становится, что неравномерность в этом цикле появляется только в Григорианском календаре.

:)
Я давным-давно читал, что стандартная юниксовая программа date знает, что в 1500-каком-то году у англичан был переход с юлианского на григорианский календарь, и показывает дни недели с учётом того, что несколько дней выпало. Возможно, на ваш алгоритм этот факт оказывает влияние, я не знаю, что за datetime в Питоне.
Оказывается питоновский дейттайм менее смышленый и ретроактивно считает все в Григорианском календаре.

Code: [Select]
>>> datetime.datetime(100, 2, 29)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day is out of range for month
>>> datetime.datetime(400, 2, 29)
datetime.datetime(400, 2, 29, 0, 0)
>>> datetime.datetime(1600, 2, 29)
datetime.datetime(1600, 2, 29, 0, 0)
>>> datetime.datetime(1500, 2, 29)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day is out of range for month
>>>

Итак смотрим:
Code: [Select]
x1:~/fun$ python weekdaycount.py 1 28
{0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 4, 6: 4}
x1:~/fun$ python weekdaycount.py 29 56
{0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 4, 6: 4}
x1:~/fun$ python weekdaycount.py 57 84
{0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 4, 6: 4}
x1:~/fun$ python weekdaycount.py 85 112
{0: 3, 1: 5, 2: 3, 3: 5, 4: 4, 5: 4, 6: 4}
x1:~/fun$ python weekdaycount.py 113 140
{0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 4, 6: 4}
x1:~/fun$ python weekdaycount.py 197 224
{0: 4, 1: 4, 2: 5, 3: 4, 4: 4, 5: 3, 6: 4}

Первые три цикла идеальное распределение, а потом входит григорианская ересь, пропуская високосный год в 100-ом году.
Дальше идет снова три хороших цикла, дальше на 200 снова хрень.

La calendario de Gregorio ave un sicle de 400 anios = 146074 dias = 20871 semanas. Esamina un periodo plu longa no es razonable.

У Григорианского календаря цикл 400 лет = 146097 дней = 20871 недель. Более долгий период проверять не имеет смысла.

{0: 56, 1: 58, 2: 57, 3: 57, 4: 58, 5: 56, 6: 58}
Действительно получается так, проверил скриптом отрезки в 400 лет, но теоретически так и не могу понять.
Ведь григорианский цикл в 400 лет не кратен юлианскому циклу в 28 лет, каждый григорианский пропуск високосного года сбивает юлианский цикл. Как в итоге они сходятся? Пока что не придумал.

А кажется понял, ведь получается, что в 400 лет кратно 7 дней, то есть каждый 1+400*х год начинается снова с понедельника сам по себе. Интересное совпадение.

Еще так можно посмотреть:

Code: [Select]
0 1 2 3 в 5 6 0 1 в [b]3[/b] 4 5 6 в 1 2 3 4 в 6 0 1 2 в 4 5 6 0 в 2 3 4 5 в (0 1 2 3 в ...)

Так как 401-ый год выпадает на 9-ый год в этом юлианском цикле, но при этом за 400 лет по-григориански было пропущено 3 високосных года, то следовательно этот девятый и будет не четверг, как в ю, а понедельник. И пошел новый цикл.

Распределение 29 февраля по дням недели в Григорианском цикле:

Code: [Select]
import datetime

def is_leapyear(year):
    if (year % 4) == 0:
       if (year % 100) == 0:
           if (year % 400) == 0:
               return True
           else:
               return False
       else:
           return True
    else:
       return False

count = {}

for y in range(1, 401):
    if is_leapyear(y):
        wd = datetime.datetime(y, 2, 29).weekday()
        count[wd] = count[wd]+1 if wd in count else 1

print count

$ python leapyear.py
{0: 15, 1: 13, 2: 15, 3: 13, 4: 14, 5: 14, 6: 13}

Более компактное определение високосного года:
Code: [Select]
def is_leapyear(year):
    return (year % 4) == 0 and ( (year % 100) != 0 or (year % 400) == 0 )

Offline Mona

  • Posts: 1205
  • Gender: Male
Интересно, что по старому стилю революция 17-го года случилась раньше революции по новому стилю. А Рождество по старому стилю отмечается позже Рождества по новому. Одно время хотел этот вопрос в "Что, где, когда" послать.

Offline Basil

  • Posts: 2102
  • Gender: Male
Интересно, что по старому стилю революция 17-го года случилась раньше революции по новому стилю. А Рождество по старому стилю отмечается позже Рождества по новому. Одно время хотел этот вопрос в "Что, где, когда" послать.
Так вроде разница только в 2000 году набежала, нет?
--
Если есть сомнения - значит сомнений нет.

Offline Mona

  • Posts: 1205
  • Gender: Male
Ничего в 2000-м не набежало, мы и до 2000-го ВОСР отмечали 7-го ноября по-новому, а не 25-го октября по-старому, а Рождество после реформы стали отмечать 8-го января по-старому, а не 25-го декабря по-новому :-). Так что противоречию больше ста лет. Хотя на самом деле оно только видимое.

Offline Basil

  • Posts: 2102
  • Gender: Male
Ничего в 2000-м не набежало, мы и до 2000-го ВОСР отмечали 7-го ноября по-новому, а не 25-го октября по-старому, а Рождество после реформы стали отмечать 8-го января по-старому, а не 25-го декабря по-новому :-). Так что противоречию больше ста лет. Хотя на самом деле оно только видимое.
А ну да, наоборот, в 2100 набежит разница и станет 14 дней, а не тринадцать.

Остальное не очень понял.

25 октября (ЮК) + 13 дней = 7 ноября (ГК) 
25 декабря (ЮК) + 13 дней = 7 января (ГК)

Quote
Рождество Христово

Русская, Грузинская, Сербская, и Польская православные церкви, а также Грекокатолическая церковь (в пределах Украины), старообрядцы и старостильные церкви празднуют 25 декабря по юлианскому календарю.

(wiki/ru) Рождество_Христово
Или вы не про Русскую церковь?

Quote
Константинопольская, Элладская, Болгарская и ряд иных поместных православных церквей празднуют 25 декабря по новоюлианскому календарю. Католическая и протестантские церкви — 25 декабря по григорианскому календарю. Армянская апостольская церковь — 6 января.
--
Если есть сомнения - значит сомнений нет.

Offline Hellerick

  • Posts: 28580
  • Gender: Male
Me ia conta la cuantia de dias de semana per cada dia 13 de mense. Par 400 nos ave tal statistica:
Посчитал, на какие дни недели выпадает 13-е число. За 400 лет набирается такая статистика:


Lun  Mar  Mer  Jov  Ven  Sat  Sol
ПН   ВТ   СР   ЧТ   ПТ   СБ   ВС
685  686  689  687  692  689  693

Offline Bhudh

  • Posts: 57091
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
И чем 13-е сильно отличается от других чисел?
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Hellerick

  • Posts: 28580
  • Gender: Male
Me ia vole sabe la cuantia de venerdi la 13.
Хотелось знать число пятниц тринадцатого.

Offline Mona

  • Posts: 1205
  • Gender: Male
Ничего в 2000-м не набежало, мы и до 2000-го ВОСР отмечали 7-го ноября по-новому, а не 25-го октября по-старому, а Рождество после реформы стали отмечать 8-го января по-старому, а не 25-го декабря по-новому :-). Так что противоречию больше ста лет. Хотя на самом деле оно только видимое.
А ну да, наоборот, в 2100 набежит разница и станет 14 дней, а не тринадцать.

Остальное не очень понял.

25 октября (ЮК) + 13 дней = 7 ноября (ГК) 
25 декабря (ЮК) + 13 дней = 7 января (ГК)

Quote
Рождество Христово

Русская, Грузинская, Сербская, и Польская православные церкви, а также Грекокатолическая церковь (в пределах Украины), старообрядцы и старостильные церкви празднуют 25 декабря по юлианскому календарю.

(wiki/ru) Рождество_Христово
Или вы не про Русскую церковь?

Quote
Константинопольская, Элладская, Болгарская и ряд иных поместных православных церквей празднуют 25 декабря по новоюлианскому календарю. Католическая и протестантские церкви — 25 декабря по григорианскому календарю. Армянская апостольская церковь — 6 января.

Вы абсолютно правильно математически сделали, что подписали ЮК и ГК, сразу стало все ясно. Но в человеческом языке революция по старому календарю раньше, чем по-новому, а Рождество по-старому - позже, чем по новому. Просто, сменив календарь, европейцы решили Рождество праздновать того же числа того же месяца, что и раньше, а русские православные решили его праздновать астрономически в тот же день, что и раньше, и вообще оставить все праздники и интервалы между ними так, как было, даже если они теперь по гражданскому календарю выпадают на непривычные даты.

Me ia vole sabe la cuantia de venerdi la 13.
Хотелось знать число пятниц тринадцатого.

А оказалось, что воскресений 13-го намного больше...

Offline Bhudh

  • Posts: 57091
  • Gender: Male
  • aka 蝎
    • Сайты по языкознанию
русские православные решили его праздновать астрономически в тот же день, что и раньше
Русские православные вообще не стали менять календарь.
Пиши, что думаешь, но думай, что пишешь.
MONEŌ ERGŌ MANEŌ.
Waheeba dokin ʔebi naha.
«каждый пост в интернете имеет коэффициент бреда» © Невский чукчо

Offline Mona

  • Posts: 1205
  • Gender: Male
Русские православные действительно не стали менять календарь и празднуют Рождество все так же 25-го декабря по церковному календарю, как и раньше (7-го января по гражданскому), а вот европейцы свое рождество празднуют хоть и 25-го декабря номинально, но на 13 дней раньше, чем праздновали до реформы, и там многие другие вещи тоже "поехали", "поплыли".

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Note: this post will not display until it's been approved by a moderator.
Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
√49 Напишите ответ строчными буквами:
«Сто одёжек, все без застёжек» — что это?: