File indexing completed on 2024-05-12 16:59:37

0001 /*
0002     SPDX-FileCopyrightText: 2021 Gary Wang <wzc782970009@gmail.com>
0003     SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "chinesecalendar.h"
0009 
0010 class ChineseCalendarProviderPrivate : public ICUCalendarPrivate
0011 {
0012 public:
0013     explicit ChineseCalendarProviderPrivate();
0014 
0015     CalendarEvents::CalendarEventsPlugin::SubLabel subLabels(const QDate &date);
0016 
0017 private:
0018     /**
0019      * For formatting, see the documentation of SimpleDateFormat:
0020      * https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details
0021      */
0022     QString formattedDateString(const icu::UnicodeString &str, bool hanidays = false) const;
0023 
0024     QString yearDisplayName() const;
0025     QString monthDisplayName() const;
0026     QString dayDisplayName() const;
0027 
0028     icu::Locale m_locale;
0029     icu::Locale m_hanidaysLocale;
0030 };
0031 
0032 ChineseCalendarProviderPrivate::ChineseCalendarProviderPrivate()
0033     : ICUCalendarPrivate()
0034     , m_locale(icu::Locale("zh", 0, 0, "calendar=chinese"))
0035     , m_hanidaysLocale(icu::Locale("zh", 0, 0, "calendar=chinese;numbers=hanidays"))
0036 {
0037     if (U_FAILURE(m_errorCode)) {
0038         return; // Failed to create m_GregorianCalendar
0039     }
0040 
0041     m_calendar.reset(icu::Calendar::createInstance("en_US@calendar=chinese", m_errorCode));
0042 }
0043 
0044 CalendarEvents::CalendarEventsPlugin::SubLabel ChineseCalendarProviderPrivate::subLabels(const QDate &date)
0045 {
0046     auto sublabel = CalendarEvents::CalendarEventsPlugin::SubLabel{};
0047 
0048     if (U_FAILURE(m_errorCode) || !date.isValid() || !setDate(date)) {
0049         return sublabel;
0050     }
0051 
0052     sublabel.yearLabel = yearDisplayName();
0053     sublabel.monthLabel = monthDisplayName();
0054     const QString dayName = dayDisplayName();
0055     sublabel.dayLabel = day() == 1 ? monthDisplayName() : dayName;
0056     sublabel.label = QStringLiteral("%1%2%3").arg(sublabel.yearLabel, sublabel.monthLabel, dayName);
0057     sublabel.priority = CalendarEvents::CalendarEventsPlugin::SubLabelPriority::Low;
0058 
0059     return sublabel;
0060 }
0061 
0062 QString ChineseCalendarProviderPrivate::formattedDateString(const icu::UnicodeString &str, bool hanidays) const
0063 {
0064     UErrorCode errorCode = U_ZERO_ERROR;
0065     icu::UnicodeString dateString;
0066     icu::SimpleDateFormat formatter(str, hanidays ? m_hanidaysLocale : m_locale, errorCode);
0067     formatter.setCalendar(*m_calendar);
0068     formatter.format(m_calendar->getTime(errorCode), dateString);
0069 
0070     std::string utf8Str;
0071     dateString.toUTF8String<std::string>(utf8Str);
0072 
0073     return QString::fromUtf8(utf8Str.c_str());
0074 }
0075 
0076 QString ChineseCalendarProviderPrivate::yearDisplayName() const
0077 {
0078     return formattedDateString("U");
0079 }
0080 
0081 QString ChineseCalendarProviderPrivate::monthDisplayName() const
0082 {
0083     return formattedDateString("MMM");
0084 }
0085 
0086 QString ChineseCalendarProviderPrivate::dayDisplayName() const
0087 {
0088     return formattedDateString("d", true);
0089 }
0090 
0091 ChineseCalendarProvider::ChineseCalendarProvider(QObject *parent, CalendarSystem::System calendarSystem)
0092     : AbstractCalendarProvider(parent, calendarSystem)
0093     , d(std::make_unique<ChineseCalendarProviderPrivate>())
0094 {
0095     Q_ASSERT(m_calendarSystem == CalendarSystem::Chinese);
0096 }
0097 
0098 ChineseCalendarProvider::~ChineseCalendarProvider()
0099 {
0100 }
0101 
0102 CalendarEvents::CalendarEventsPlugin::SubLabel ChineseCalendarProvider::subLabels(const QDate &date) const
0103 {
0104     return d->subLabels(date);
0105 }