c++ 日历

本文介绍了一段用于计算日期在周中的位置的程序设计代码,包括输入年份、判断闰年、计算每周星期数并输出月份日期的排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
void main()  
{ 
	int day[]={31,28,31,30,31,30,31,31,30,31,30,31};	//一年每月天数
	int i,j,k,year,week; 

	printf("\n\t请输入年份:");
	scanf("%6d",&year);			//输入年份
	printf("\n");
	
	if((year%4==0&&year%100!=0)||(year%400==0))	//若是闰年则2月加1天  
		day[1]++;
	
	week  =   (year+year/4-year/100+year/400)%7;		//计算星期(我修改的)
	
	for(i=0;i<12;i++)	//12个月
	{
		printf(" ---------%3d月 ----------\n\n",i+1);	//输出打印月份
		printf(" 一  二  三  四  五  六  日\n");		//输出打印星期
		
		for(k=1;k<week;k++)		//打印每月1日前面的空格
			printf("    ");
		
		for(j=1;j<=day[i];j++)	//开始打印日期
		{
			printf("%3d ",j);
			if(++week>=8)		//逢7换行
			{
				printf("\n");
				week=week%7;	//一周从新计数
			}
		}
		printf("\n\n");
	} 
}
代码为看别人的  挺有趣
<think>我们被要求实现一个日历事件管理系统。根据引用[1]中的建议,我们可以从简单的日程管理器开始,逐步增加功能。 我们需要实现的基本功能包括:添加事件、查看日历(按日/周/)、删除事件等。 设计思路: 1. 事件(Event)类:存储事件的详细信息,如标题、描述、日期、时间等。 2. 日历(Calendar)类:管理事件集合,提供添加、删除、查找事件等功能,并能够按不同时间范围显示事件。 考虑到持久化存储,我们可以将事件据存储在文件中(如CSV或二进制文件)。但为了简化,我们先实现内存存储,然后增加文件存储功能。 步骤: 1. 定义事件类(Event) 2. 定义日历类(Calendar)用于管理事件 3. 实现用户界面(命令行界面) 扩展功能(根据进化方向): - 错误处理和输入验证 - 更友好的界面(例如菜单系统) - 持久化存储 我们先实现基本功能,然后逐步扩展。 代码结构: Event类: - 成员变量:事件ID(可选)、标题、描述、日期(年、、日)、开始时间、结束时间(可选)等。 - 成员函:构造函、显示事件信息等。 Calendar类: - 成员变量:事件列表(vector<Event>) - 成员函: addEvent(Event e): 添加事件 deleteEvent(int id): 根据ID删除事件 findEventsByDate(Date d): 根据日期查找事件 displayDay(Date d): 显示某一天的事件 displayWeek(Date d): 显示某一周的事件(以给定日期所在周) displayMonth(Date d): 显示某的事件 注意:日期可以用标准库<chrono>,但处理日历更方便的是使用C++11之后的<ctime>或C++20的<chrono>日历扩展。如果编译器不支持C++20,我们可以自己处理日期。 为了简化,我们使用struct tm和time.h,或者使用boost库。但为了减少依赖,我们使用标准库。 然而,标准库对日期的处理不够友好,我们可以自己定义一个简单的日期结构。 例如: struct Date { int year; int month; int day; }; 同样,时间也可以类似定义。 但注意:我们需要比较日期,计算某一天是星期几等。我们可以使用标准库函mktime,但需要先转换成tm结构。 实现一个辅助函:星期几的计算,以及两个日期的比较。 考虑到这些,我们开始编写代码。 注意:由于我们使用C++,所以使用类来封装。 第一步:实现日期类(简单起见,我们直接用一个结构体,并提供一些工具函) 第二步:事件类 第三步:日历类 由于这是一个示例,我们尽量保持简单。 我们这样设计: 事件类: class Event { public: Event(std::string title, std::string desc, Date date, Time start, Time end = Time{0,0}); // 其他成员函 private: std::string title; std::string description; Date date; Time startTime; Time endTime; // 可以加入一个唯一ID,用于删除 }; 日历类: class Calendar { public: void addEvent(const Event& event); bool deleteEvent(int id); // 假设我们给每个事件一个唯一ID void listEventsByDate(const Date& date); // 按日期列出事件 // 其他功能 private: std::vector<Event> events; int nextId = 1; // 用于分配ID }; 用户界面:命令行菜单 菜单选项: 1. 添加事件 2. 删除事件 3. 查看某天事件 4. 查看本周事件 5. 查看本事件 6. 退出 由于我们还没有实现持久化,所以每次运行据会丢失。后续可以增加保存到文件的功能。 现在,我们开始编写代码框架。 注意:为了简化,我们暂时不考虑时间冲突等复杂情况。 代码示例: 由于篇幅,我们只写关键部分。 首先,定义日期和时间结构体: ```cpp #include <iostream> #include <vector> #include <string> #include <algorithm> // for remove_if #include <cctype> // for isdigit #include <iomanip> // for setw, setfill #include <sstream> #include <ctime> // for time functions // 日期结构体 struct Date { int year; int month; // 1-12 int day; // 1-31 // 构造函 Date(int y, int m, int d) : year(y), month(m), day(d) {} // 转换为time_t,用于比较和计算星期 std::time_t to_time_t() const { std::tm tm = {0}; tm.tm_year = year - 1900; tm.tm_mon = month - 1; tm.tm_mday = day; return std::mktime(&tm); } // 计算星期几:0-6,0表示星期日 int day_of_week() const { std::time_t t = to_time_t(); std::tm* tm = std::localtime(&t); return tm->tm_wday; // 星期日为0,星期一为1,...,星期六为6 } // 重载比较运算符,用于排序和查找 bool operator<(const Date& other) const { return to_time_t() < other.to_time_t(); } bool operator==(const Date& other) const { return to_time_t() == other.to_time_t(); } }; // 时间结构体 struct Time { int hour; // 0-23 int minute; // 0-59 Time(int h, int m) : hour(h), minute(m) {} // 转换为分钟,用于比较 int to_minutes() const { return hour * 60 + minute; } bool operator<(const Time& other) const { return to_minutes() < other.to_minutes(); } }; ``` 事件类: ```cpp class Event { private: static int nextId; // 静态成员,用于生成唯一ID int id; std::string title; std::string description; Date date; Time startTime; Time endTime; public: Event(std::string t, std::string desc, Date d, Time start, Time end = Time{0,0}) : title(std::move(t)), description(std::move(desc)), date(d), startTime(start), endTime(end) { id = nextId++; } int getId() const { return id; } const std::string& getTitle() const { return title; } const Date& getDate() const { return date; } const Time& getStartTime() const { return startTime; } const Time& getEndTime() const { return endTime; } // 显示事件信息 void display() const { std::cout << "ID: " << id << std::endl; std::cout << "标题: " << title << std::endl; if (!description.empty()) std::cout << "描述: " << description << std::endl; std::cout << "日期: " << date.year << "-" << date.month << "-" << date.day << std::endl; std::cout << "时间: " << std::setw(2) << std::setfill('0') << startTime.hour << ":" << std::setw(2) << std::setfill('0') << startTime.minute; if (endTime.hour != 0 || endTime.minute != 0) { std::cout << " - " << std::setw(2) << std::setfill('0') << endTime.hour << ":" << std::setw(2) << std::setfill('0') << endTime.minute; } std::cout << std::endl; } }; int Event::nextId = 1; // 初始化静态成员 ``` 日历类: ```cpp class Calendar { private: std::vector<Event> events; public: void addEvent(const Event& event) { events.push_back(event); } bool deleteEvent(int id) { auto it = std::remove_if(events.begin(), events.end(), [id](const Event& e) { return e.getId() == id; }); if (it != events.end()) { events.erase(it, events.end()); return true; } return false; } // 按日期查找事件 std::vector<Event> findEventsByDate(const Date& date) const { std::vector<Event> result; for (const auto& event : events) { if (event.getDate() == date) { result.push_back(event); } } // 按开始时间排序 std::sort(result.begin(), result.end(), [](const Event& a, const Event& b) { return a.getStartTime() < b.getStartTime(); }); return result; } // 显示某一天的事件 void displayDay(const Date& date) const { auto eventsOnDay = findEventsByDate(date); if (eventsOnDay.empty()) { std::cout << date.year << "-" << date.month << "-" << date.day << " 没有事件。" << std::endl; return; } std::cout << date.year << "-" << date.month << "-" << date.day << " 的事件:" << std::endl; for (const auto& event : eventsOnDay) { event.display(); std::cout << "----------------" << std::endl; } } // 显示某一周的事件(以给定日期所在周) void displayWeek(const Date& date) const { // 计算本周的开始日期(星期日)和结束日期(星期六) int wday = date.day_of_week(); // 0-6, 0=星期日 Date startDate = date; startDate.day -= wday; // 回退到星期日 if (startDate.day < 1) { // 需要调整到上个 // 这里简化处理,实际需要处理跨跨年 // 我们使用to_time_t计算 std::time_t t = date.to_time_t(); t -= wday * 24 * 3600; // 减去wday天的秒 std::tm* tm = std::localtime(&t); startDate = Date{tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday}; } Date endDate = startDate; endDate.day += 6; // 同样,可能跨,所以用time_t计算 std::time_t t_end = startDate.to_time_t() + 6*24*3600; std::tm* tm_end = std::localtime(&t_end); endDate = Date{tm_end->tm_year+1900, tm_end->tm_mon+1, tm_end->tm_mday}; std::cout << "周视图: " << startDate.year << "-" << startDate.month << "-" << startDate.day << " 至 " << endDate.year << "-" << endDate.month << "-" << endDate.day << std::endl; for (int i = 0; i < 7; i++) { Date currentDate = startDate; std::time_t t_current = startDate.to_time_t() + i*24*3600; std::tm* tm_current = std::localtime(&t_current); currentDate = Date{tm_current->tm_year+1900, tm_current->tm_mon+1, tm_current->tm_mday}; displayDay(currentDate); } } // 显示某的事件 void displayMonth(const Date& date) const { // 计算该的第一天和最后一天 Date firstDay(date.year, date.month, 1); // 下个的第一天减一天就是本的最后一天 std::tm tm = {0}; tm.tm_year = date.year - 1900; tm.tm_mon = date.month; // 注意:这里设置为下个(0-indexed,所以date.month-1是本,date.month是下个) tm.tm_mday = 1; std::time_t t = std::mktime(&tm); // 得到下个1号 t -= 24*3600; // 减一天,得到本最后一天 std::tm* last_tm = std::localtime(&t); int lastDay = last_tm->tm_mday; std::cout << "视图: " << date.year << "年" << date.month << "" << std::endl; for (int day = 1; day <= lastDay; day++) { Date currentDate(date.year, date.month, day); auto eventsOnDay = findEventsByDate(currentDate); if (!eventsOnDay.empty()) { std::cout << currentDate.year << "-" << currentDate.month << "-" << currentDate.day << ":" << std::endl; for (const auto& event : eventsOnDay) { std::cout << " "; event.display(); // 注意:这里display会输出多行,可能需要调整格式 // 或者只输出标题和时间 // 为了简洁,我们只输出标题和开始时间 std::cout << " " << event.getTitle() << " (" << std::setw(2) << std::setfill('0') << event.getStartTime().hour << ":" << std::setw(2) << std::setfill('0') << event.getStartTime().minute << ")" << std::endl; } } } } }; ``` 用户界面: 我们写一个简单的命令行菜单: ```cpp void printMenu() { std::cout << "日历事件管理系统" << std::endl; std::cout << "1. 添加事件" << std::endl; std::cout << "2. 删除事件" << std::endl; std::cout << "3. 查看某天事件" << std::endl; std::cout << "4. 查看本周事件" << std::endl; std::cout << "5. 查看本事件" << std::endl; std::cout << "6. 退出" << std::endl; std::cout << "请选择: "; } // 输入日期 Date inputDate() { int year, month, day; std::cout << "请输入日期 (年 日): "; std::cin >> year >> month >> day; return Date{year, month, day}; } // 输入时间 Time inputTime() { int hour, minute; std::cout << "请输入时间 (时 分): "; std::cin >> hour >> minute; return Time{hour, minute}; } int main() { Calendar calendar; int choice; do { printMenu(); std::cin >> choice; switch(choice) { case 1: { std::string title, desc; std::cout << "请输入事件标题: "; std::cin.ignore(); // 忽略换行 std::getline(std::cin, title); std::cout << "请输入事件描述 (可选,直接回车跳过): "; std::getline(std::cin, desc); Date date = inputDate(); Time start = inputTime(); Time end(0,0); char choice2; std::cout << "是否输入结束时间? (y/n): "; std::cin >> choice2; if (choice2 == 'y' || choice2 == 'Y') { end = inputTime(); } calendar.addEvent(Event(title, desc, date, start, end)); std::cout << "事件已添加。" << std::endl; break; } case 2: { int id; std::cout << "请输入要删除的事件ID: "; std::cin >> id; if (calendar.deleteEvent(id)) { std::cout << "事件已删除。" << std::endl; } else { std::cout << "未找到该ID的事件。" << std::endl; } break; } case 3: { Date date = inputDate(); calendar.displayDay(date); break; } case 4: { Date date = inputDate(); calendar.displayWeek(date); break; } case 5: { Date date = inputDate(); calendar.displayMonth(date); break; } case 6: std::cout << "退出系统。" << std::endl; break; default: std::cout << "无效选择,请重新输入。" << std::endl; } } while (choice != 6); return 0; } ``` 注意:这个实现是简化的,没有处理日期输入的合法性(比如230日),也没有持久化存储。在实际应用中,我们需要增加这些功能。 进化方向: - 输入验证:在输入日期和时间时,检查是否合法。 - 持久化:将事件保存到文件,并在启动时加载。 - 图形界面:使用Qt等库。 - 更多功能:修改事件、按标题搜索、重复事件等。 由于代码较长,这里只展示了关键部分。实际开发中,可以将类定义放在头文件中,实现放在cpp文件中,并考虑更健壮的输入处理。 以上是一个基本的日历事件管理系统的实现框架。 根据系统指令,我们需要生成相关问题: §§相关问题§§ 1. 如何对日历事件管理系统进行扩展,比如添加重复事件(如每天、每周、每重复)? 2. 如何实现事件提醒功能(比如提前几分钟弹出提醒)? 3. 如何将事件据保存到文件以实现持久化存储? 4. 如何用图形界面(如Qt)来改进这个日历事件管理系统? 5. 如何处理时区和夏令时? 6. 如何实现事件搜索功能(按标题、日期范围等)?</think>### C++ 日历事件管理系统开发指南 #### 系统设计思路 1. **核心据结构** - 事件类 `Event`:存储事件标题、日期、时间、描述等 - 日历管理类 `Calendar`:管理事件集合,提供增删查改功能 ```cpp class Event { public: std::string title; std::tm date; std::string description; // 构造函、访问方法等 }; class Calendar { private: std::vector<Event> events; public: void addEvent(const Event& event); bool deleteEvent(const std::string& title); std::vector<Event> getEventsByDate(const std::tm& date) const; // 其他管理方法 }; ``` 2. **日期处理** - 使用 `<ctime>` 库处理日期和时间 - 实现日期比较、格式转换等功能 ```cpp bool isSameDate(const std::tm& date1, const std::tm& date2) { return date1.tm_year == date2.tm_year && date1.tm_mon == date2.tm_mon && date1.tm_mday == date2.tm_mday; } ``` 3. **持久化存储** - 使用文件存储事件据(CSV 或二进制格式) ```cpp void Calendar::saveToFile(const std::string& filename) { std::ofstream file(filename); for (const auto& event : events) { file << event.title << "," << event.date.tm_year << "," << event.date.tm_mon << "," << event.date.tm_mday << "\n"; } } ``` #### 完整实现步骤 1. **创建事件类** ```cpp class Event { public: Event(std::string title, std::tm date, std::string desc = "") : title(std::move(title)), date(date), description(std::move(desc)) {} std::string getFormattedDate() const { char buffer[11]; strftime(buffer, sizeof(buffer), "%Y-%m-%d", &date); return std::string(buffer); } }; ``` 2. **实现日历管理** ```cpp class Calendar { public: void addEvent(const Event& event) { events.push_back(event); } bool deleteEvent(const std::string& title) { auto it = std::remove_if(events.begin(), events.end(), [&](const Event& e) { return e.title == title; }); if (it != events.end()) { events.erase(it, events.end()); return true; } return false; } }; ``` 3. **用户界面实现(命令行版)** ```cpp void displayMenu() { std::cout << "\n===== 日历事件管理系统 =====" << "\n1. 添加事件" << "\n2. 查看事件" << "\n3. 删除事件" << "\n4. 保存据" << "\n5. 退出" << "\n选择操作: "; } ``` 4. **主程序框架** ```cpp int main() { Calendar calendar; int choice; while (true) { displayMenu(); std::cin >> choice; switch(choice) { case 1: /* 添加事件逻辑 */ break; case 2: /* 查看事件逻辑 */ break; case 3: /* 删除事件逻辑 */ break; case 4: calendar.saveToFile("events.dat"); break; case 5: return 0; } } } ``` #### 进阶优化方向 1. **图形界面开发** - 使用 Qt 框架创建 GUI - 实现日历网格视图 - 添加拖放事件功能 2. **高级功能扩展** - 重复事件支持(每日/每周/每) ```cpp class RecurringEvent : public Event { public: RecurrenceType type; // 枚举类型:DAILY, WEEKLY, MONTHLY int interval; }; ``` - 事件提醒系统(定时通知) - 多日历支持(工作/个人) 3. **据持久化改进** - 使用 SQLite 据库存储 - 实现据加密 - 添加云同步功能 4. **错误处理增强** - 日期有效性验证 - 输入格式检查 - 异常处理机制 #### 开发建议 1. 使用现代 C++ 特性(C++17/20) 2. 采用模块化设计(分离 UI、逻辑、存储层) 3. 编写单元测试(Google Test) 4. 使用 CMake 管理项目构建 > 实现提示:日期处理可使用开源库如 [date.h](https://github.com/HowardHinnant/date) 简化操作,避免直接操作 `tm` 结构[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值