Праздники в календарях или кто больше всех работает


    Грядут новогодние каникулы… и самое время поговорить о праздниках. При разработке приложения с поддержкой праздничных дат встает ряд вопросов: каким способом можно получить такие данные и откуда, как их использовать и обрабатывать?


    В данной статье я хочу рассказать о ресурсах, связанных с праздниками, и поделиться личным опытом их применения в популярных сервисах и программах. Варианты работы с этими сервисами я буду рассматривать на примере нашего планировщика XtraScheduler. А в конце статьи приведу небольшую статистику по праздникам для различных стран мира.


    Онлайн-ресурсы


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

    В рунете одним из таким ресурсом является "Календарь событий" (http://www.calend.ru/), где можно найти информацию о государственных, профессиональных, религиозных и других праздниках, разбитых по категориям. Все они представлены в виде ics-файлов формата iCalendar, которые можно использовать в своих приложениях.


    В качестве других примеров приведу ресурсы, которые представляет Яндекс календарь: Apple.com, Mozilla.org, iCalShare.com. Они также содержат коллекции общедоступных ics-файлов.

    Наш планировщик XtraScheduler может импортировать данные из формата iCalendar, поэтому вы можете использовать любые из перечисленных выше ресурсов. Для этого мы используем класс iCalendarImporter из отдельной сборки DevExpress.XtraScheduler.v10.2.iCalendarExchange.dll. В ней реализован весь необходимый функционал загрузки из ics-файла и создания объектов календаря.

    Предустановленные праздники


    Помимо предложенных ресурсов, Яндекс календарь также содержит предопределённые праздничные даты. На навигаторе дат и на различных видах они отмечены красным цветом и имеют подсказку с описанием. Радует наличие переносов рабочих дней — даже несмотря на то, что не всегда цвет даты в навигаторе соответствует цвету даты в самом календаре.


    Так как XtraScheduler является компонентом, то хранить в нём предустановленный набор дат не имеет смыла. Это объясняется тем, что ситуация с праздниками меняется год от года и требования, предъявляемые пользователями, могут отличаться в зависимости от страны или сценария использования. Поэтому вместо того, чтобы вводить фиксированный набор праздников, мы предоставили пользователю свойство-коллекцию для этого набора дат и дали возможность самому определять список рабочих дней, праздников и «рабочих» выходных.
    public WorkDaysCollection WorkDays { get {... } }
    

    Ниже приведен следующий набор классов-элементов этой коллекции, который «перекрывает» все варианты использования выходных дней.
    public abstract class WorkDay : ICloneable {
        public abstract bool IsWorkDay(DateTime date);
    }
    public class WeekDaysWorkDay : WorkDay {
        public WeekDays WeekDays {get { ...} }
    }
    public abstract class KnownDateDay : WorkDay {
        public string DisplayName { get { ... } set { ... } }
        public DateTime Date { get { ... } }
    }
    public class Holiday : KnownDateDay {
        public string Location { get { ...} set { ... } }
    }
    public class ExactWorkDay : KnownDateDay { 
    }
    

    Праздники как события календаря


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

    Вернёмся к Яндекс календарю. При первом рассмотрении я не нашёл, как добавить праздники в календарь, хотя ожидал увидеть упоминание о праздниках где-то рядом с Афишей и Телепрограммой. Зато нашёл универсальный способ добавления любых событий (включая праздники), используя импорт из ics-файла. Полученный список можно импортировать либо в новый, либо в уже существующий календарь.

    Я попробовал выполнить импорт списка «Международных праздников» (http://www.calend.ru/img/export/ical-wholeworld.ics) с описанного выше ресурса.
    К сожалению, с импортом выбранного календаря Яндекс не смог справиться (хотя, мягко говоря, формат предложенного файла не идеален). Зато импорт с ресурсов, предложенным самим Яндексом, работает отлично.

    В Google Календаре дело обстоит несколько иначе. Наряду с импортом календарей из файла, импортом по указанной по ссылке, импортом из другой учётной записи существует и ещё один вариант.



    Мы сразу видим список «Другие календари» и открыв пункт меню «Посмотреть интересные календари» (кстати, интересное выбрано название меню) мы попадём в целую коллекцию разнообразных календарных событий, включая спорт, фазы луны и т.д. Одним из них является список предустановленных праздников — примерно по 30 странам.



    Достаточно лишь выбрать необходимый и нажать «подписаться» — и список календарных событий будет добавлен как отдельный календарь. При этом будет добавлено событие на день и, как следствие, появится выделение соответствующей даты жирным шрифтом на навигаторе дат.

    Кстати, Google с задачей импорта нашего файла «Международных праздников» справился успешно.

    XtraScheduler при импорте праздников из ics-файла также создаёт отдельные события на целый день. Как можно это использовать? Достаточно включить опцию, запрещающую иметь пересекающиеся во времени события:
    schedulerControl1.OptionsCustomization.AllowAppointmentConflicts = AppointmentConflictsMode.Forbidden;
    

    и в этот праздничный день невозможно будет создать любое другое мероприятие.

    Праздники в десктопных приложениях


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

    Одним из источников, при наличии установленного Microsoft Office, является файл outlook.hol, который расположен в подпапках установленного продукта, например, здесь: C:\Program Files\Microsoft Office\Office12\1049\outlook.hol"

    Данные в этом файле разбиты по секциям-странам и содержат фиксированный список строк, представляющих праздники на несколько лет назад и вперёд.

    ...
    [Россия] 84
    Новогодние каникулы,2006/1/1
    Новогодние каникулы,2007/1/1
    Новогодние каникулы,2008/1/1
    Новогодние каникулы,2009/1/1
    Новогодние каникулы,2010/1/1
    Новогодние каникулы,2011/1/1
    Новогодние каникулы,2012/1/1
    ...
    

    В версии офиса 2010 данные о праздниках представлены с 2009 до 2028 года…

    Именно эти данные используются в Outlook Calendar. В параметрах календаря можно добавить праздники для указанной страны. При этом праздники будут также добавлены как физические события календаря.



    Остановимся на том, как определяется строка-праздник в этом файле. Строка, хранящая информацию о празднике, состоит из его названия, даты и идентификатора календаря. Заметьте, что для ряда стран, где даты представлены не только в Григорианском календаре, необходимо выполнять преобразования дат.
    ...
    [Алжир] 42
    ...
    День рождения пророка Магомета,1424/3/12,6
    ...
    


    Такие преобразования дат несложно сделать встроенными средствами, если вы используете .NET.

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

    Количество поддерживаемых календарей для выполнения преобразований видно из кода ниже.
    public class OutlookHolidaysLoader {
        #region CalendarTypes consts
        internal const int CAL_GREGORIAN = 1;
        internal const int CAL_GREGORIAN_ARABIC = 10;
        internal const int CAL_GREGORIAN_ME_FRENCH = 9;
        internal const int CAL_GREGORIAN_US = 2;
        internal const int CAL_GREGORIAN_XLIT_ENGLISH = 11;
        internal const int CAL_GREGORIAN_XLIT_FRENCH = 12;
        internal const int CAL_HEBREW = 8;
        internal const int CAL_HIJRI = 6;
        internal const int CAL_JAPAN = 3;
        internal const int CAL_JULIAN = 13;
        internal const int CAL_KOREA = 5;
        internal const int CAL_TAIWAN = 4;
        internal const int CAL_THAI = 7;
        #endregion
    
        internal const int DefaultCalendarType = CAL_GREGORIAN;
    
        public string[] ExtractLocations(string fileName) { }
        public string[] ExtractLocations(Stream stream) { }
        public HolidayBaseCollection FromFile(string fileName) {  }
        public HolidayBaseCollection FromFile(string fileName, string[] locations) { }
        public HolidayBaseCollection FromFile(string fileName, Encoding encoding, string[] locations) { }
        public HolidayBaseCollection FromStream(Stream stream) { }
        public HolidayBaseCollection FromStream(Stream stream, string[] locations) { }
        public HolidayBaseCollection FromStream(Stream stream, Encoding encoding, string[]) { }
    }
    

    Аналогичный функционал праздников получили такие продукты как ASPxScheduler и DXScheduler for WPF.
    Как это работает в ASPxScheduler, вы можете посмотреть в нашей онлайн-демо.

    Помимо загрузки из iCalendar и outlook.hol наш планировщик может загружать и сохранять коллекцию праздников в формате XML.
        //...
        HolidayBaseCollection holidays = HolidayCollectionXmlPersistenceHelper.ObjectFromXml(string xml);
        //....
        new HolidayCollectionXmlPersistenceHelper(holidays).ToXml();
    


    Где еще может понадобиться поддержка праздников в приложениях? Один из возможных сценариев — фильтрация ненужных дней при показе большого списка временнЫх данных. В качестве примера приведу продукт XtraCharts, который вслед за нашими планировщиками реализовал поддержку выходных дней и праздников для выбрасывания ненужных дат в сериях.

    Немного аналитики


    В качестве бонуса приведу немного статистических данных, полученных из файла Outlook-а. Я загрузил файл outlook.hol с праздниками, отфильтровал даты по 2010 году и визуализировал результаты, при этом подсчитав их количество в году для разных стран.

    Следующая диаграмма показывает распределение количества государственных праздников по странам в 2010 году:


    Полный список количества праздников по странам отражен на легенде ниже:


    Если не брать во внимание религиозные праздники, то нетрудно заметить, что лидирующее положение по количеству праздников занимают такие страны как
    Китай, Канада и Соединенные Штаты Америки.

    Минимальное число праздников у Евроcоюза, Ливии, Индии, Малайзии.

    Россия занимает среднее положение со значением 12.

    Конечно надо понимать, что эти цифры показывают только официальные праздники и никак не отражают реальную картину общего количества выходных. Так что делать какие-либо выводы (например, кто самая «празднующая» страна, а кто — «страна-трудоголик») предоставлю вам… :-)

    ВСЕХ С НАСТУПАЮЩИМ НОВЫМ ГОДОМ!!!
    Developer Soft
    0,00
    Компания
    Поделиться публикацией

    Похожие публикации

    Комментарии 24

      +5
      Бедные индусы :) С наступающим всех!
        +1
        Евросоюз «1» — видимо надо прибавлять к кол-ву праздников каждой страны Евросоюза? Тогда фраза «Минимальное число праздников у Евроcоюза» не совсем корректна…
          +2
          Тут День Европы , который 9 мая, считается официальным. Согласен, что Евросоюз стоит в списке обособленно, но справедливости ради посчитал уместным его посчитать ;)
          +3
          … и никак не отражают реальную картину общего количества выходных…

          А я как раз таки статистику по выходным и ожидал увидеть =(.
          Может название тогда стоило бы другое придумать.
            +2
            Я бы и сам не отказался взглянуть, но выходные — вообще понятие размытое, впрочем как количественный показатель работы ;)
            0
            Сегодня праздновал день сурка. Опять.
              –1
              Откуда такая информация по Китаю? Только 7 официальных общеотмечаемых праздников.
                +1
                Данные взяты их файла outlook.hol из MS Office2010.
                По этим данным в Китае 42 праздника:
                [China]
                National Day (1st day),2010/10/1
                National Day (2nd Day),2010/10/2
                National Day (3rd Day),2010/10/3
                Labor Day,2010/5/1
                Slight cold,2010/1/5
                Great cold,2010/1/20
                Spring begins,2010/2/4
                The rains,2010/2/19
                Insects awaken,2010/3/6
                Vernal Equinox,2010/3/21
                Clear and bright,2010/4/5
                Grain rain,2010/4/20
                Summer begins,2010/5/5
                Grain buds,2010/5/21
                Grain in ear,2010/6/6
                Summer solstice,2010/6/21
                Slight heat,2010/7/7
                Great heat,2010/7/23
                Autumn begins,2010/8/7
                Stopping the heat,2010/8/23
                White dews,2010/9/8
                Autumn Equinox,2010/9/23
                Cold dews,2010/10/8
                Hoar-frost falls,2010/10/23
                Winter begins,2010/11/7
                Light snow,2010/11/22
                Heavy snow,2010/12/7
                Winter Solstice,2010/12/22
                Army's Day,2010/8/1
                Children's Day,2010/6/1
                Chinese New Year (1st day),2010/2/14
                Chinese New Year (2nd day),2010/2/15
                Dragon Boat Festival,2010/6/16
                Chinese New Year's Eve,2010/2/13
                Chinese Mid-Autumn Festival,2010/9/22
                New Year's Day,2010/1/1
                Women's Day,2010/3/8
                Youth Day,2010/5/4
                Party's Day,2010/7/1
                Lantern Festival,2010/2/12
                Double Ninth Festival,2010/10/30
                Tomb Sweeping Day,2010/4/5
                  –1
                  Spring begins,2010/2/4
                  The rains,2010/2/19 — это вот просто рандомные праздники. Вы хотите сказать, что они государственные и отмечаются всей страной? С таким же успехом можно взять какой-нибудь День архивов 10-го марта, День работника культуры 25-го, День специалиста юридической службы и так далее.
                    +3
                    Это вопрос скорее к разработчикам офиса, а не ко мне… Касательно России, так все в порядке с «государственностью». Что есть, то я и отобразил, ничего своего не добавлял и не выбрасывал.
                +3
                В Штатах вообще понятие «праздники» условное — никто не обязан предоставлять выходной день в праздник. Обязательно выходные получают госслужащие, все остальные — согласно условиям личного контракта.
                  0
                  usa www.madmanmike.com/us_holidays_dates.html тоже откуда 24?
                    0
                    День профессиональных секретарей,2003/4/23
                    Рождество,2003/12/25
                    Сочельник,2003/12/24
                    День Колумба,2003/10/13
                    Пасха,2003/4/20
                    День выборов,2003/11/4
                    День отцов,2003/6/15
                      +1
                      Извините за преждевременный коммит… Вот список по 2010 году. Кстати, странновато, что День сурка там тоже фигурирует.

                      [United States]
                      Christmas Day,2010/12/25
                      Christmas Eve,2010/12/24
                      Columbus Day,2010/10/11
                      Easter Day,2010/4/4
                      Election Day,2010/11/2
                      Flag Day,2010/6/14
                      Groundhog Day,2010/2/2
                      Halloween,2010/10/31
                      Independence Day,2010/7/4
                      Labor Day,2010/9/6
                      Lincoln's Birthday,2010/2/12
                      Martin Luther King Day,2010/1/18
                      Memorial Day,2010/5/31
                      Mother's Day,2010/5/9
                      New Year's Day,2010/1/1
                      New Year's Eve,2010/12/31
                      Saint Patrick's Day,2010/3/17
                      Tax Day,2010/4/15
                      Thanksgiving Day,2010/11/25
                      Valentine's Day,2010/2/14
                      Veteran's Day,2010/11/11
                      Administrative Professionals Day,2010/4/21
                      Presidents' Day,2010/2/15
                        0
                        Половина из этих «праздников» — НЕ выходные дни
                    +3
                    Беларуси нет.
                      +1
                      Непорядок, надо им реквест зарепорnить :-)
                      +1
                      Что-то слишком хорошо в США, реально гос. служащие праздновали (гуляли) в 2010 году 13 дней.
                      Календарик для множества стран тут: timeanddate.com/calendar/
                        +2
                        Не спорю. Немного погуглив нашел следующее :

                        "… в США нет федеральных (общегосударственных) праздников. Каждый из 50 штатов сам провозглашает свои праздники. Однако на практике в большинстве штатов отмечаются федеральные («официальные» или «государственные») праздники, хотя по закону президент и Конгресс вводят праздничные дни только для государственных служащих федерального правительства."

                        По этой версии федеральных праздников 10 штук. Видимо в офисный список включены наиболее распространенные для разных штатов, хотя истину в первой инстанции на не претендую.
                          0
                          Это правда. Обычно в любой компании базовыми являются 12 дней.

                          Christmas Day,2010/12/25
                          Columbus Day,2010/10/11 (и то — не у всех)
                          Easter Day,2010/4/4
                          Election Day,2010/11/2
                          Independence Day,2010/7/4
                          Labor Day,2010/9/6
                          Martin Luther King Day,2010/1/18
                          Memorial Day,2010/5/31
                          New Year's Day,2010/1/1
                          Thanksgiving Day,2010/11/25
                          Veteran's Day,2010/11/11
                          Presidents' Day,2010/2/15
                            0
                            (см. мой комментарий выше) правда что федеральных праздников «около» 10 — 12. В Вики вполне нормально написано: en.wikipedia.org/wiki/Federal_holidays_in_the_United_States
                          +2
                          евреем чтоль стать или китайцем хм…
                            0
                            многие из еврейских религиозных праздников не являются выходными. нет смысла:)
                            0
                            Во многих странах праздники «сгорают» при попадании на выходной день.

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое