summaryrefslogtreecommitdiff
path: root/Userland/Utilities/ddate.cpp
blob: 9e68eb2aa11539adf3e9117a615aafda34f40f17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (c) 2021, the SerenityOS developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/String.h>
#include <LibCore/DateTime.h>
#include <stdio.h>
#include <unistd.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::now();
    outln("Today is {}", DiscordianDate(date).to_string());

    return 0;
}