From b477e59d2daa8e272f5ad679c94cd886b3ce4d4d Mon Sep 17 00:00:00 2001 From: vincent <vincent@groupe-sa.fr> Date: Mon, 4 Jan 2016 14:08:38 +0100 Subject: [PATCH] Add Holiday management (France only). --- src/CMakeLists.txt | 1 + src/holiday.cpp | 56 +++++++++++++++++++++++++++++++++++ src/holiday.hpp | 13 ++++++++ test/CMakeLists.txt | 1 + test/holiday_test.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++ test/holiday_test.hpp | 15 ++++++++++ 6 files changed, 155 insertions(+) create mode 100644 src/holiday.cpp create mode 100644 src/holiday.hpp create mode 100644 test/holiday_test.cpp create mode 100644 test/holiday_test.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5fac8ff..ddd657b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ set(${PROJECT}_SRC_FILES qcron.cpp qcronfield.cpp qcronnode.cpp + holiday.cpp ) set(${PROJECT}_HEADERS diff --git a/src/holiday.cpp b/src/holiday.cpp new file mode 100644 index 0000000..3276839 --- /dev/null +++ b/src/holiday.cpp @@ -0,0 +1,56 @@ +#include "holiday.hpp" + +#include <QList> + +/******************************************************************************/ + +bool +Holiday:: +isHoliday(const QDate & today) +{ + int y = today.year(); + QList<QDate> holidays = QList<QDate>() + << QDate(y, 1, 1) // Jour de l'an + << QDate(y, 5, 1) // Fete du travail + << QDate(y, 5, 8) // Fete de la victoire + << QDate(y, 7, 14) // Fete nationale + << QDate(y, 8, 15) // Assomption + << QDate(y, 11, 1) // Toussaint + << QDate(y, 11, 11) // Armistice de 1918 + << QDate(y, 12, 25) // Noel + ; + QDate easter = Holiday::easter(y); + + return holidays.contains(today) || + today == easter.addDays(1) || // Lundi de Paques + today == easter.addDays(39) || // Jeaudi de l'Ascension + today == easter.addDays(50) // Lundi de Pentecote + ; +} + +/******************************************************************************/ + +QDate +Holiday:: +easter(int y) +{ + /* Many thanks to http://www.henk-reints.nl/easter/index.htm */ + int a = y % 19 + 1; + int b = y / 100 + 1; + int c = (3 * b) / 4 - 12; + int d = (8 * b + 5) / 25 - 5; + int e = (y * 5) / 4 - 10 - c; + int f = ((11 * a + 20 + d - c) % 30 + 30) % 30; + if (24 == f || (25 == f && a > 11)) + { + ++f; + } + int g = 44 - f; + if (g < 21) + { + g += 30; + } + return QDate(y, 3, 1).addDays(g + 7 - (e + g) % 7 - 1); +} + +/******************************************************************************/ diff --git a/src/holiday.hpp b/src/holiday.hpp new file mode 100644 index 0000000..03f1c87 --- /dev/null +++ b/src/holiday.hpp @@ -0,0 +1,13 @@ +#ifndef _HOLIDAY_HPP +#define _HOLIDAY_HPP + +#include <QDate> + +class Holiday +{ +public: + static bool isHoliday(const QDate & date); + static QDate easter(int year); +}; + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ba1fc03..be4cd31 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,7 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/test) set(TESTS qcron_test syntax_test + holiday_test ) foreach(test ${TESTS}) diff --git a/test/holiday_test.cpp b/test/holiday_test.cpp new file mode 100644 index 0000000..5c067cb --- /dev/null +++ b/test/holiday_test.cpp @@ -0,0 +1,69 @@ +#include "holiday_test.hpp" + +#include <holiday.hpp> + +#include <QTest> + +void +HolidayTest:: +easter() +{ + QCOMPARE(Holiday::easter(2000), QDate(2000, 4, 23)); + QCOMPARE(Holiday::easter(2001), QDate(2001, 4, 15)); + QCOMPARE(Holiday::easter(2002), QDate(2002, 3, 31)); + QCOMPARE(Holiday::easter(2003), QDate(2003, 4, 20)); + QCOMPARE(Holiday::easter(2004), QDate(2004, 4, 11)); + QCOMPARE(Holiday::easter(2005), QDate(2005, 3, 27)); + QCOMPARE(Holiday::easter(2006), QDate(2006, 4, 16)); + QCOMPARE(Holiday::easter(2007), QDate(2007, 4, 8)); + QCOMPARE(Holiday::easter(2008), QDate(2008, 3, 23)); + QCOMPARE(Holiday::easter(2009), QDate(2009, 4, 12)); + QCOMPARE(Holiday::easter(2010), QDate(2010, 4, 4)); + QCOMPARE(Holiday::easter(2011), QDate(2011, 4, 24)); + QCOMPARE(Holiday::easter(2012), QDate(2012, 4, 8)); + QCOMPARE(Holiday::easter(2013), QDate(2013, 3, 31)); + QCOMPARE(Holiday::easter(2014), QDate(2014, 4, 20)); + QCOMPARE(Holiday::easter(2015), QDate(2015, 4, 5)); + QCOMPARE(Holiday::easter(2016), QDate(2016, 3, 27)); + QCOMPARE(Holiday::easter(2017), QDate(2017, 4, 16)); + QCOMPARE(Holiday::easter(2018), QDate(2018, 4, 1)); + QCOMPARE(Holiday::easter(2019), QDate(2019, 4, 21)); + QCOMPARE(Holiday::easter(2020), QDate(2020, 4, 12)); + QCOMPARE(Holiday::easter(2021), QDate(2021, 4, 4)); + QCOMPARE(Holiday::easter(2022), QDate(2022, 4, 17)); + QCOMPARE(Holiday::easter(2023), QDate(2023, 4, 9)); + QCOMPARE(Holiday::easter(2024), QDate(2024, 3, 31)); + QCOMPARE(Holiday::easter(2025), QDate(2025, 4, 20)); + QCOMPARE(Holiday::easter(2026), QDate(2026, 4, 5)); + QCOMPARE(Holiday::easter(2027), QDate(2027, 3, 28)); + QCOMPARE(Holiday::easter(2028), QDate(2028, 4, 16)); + QCOMPARE(Holiday::easter(2029), QDate(2029, 4, 1)); + QCOMPARE(Holiday::easter(2030), QDate(2030, 4, 21)); + +} + +/******************************************************************************/ + +void +HolidayTest:: +holiday() +{ + QVERIFY(Holiday::isHoliday( QDate(2016, 1, 1))); + QVERIFY(Holiday::isHoliday( QDate(2016, 5, 1))); + QVERIFY(Holiday::isHoliday( QDate(2016, 5, 8))); + QVERIFY(Holiday::isHoliday( QDate(2016, 7, 14))); + QVERIFY(Holiday::isHoliday( QDate(2016, 8, 15))); + QVERIFY(Holiday::isHoliday( QDate(2016, 11, 1))); + QVERIFY(Holiday::isHoliday( QDate(2016, 11, 11))); + QVERIFY(Holiday::isHoliday( QDate(2016, 12, 25))); + QVERIFY(Holiday::isHoliday( QDate(2016, 3, 28))); // Lundi de Paques + QVERIFY(Holiday::isHoliday( QDate(2016, 5, 5))); // Jeudi de l'Ascension + QVERIFY(Holiday::isHoliday( QDate(2016, 5, 16))); // Lundi de Pentecote + + // Chuck Norris' birthday (should be a holiday though). + QVERIFY(!Holiday::isHoliday(QDate(2016, 3, 10))); +} + +/******************************************************************************/ + +QTEST_MAIN(HolidayTest) diff --git a/test/holiday_test.hpp b/test/holiday_test.hpp new file mode 100644 index 0000000..83d9377 --- /dev/null +++ b/test/holiday_test.hpp @@ -0,0 +1,15 @@ +#ifndef _HOLIDAY_TEST_HPP +#define _HOLIDAY_TEST_HPP + +#include <QObject> + +class HolidayTest : public QObject +{ + Q_OBJECT + +private slots: + void easter(); + void holiday(); +}; + +#endif