diff options
author | Brendan Coles <bcoles@gmail.com> | 2021-01-07 15:58:57 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-08 09:42:43 +0100 |
commit | d0a9954f0e8393c0eb68ca53bd246ed10d137361 (patch) | |
tree | b6327cf4c553c8cc93cf3817a550986085b55874 | |
parent | fb9eb2054461fd5622e6a80c66af265fba8f62be (diff) | |
download | serenity-d0a9954f0e8393c0eb68ca53bd246ed10d137361.zip |
Userland: Add ddate utility
Today is Boomtime, day 7 of Chaos, in the YOLD 3187
-rw-r--r-- | Base/usr/share/man/man1/ddate.md | 20 | ||||
-rw-r--r-- | Userland/ddate.cpp | 132 |
2 files changed, 152 insertions, 0 deletions
diff --git a/Base/usr/share/man/man1/ddate.md b/Base/usr/share/man/man1/ddate.md new file mode 100644 index 0000000000..a8fdceab88 --- /dev/null +++ b/Base/usr/share/man/man1/ddate.md @@ -0,0 +1,20 @@ +## Name + +ddate - prints the current date in Discordian date format. + +## Synopsis + +```**sh +$ ddate +``` + +## Description + +ddate prints the current date in Discordian date format. + +## Examples + +```sh +$ ddate # Thu 07 Jan 2021 +Today is Boomtime, day 7 of Chaos, in the YOLD 3187 +``` diff --git a/Userland/ddate.cpp b/Userland/ddate.cpp new file mode 100644 index 0000000000..763a5a3493 --- /dev/null +++ b/Userland/ddate.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/String.h> +#include <LibCore/DateTime.h> +#include <stdio.h> + +class DiscordianDate { +public: + explicit DiscordianDate(Core::DateTime date) + { + m_gregorian_date = date; + m_yold = date.year() + 1166; + + uint16_t day = day_of_yold() + 1; + if (is_leap_year() && day > m_st_tibs_day_of_yold) + --day; + + m_day_of_week = day_of_week_from_day_of_yold(day); + m_season = season_from_day_of_yold(day); + m_date = date_from_day_of_yold(day); + } + + const char* day_of_week() { return m_day_of_week.characters(); }; + const char* season() { return m_season.characters(); }; + uint16_t year() { return yold(); }; + uint16_t yold() { return m_yold; }; + uint16_t day_of_year() { return day_of_yold(); }; + uint16_t day_of_yold() { return m_gregorian_date.day_of_year(); }; + bool is_leap_year() { return m_gregorian_date.is_leap_year(); }; + bool is_st_tibs_day() { return (is_leap_year() && (day_of_yold() + 1) == m_st_tibs_day_of_yold); }; + + String to_string() + { + if (is_st_tibs_day()) + return String::formatted("St. Tib's Day, in the YOLD {}", m_yold); + return String::formatted("{}, day {} of {}, in the YOLD {}", m_day_of_week, m_date, m_season, m_yold); + } + +private: + static const int m_days_in_week = 5; + static const int m_days_in_season = 73; + static const int m_st_tibs_day_of_yold = 60; + Core::DateTime m_gregorian_date; + String m_day_of_week; + String m_season; + int m_date; + uint64_t m_yold; // 64-bit for use after X-Day in the YOLD 8661 + + int date_from_day_of_yold(uint16_t day) + { + return (day % m_days_in_season == 0 ? m_days_in_season : day % m_days_in_season); + } + + const char* day_of_week_from_day_of_yold(uint16_t day) + { + if (is_st_tibs_day()) + return nullptr; + + switch ((day % m_days_in_week) == 0 ? m_days_in_week : (day % m_days_in_week)) { + case 1: + return "Sweetmorn"; + case 2: + return "Boomtime"; + case 3: + return "Pungenday"; + case 4: + return "Prickle-Prickle"; + case 5: + return "Setting Orange"; + default: + return nullptr; + } + } + + const char* season_from_day_of_yold(uint16_t day) + { + if (is_st_tibs_day()) + return nullptr; + + switch (((day % m_days_in_season) == 0 ? day - 1 : day) / m_days_in_season) { + case 0: + return "Chaos"; + case 1: + return "Discord"; + case 2: + return "Confusion"; + case 3: + return "Bureaucracy"; + case 4: + return "The Aftermath"; + default: + return nullptr; + } + } +}; + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) +{ + if (pledge("stdio", nullptr) < 0) { + perror("pledge"); + return 1; + } + + auto date = Core::DateTime::from_timestamp(time(nullptr)); + printf("Today is %s\n", DiscordianDate(date).to_string().characters()); + + return 0; +} |