Quantcast
Channel: Perl — shoorick.ru
Viewing all articles
Browse latest Browse all 38

30 или 31

$
0
0

Писал как-то на перле валидатор дат и додумался до формулы, вычисляющей число дней в месяце — она заказчику не пригодилась, и была выкинута из кода ради сомнительной простоты, так что буду думать эту мысль ещё раз.

Итак, в языках с си-подобным синтаксисом (хотя подойдёт и для питона) определить, сколько же дней в месяце, можно по формуле

days = 30 + (month + 4) * 13 / 12 % 2

где month — номер месяца начиная с 1.

Работает для всех месяцев кроме февраля. Например, перловый однострочник

perl -e 'printf "%2d → %d\n", $_, 30 + ($_ + 4) * 13 / 12 % 2 for 1 .. 12'

выведет

 1 → 31
 2 → 30
 3 → 31
 4 → 30
 5 → 31
 6 → 30
 7 → 31
 8 → 31
 9 → 30
10 → 31
11 → 30
12 → 31

С февралём ситуация чуть более сложная, потому что число дней в нём зависит от номера года: в григорианском календаре високосным годом является такой, который делится на 4, но не на 100, хотя если при этом делится на 400 — всё равно високосный. Например, 1900 год — обычный, а 2000 — високосный, как и 2004.

year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)

можно вообще переписать как

!!(!(year % 4) && ((year % 100) || !(year % 400)))

однако такой вариант хуже — хоть и компактнее, но менее понятен.

Проверим (в перле «из коробки» нет булевых типов, поэтому выводятся нули и единицы)

1600 → 1
1700 → 0
1799 → 0
1800 → 0
1899 → 0
1900 → 0
1901 → 0
1944 → 1
1988 → 1
1999 → 0
2000 → 1
2001 → 0
2004 → 1

Осталось объединить всё в одну формулу


Viewing all articles
Browse latest Browse all 38

Latest Images

Trending Articles





Latest Images