thisweek_core/calendar/
chinese.rs

1use crate::weekdays::convert_weekday;
2use crate::{
3    language::{str_to_vec, Language},
4    week_info::{Date, DateView},
5};
6
7use crate::calendar::calendar_names::*;
8use crate::month_names::*;
9use crate::season_names::*;
10use crate::weekday_names::*;
11
12use super::{Calendar, CalendarSpecificDateView, CalendarView, CALENDAR_CHINESE};
13use chinese_lunisolar_calendar::{LunisolarDate, SolarDate};
14use chrono::{DateTime, Datelike, Local};
15use serde::Serialize;
16
17#[derive(Debug, Serialize, Clone, PartialEq)]
18pub struct ChineseCalendar;
19
20impl CalendarSpecificDateView for ChineseCalendar {
21    fn new_date(datetime: DateTime<Local>) -> Date {
22        let year = datetime.year() as u16;
23        let month = datetime.month() as u8;
24        let day = datetime.day() as u8;
25        let solar_date = SolarDate::from_ymd(year, month, day).unwrap();
26        let lunisolar_date = LunisolarDate::from_solar_date(solar_date).unwrap();
27        let month_number = lunisolar_date.to_lunar_month().to_u8() as u32;
28        Date {
29            calendar: Calendar::Chinese(ChineseCalendar),
30            weekday: convert_weekday(datetime.weekday()) as u32,
31            day: lunisolar_date.to_lunar_day() as u32,
32            month: month_number,
33            year: lunisolar_date.to_lunisolar_year().to_u16() as i32,
34        }
35    }
36
37    fn new_date_view(datetime: DateTime<Local>, lang: &Language) -> DateView {
38        let year = datetime.year() as u16;
39        let month = datetime.month() as u8;
40        let day = datetime.day() as u8;
41        let weekday = datetime.weekday();
42        let solar_date = SolarDate::from_ymd(year, month, day).unwrap();
43        let lunisolar_date = LunisolarDate::from_solar_date(solar_date).unwrap();
44        let day = lunisolar_date.to_lunar_day();
45        let month = lunisolar_date.to_lunar_month();
46        let year = lunisolar_date.to_lunisolar_year();
47        let month_index = (lunisolar_date.to_lunar_month().to_u8() - 1) as u32;
48        let day = match lang {
49            Language::Chinese => day.to_string(),
50            _ => day.to_u8().to_string(),
51        };
52        let month = match lang {
53            // format!("{:#}", month), // simplified chinese names
54            Language::Chinese => {
55                if month.is_leap_month() {
56                    format!(
57                        "{}{}",
58                        CHINESE_LEAP_MONTH_PREFIX_ZH, CHINESE_MONTH_NAME_ZH[month_index as usize]
59                    )
60                } else {
61                    CHINESE_MONTH_NAME_ZH[month_index as usize].to_string()
62                }
63            }
64            _ => {
65                if month.is_leap_month() {
66                    format!(
67                        "{}{}",
68                        CHINESE_LEAP_MONTH_PREFIX_EN, CHINESE_MONTH_NAME_EN[month_index as usize]
69                    )
70                } else {
71                    CHINESE_MONTH_NAME_EN[month_index as usize].to_string()
72                }
73            }
74        };
75        let year = match lang {
76            // Language::Chinese => year.to_string(), // this is not very intuitive!
77            Language::Chinese => year.to_u16().to_string(),
78            _ => year.to_u16().to_string(),
79        };
80
81        let weekday = convert_weekday(weekday) as usize;
82        let full_format = match lang {
83            Language::Chinese => format!(
84                "{}, {} {} {}",
85                WEEKDAY_NAME_FULL_CN[weekday], day, month, year
86            ),
87            _ => format!(
88                "{}, {} {} {}",
89                WEEKDAY_NAME_FULL_EN[weekday], day, month, year
90            ),
91        }
92        .to_string();
93        let weekday = match lang {
94            Language::Chinese => WEEKDAY_NAME_FULL_CN[weekday],
95            _ => WEEKDAY_NAME_HALF_CAP_EN[weekday],
96        }
97        .to_string();
98
99        DateView {
100            unix_day: 0,
101            day,
102            month,
103            weekday,
104            year,
105            full_format,
106        }
107    }
108
109    fn get_calendar_view(lang: &Language) -> CalendarView {
110        let months_names: Vec<String> = match lang {
111            Language::Chinese => str_to_vec(&CHINESE_MONTH_NAME_ZH),
112            _ => str_to_vec(&CHINESE_MONTH_NAME_EN),
113        };
114        let seasons_names: Vec<String> = match lang {
115            Language::Chinese => str_to_vec(&SEASON_NAME_ZH),
116            _ => str_to_vec(&SEASON_NAME_EN),
117        };
118        let calendar_name: String = match lang {
119            // Language::Chinese => "中国农历".into(),
120            Language::Chinese => CHINESE_CALENDAR_NAME_ZH.into(),
121            _ => CHINESE_CALENDAR_NAME_EN.into(),
122        };
123        CalendarView {
124            calendar: CALENDAR_CHINESE,
125            calendar_name,
126            language: lang.clone().into(),
127            direction: lang.default_direction(),
128            months_names,
129            seasons_names,
130        }
131    }
132}