April 6th, 2011

2017

Yearfrac

В MatLab есть замечательная функция yearfrac, которая возвращает разницу между двумя датами, выраженную в годах. При этом у функции есть третий параметр, правило подсчёта разницы — в финансах регулярно используются довольно экзотические правила, рудименты докомпьютерной эпохи. Например, между 1 январём и 1 февралём может быть 1/12 года (правило 30/360), 31/365 (правило actual/365) или иногда 31/365, а иногда 31/366, в зависимости от високосности года (правило actual/actual). Правил несколько десятков, но в нормальных условиях всегда используется правило actual/actual, это значение параметра by default.

А только что я обнаружил ужасный баг в этой, казалось бы, простой функции. Если посчитать разницу между 01/01/2007 года и 01/01/2009 года (здесь и далее только actual/actual), то функция выдаёт значение 731/365. Между 01/01/2008 года и 01/01/2010 года — 731/366. И только между 01/01/2009 и 01/01/2011 получаем разумный результат — ровно 2 года.

То есть авторы проверяют, есть ли 29 число в первом феврале промежутка, и если да, то все годы объявляются високосными, если нет — то все невисокосными. Понятно, что функцию писали из рассчёта на её использование внутри одного года, но в документации об этом ограничении ни слова!

P.S. К слову, поведение аналогичной функции Excel я вообще не понимаю. Первые два примера дают 731/365,333 (откуда берётся 365 1/3 дня?!), последний — уверенное 2.