C语言多功能万年历时钟系统
语言控制台版多功能万年历时钟系统,包含数字时钟、日历显示、农历计算、闹钟提醒、秒表计时、倒计时等功能。
一、项目结构
MultiCalendarClock_C/
├── main.c # 主程序入口
├── calendar.h # 日历头文件
├── calendar.c # 日历功能实现
├── clock.h # 时钟头文件
├── clock.c # 时钟功能实现
├── lunar.h # 农历计算头文件
├── lunar.c # 农历计算实现
├── alarm.h # 闹钟头文件
├── alarm.c # 闹钟功能实现
├── stopwatch.h # 秒表头文件
├── stopwatch.c # 秒表功能实现
├── countdown.h # 倒计时头文件
├── countdown.c # 倒计时功能实现
├── utils.h # 工具函数头文件
├── utils.c # 工具函数实现
└── Makefile # 编译脚本
二、核心源码实现
2.1 主程序 (main.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include "calendar.h"
#include "clock.h"
#include "lunar.h"
#include "alarm.h"
#include "stopwatch.h"
#include "countdown.h"
#include "utils.h"
// 全局变量
int running = 1;
int current_view = 0; // 0:时钟 1:日历 2:闹钟 3:秒表 4:倒计时
void show_main_menu() {
system("cls");
printf("=========================================\n");
printf(" 多功能万年历时钟系统 v1.0\n");
printf("=========================================\n");
printf("当前时间: ");
show_current_time();
printf("\n");
printf("-----------------------------------------\n");
printf("请选择功能:\n");
printf("1. 时钟显示\n");
printf("2. 日历查看\n");
printf("3. 闹钟管理\n");
printf("4. 秒表计时\n");
printf("5. 倒计时器\n");
printf("6. 系统设置\n");
printf("0. 退出系统\n");
printf("-----------------------------------------\n");
printf("请选择: ");
}
void show_clock_view() {
system("cls");
printf("=========================================\n");
printf(" 数字时钟\n");
printf("=========================================\n");
// 显示数字时钟
display_digital_clock();
printf("\n-----------------------------------------\n");
printf("按任意键返回主菜单...\n");
getch();
}
void show_calendar_view() {
system("cls");
printf("=========================================\n");
printf(" 万年历\n");
printf("=========================================\n");
// 显示日历
display_calendar();
printf("\n-----------------------------------------\n");
printf("按任意键返回主菜单...\n");
getch();
}
void show_alarm_view() {
system("cls");
printf("=========================================\n");
printf(" 闹钟管理\n");
printf("=========================================\n");
// 显示闹钟管理界面
display_alarm_manager();
printf("\n-----------------------------------------\n");
printf("按任意键返回主菜单...\n");
getch();
}
void show_stopwatch_view() {
system("cls");
printf("=========================================\n");
printf(" 秒表计时器\n");
printf("=========================================\n");
// 显示秒表界面
display_stopwatch();
printf("\n-----------------------------------------\n");
printf("按任意键返回主菜单...\n");
getch();
}
void show_countdown_view() {
system("cls");
printf("=========================================\n");
printf(" 倒计时器\n");
printf("=========================================\n");
// 显示倒计时界面
display_countdown();
printf("\n-----------------------------------------\n");
printf("按任意键返回主菜单...\n");
getch();
}
int main() {
int choice;
// 初始化随机数种子
srand((unsigned int)time(NULL));
// 加载闹钟数据
load_alarms();
while (running) {
show_main_menu();
scanf("%d", &choice);
switch (choice) {
case 1:
show_clock_view();
break;
case 2:
show_calendar_view();
break;
case 3:
show_alarm_view();
break;
case 4:
show_stopwatch_view();
break;
case 5:
show_countdown_view();
break;
case 6:
printf("系统设置功能开发中...\n");
Sleep(1000);
break;
case 0:
running = 0;
printf("感谢使用,再见!\n");
break;
default:
printf("无效选择,请重新输入!\n");
Sleep(1000);
break;
}
}
// 保存闹钟数据
save_alarms();
return 0;
}
2.2 日历头文件 (calendar.h)
#ifndef CALENDAR_H
#define CALENDAR_H
#include <stdio.h>
#include <time.h>
// 显示当前时间
void show_current_time();
// 显示日历
void display_calendar();
// 获取某月的天数
int get_days_in_month(int year, int month);
// 获取某月第一天是星期几
int get_first_day_of_week(int year, int month);
// 判断是否为闰年
int is_leap_year(int year);
#endif
2.3 日历功能实现 (calendar.c)
#include "calendar.h"
#include "lunar.h"
#include "utils.h"
void show_current_time() {
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
printf("%04d-%02d-%02d %02d:%02d:%02d",
tm_now->tm_year + 1900, tm_now->tm_mon + 1, tm_now->tm_mday,
tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
}
void display_calendar() {
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
int year = tm_now->tm_year + 1900;
int month = tm_now->tm_mon + 1;
int day = tm_now->tm_mday;
int days_in_month = get_days_in_month(year, month);
int first_day = get_first_day_of_week(year, month);
printf("\n%d年%d月\n", year, month);
printf("日 一 二 三 四 五 六\n");
// 打印前面的空格
for (int i = 0; i < first_day; i++) {
printf(" ");
}
// 打印日期
for (int date = 1; date <= days_in_month; date++) {
if (date == day) {
printf("[%2d]", date); // 当前日期用方括号标记
} else {
printf("%3d", date);
}
// 换行处理
if ((first_day + date) % 7 == 0) {
printf("\n");
}
}
printf("\n");
// 显示农历信息
printf("\n农历信息:\n");
display_lunar_date(year, month, day);
// 显示节气
printf("今日节气: %s\n", get_solar_term(year, month, day));
// 显示节日
printf("今日节日: %s\n", get_holiday(year, month, day));
}
int get_days_in_month(int year, int month) {
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && is_leap_year(year)) {
return 29;
}
return days[month - 1];
}
int get_first_day_of_week(int year, int month) {
// 使用蔡勒公式计算星期几
if (month < 3) {
month += 12;
year--;
}
int k = year % 100; // 年份后两位
int j = year / 100; // 世纪数
int h = (1 + 13*(month + 1)/5 + k + k/4 + j/4 + 5*j) % 7;
// 转换为星期天=0的格式
return (h + 5) % 7;
}
int is_leap_year(int year) {
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
2.4 时钟头文件 (clock.h)
#ifndef CLOCK_H
#define CLOCK_H
#include <stdio.h>
#include <time.h>
#include <windows.h>
// 显示数字时钟
void display_digital_clock();
// 显示模拟时钟(ASCII艺术)
void display_analog_clock();
// 更新时钟显示
void update_clock_display();
#endif
2.5 时钟功能实现 (clock.c)
#include "clock.h"
#include "utils.h"
void display_digital_clock() {
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
printf("\n");
printf(" ╔════════════════════════════╗\n");
printf(" ║ 数字时钟 ║\n");
printf(" ╠════════════════════════════╣\n");
printf(" ║ %04d-%02d-%02d ║\n",
tm_now->tm_year + 1900, tm_now->tm_mon + 1, tm_now->tm_mday);
printf(" ║ %02d:%02d:%02d ║\n",
tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
printf(" ║ 星期%s ║\n", get_weekday_name(tm_now->tm_wday));
printf(" ╚════════════════════════════╝\n");
printf("\n");
}
void display_analog_clock() {
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
int hour = tm_now->tm_hour % 12;
int minute = tm_now->tm_min;
int second = tm_now->tm_sec;
// ASCII模拟时钟
printf("\n");
printf(" 12 \n");
printf(" 11 1 \n");
printf(" 10 ● 2 \n");
printf(" 9 3 \n");
printf(" 8 4 \n");
printf(" 7 6 5 \n");
printf("\n");
// 显示指针位置
printf("时针: %d, 分针: %d, 秒针: %d\n", hour, minute, second);
}
2.6 农历计算头文件 (lunar.h)
#ifndef LUNAR_H
#define LUNAR_H
// 显示农历日期
void display_lunar_date(int year, int month, int day);
// 获取天干地支
const char* get_gan_zhi(int year);
// 获取生肖
const char* get_chinese_zodiac(int year);
// 获取节气
const char* get_solar_term(int year, int month, int day);
// 获取节日
const char* get_holiday(int year, int month, int day);
#endif
2.7 农历计算实现 (lunar.c)
#include "lunar.h"
#include <string.h>
// 农历月份名称
static const char* lunar_months[] = {
"正月", "二月", "三月", "四月", "五月", "六月",
"七月", "八月", "九月", "十月", "冬月", "腊月"
};
// 农历日期名称
static const char* lunar_days[] = {
"初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
"十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
"廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"
};
// 天干
static const char* heavenly_stems[] = {
"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"
};
// 地支
static const char* earthly_branches[] = {
"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
};
// 生肖
static const char* zodiac_animals[] = {
"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"
};
// 节气
static const char* solar_terms[] = {
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
"清明", "谷雨", "立夏", "小满", "芒种", "夏至",
"小暑", "大暑", "立秋", "处暑", "白露", "秋分",
"寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
};
void display_lunar_date(int year, int month, int day) {
// 简化农历计算(实际应使用复杂的农历算法)
int lunar_year = year;
int lunar_month = month;
int lunar_day = day;
// 简单调整(实际应更复杂)
if (month == 1 && day < 21) {
lunar_month = 12;
lunar_day = day + 10;
} else if (month == 2 && day < 20) {
lunar_month = 1;
lunar_day = day + 10;
}
const char* gan_zhi = get_gan_zhi(lunar_year);
const char* zodiac = get_chinese_zodiac(lunar_year);
printf("农历: %s年(%s) %s%s\n",
gan_zhi, zodiac,
lunar_months[lunar_month - 1],
lunar_days[lunar_day - 1]);
}
const char* get_gan_zhi(int year) {
static char result[10];
int stem_index = (year - 4) % 10;
int branch_index = (year - 4) % 12;
sprintf(result, "%s%s",
heavenly_stems[stem_index],
earthly_branches[branch_index]);
return result;
}
const char* get_chinese_zodiac(int year) {
int index = (year - 4) % 12;
return zodiac_animals[index];
}
const char* get_solar_term(int year, int month, int day) {
// 简化节气判断
if (month == 1 && day == 6) return "小寒";
if (month == 1 && day == 20) return "大寒";
if (month == 2 && day == 4) return "立春";
if (month == 2 && day == 19) return "雨水";
if (month == 3 && day == 6) return "惊蛰";
if (month == 3 && day == 21) return "春分";
if (month == 4 && day == 5) return "清明";
if (month == 4 && day == 20) return "谷雨";
if (month == 5 && day == 6) return "立夏";
if (month == 5 && day == 21) return "小满";
if (month == 6 && day == 6) return "芒种";
if (month == 6 && day == 21) return "夏至";
if (month == 7 && day == 7) return "小暑";
if (month == 7 && day == 23) return "大暑";
if (month == 8 && day == 8) return "立秋";
if (month == 8 && day == 23) return "处暑";
if (month == 9 && day == 8) return "白露";
if (month == 9 && day == 23) return "秋分";
if (month == 10 && day == 8) return "寒露";
if (month == 10 && day == 24) return "霜降";
if (month == 11 && day == 8) return "立冬";
if (month == 11 && day == 22) return "小雪";
if (month == 12 && day == 7) return "大雪";
if (month == 12 && day == 22) return "冬至";
return "无";
}
const char* get_holiday(int year, int month, int day) {
// 2024年节假日
if (month == 1 && day == 1) return "元旦";
if (month == 2 && day == 10) return "春节";
if (month == 2 && day == 11) return "春节";
if (month == 2 && day == 12) return "春节";
if (month == 4 && day == 4) return "清明节";
if (month == 5 && day == 1) return "劳动节";
if (month == 6 && day == 10) return "端午节";
if (month == 9 && day == 17) return "中秋节";
if (month == 10 && day == 1) return "国庆节";
if (month == 10 && day == 2) return "国庆节";
if (month == 10 && day == 3) return "国庆节";
// 周末
time_t t = time(NULL);
struct tm *tm_info = localtime(&t);
tm_info->tm_year = year - 1900;
tm_info->tm_mon = month - 1;
tm_info->tm_mday = day;
mktime(tm_info);
if (tm_info->tm_wday == 0 || tm_info->tm_wday == 6) {
return "周末";
}
return "无";
}
2.8 闹钟头文件 (alarm.h)
#ifndef ALARM_H
#define ALARM_H
#include <stdio.h>
#include <time.h>
#define MAX_ALARMS 10
typedef struct {
int id;
int hour;
int minute;
int enabled;
int repeat;
char message[100];
} Alarm;
// 初始化闹钟系统
void init_alarm_system();
// 添加闹钟
int add_alarm(int hour, int minute, const char* message, int repeat);
// 删除闹钟
int delete_alarm(int id);
// 启用/禁用闹钟
int toggle_alarm(int id);
// 显示所有闹钟
void display_alarms();
// 检查闹钟
void check_alarms();
// 加载闹钟数据
void load_alarms();
// 保存闹钟数据
void save_alarms();
// 闹钟管理界面
void display_alarm_manager();
#endif
2.9 闹钟功能实现 (alarm.c)
#include "alarm.h"
#include "utils.h"
#include <stdlib.h>
#include <string.h>
static Alarm alarms[MAX_ALARMS];
static int alarm_count = 0;
void init_alarm_system() {
for (int i = 0; i < MAX_ALARMS; i++) {
alarms[i].id = i + 1;
alarms[i].enabled = 0;
alarms[i].repeat = 0;
strcpy(alarms[i].message, "");
}
alarm_count = 0;
}
int add_alarm(int hour, int minute, const char* message, int repeat) {
if (alarm_count >= MAX_ALARMS) {
return 0;
}
for (int i = 0; i < MAX_ALARMS; i++) {
if (!alarms[i].enabled) {
alarms[i].hour = hour;
alarms[i].minute = minute;
alarms[i].enabled = 1;
alarms[i].repeat = repeat;
strcpy(alarms[i].message, message);
alarm_count++;
return 1;
}
}
return 0;
}
int delete_alarm(int id) {
for (int i = 0; i < MAX_ALARMS; i++) {
if (alarms[i].id == id && alarms[i].enabled) {
alarms[i].enabled = 0;
alarm_count--;
return 1;
}
}
return 0;
}
int toggle_alarm(int id) {
for (int i = 0; i < MAX_ALARMS; i++) {
if (alarms[i].id == id) {
alarms[i].enabled = !alarms[i].enabled;
return 1;
}
}
return 0;
}
void display_alarms() {
printf("\n=== 闹钟列表 ===\n");
printf("ID 时间 状态 重复 消息\n");
printf("--------------------------------\n");
for (int i = 0; i < MAX_ALARMS; i++) {
if (alarms[i].enabled) {
printf("%2d %02d:%02d %s %s %s\n",
alarms[i].id,
alarms[i].hour,
alarms[i].minute,
alarms[i].enabled ? "启用" : "禁用",
alarms[i].repeat ? "是" : "否",
alarms[i].message);
}
}
if (alarm_count == 0) {
printf("暂无闹钟\n");
}
}
void check_alarms() {
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
int current_hour = tm_now->tm_hour;
int current_minute = tm_now->tm_min;
for (int i = 0; i < MAX_ALARMS; i++) {
if (alarms[i].enabled &&
alarms[i].hour == current_hour &&
alarms[i].minute == current_minute) {
printf("\n*** 闹钟提醒 ***\n");
printf("时间: %02d:%02d\n", current_hour, current_minute);
printf("消息: %s\n", alarms[i].message);
printf("*****************\n");
// 播放提示音
Beep(1000, 500);
if (!alarms[i].repeat) {
alarms[i].enabled = 0;
alarm_count--;
}
}
}
}
void load_alarms() {
FILE *file = fopen("alarms.dat", "r");
if (file) {
fscanf(file, "%d", &alarm_count);
for (int i = 0; i < alarm_count; i++) {
fscanf(file, "%d %d %d %d %d %s",
&alarms[i].id,
&alarms[i].hour,
&alarms[i].minute,
&alarms[i].enabled,
&alarms[i].repeat,
alarms[i].message);
}
fclose(file);
}
}
void save_alarms() {
FILE *file = fopen("alarms.dat", "w");
if (file) {
fprintf(file, "%d\n", alarm_count);
for (int i = 0; i < MAX_ALARMS; i++) {
if (alarms[i].enabled) {
fprintf(file, "%d %d %d %d %d %s\n",
alarms[i].id,
alarms[i].hour,
alarms[i].minute,
alarms[i].enabled,
alarms[i].repeat,
alarms[i].message);
}
}
fclose(file);
}
}
void display_alarm_manager() {
int choice;
int hour, minute;
char message[100];
int repeat;
int id;
while (1) {
system("cls");
printf("=========================================\n");
printf(" 闹钟管理\n");
printf("=========================================\n");
display_alarms();
printf("\n请选择操作:\n");
printf("1. 添加闹钟\n");
printf("2. 删除闹钟\n");
printf("3. 启用/禁用闹钟\n");
printf("0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("请输入时间 (时 分): ");
scanf("%d %d", &hour, &minute);
printf("请输入提醒消息: ");
scanf("%s", message);
printf("是否重复? (1=是, 0=否): ");
scanf("%d", &repeat);
if (add_alarm(hour, minute, message, repeat)) {
printf("闹钟添加成功!\n");
} else {
printf("闹钟添加失败!\n");
}
Sleep(1000);
break;
case 2:
printf("请输入要删除的闹钟ID: ");
scanf("%d", &id);
if (delete_alarm(id)) {
printf("闹钟删除成功!\n");
} else {
printf("闹钟删除失败!\n");
}
Sleep(1000);
break;
case 3:
printf("请输入要切换状态的闹钟ID: ");
scanf("%d", &id);
if (toggle_alarm(id)) {
printf("闹钟状态已切换!\n");
} else {
printf("操作失败!\n");
}
Sleep(1000);
break;
case 0:
return;
default:
printf("无效选择!\n");
Sleep(1000);
break;
}
}
}
2.10 秒表头文件 (stopwatch.h)
#ifndef STOPWATCH_H
#define STOPWATCH_H
#include <stdio.h>
#include <time.h>
// 秒表状态
typedef enum {
STOPWATCH_STOPPED,
STOPWATCH_RUNNING,
STOPWATCH_PAUSED
} StopwatchState;
// 秒表结构体
typedef struct {
StopwatchState state;
clock_t start_time;
clock_t pause_time;
clock_t elapsed_time;
int lap_count;
double lap_times[10];
} Stopwatch;
// 初始化秒表
void init_stopwatch(Stopwatch *sw);
// 开始秒表
void start_stopwatch(Stopwatch *sw);
// 暂停秒表
void pause_stopwatch(Stopwatch *sw);
// 重置秒表
void reset_stopwatch(Stopwatch *sw);
// 记录计次
void lap_stopwatch(Stopwatch *sw);
// 显示秒表
void display_stopwatch();
// 更新秒表显示
void update_stopwatch_display(Stopwatch *sw);
#endif
2.11 秒表功能实现 (stopwatch.c)
#include "stopwatch.h"
#include "utils.h"
static Stopwatch stopwatch;
void init_stopwatch(Stopwatch *sw) {
sw->state = STOPWATCH_STOPPED;
sw->start_time = 0;
sw->pause_time = 0;
sw->elapsed_time = 0;
sw->lap_count = 0;
for (int i = 0; i < 10; i++) {
sw->lap_times[i] = 0.0;
}
}
void start_stopwatch(Stopwatch *sw) {
if (sw->state == STOPWATCH_STOPPED) {
sw->start_time = clock();
sw->state = STOPWATCH_RUNNING;
} else if (sw->state == STOPWATCH_PAUSED) {
sw->start_time = clock() - sw->elapsed_time;
sw->state = STOPWATCH_RUNNING;
}
}
void pause_stopwatch(Stopwatch *sw) {
if (sw->state == STOPWATCH_RUNNING) {
sw->elapsed_time = clock() - sw->start_time;
sw->state = STOPWATCH_PAUSED;
}
}
void reset_stopwatch(Stopwatch *sw) {
sw->state = STOPWATCH_STOPPED;
sw->start_time = 0;
sw->pause_time = 0;
sw->elapsed_time = 0;
sw->lap_count = 0;
for (int i = 0; i < 10; i++) {
sw->lap_times[i] = 0.0;
}
}
void lap_stopwatch(Stopwatch *sw) {
if (sw->state == STOPWATCH_RUNNING && sw->lap_count < 10) {
double current_time = (double)(clock() - sw->start_time) / CLOCKS_PER_SEC;
sw->lap_times[sw->lap_count] = current_time;
sw->lap_count++;
}
}
void display_stopwatch() {
int choice;
init_stopwatch(&stopwatch);
while (1) {
system("cls");
printf("=========================================\n");
printf(" 秒表计时器\n");
printf("=========================================\n");
update_stopwatch_display(&stopwatch);
printf("\n请选择操作:\n");
printf("1. 开始/继续\n");
printf("2. 暂停\n");
printf("3. 重置\n");
printf("4. 计次\n");
printf("0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
start_stopwatch(&stopwatch);
break;
case 2:
pause_stopwatch(&stopwatch);
break;
case 3:
reset_stopwatch(&stopwatch);
break;
case 4:
lap_stopwatch(&stopwatch);
break;
case 0:
return;
default:
printf("无效选择!\n");
Sleep(1000);
break;
}
}
}
void update_stopwatch_display(Stopwatch *sw) {
double elapsed_seconds;
if (sw->state == STOPWATCH_RUNNING) {
elapsed_seconds = (double)(clock() - sw->start_time) / CLOCKS_PER_SEC;
} else if (sw->state == STOPWATCH_PAUSED) {
elapsed_seconds = (double)sw->elapsed_time / CLOCKS_PER_SEC;
} else {
elapsed_seconds = 0.0;
}
int hours = (int)elapsed_seconds / 3600;
int minutes = ((int)elapsed_seconds % 3600) / 60;
int seconds = (int)elapsed_seconds % 60;
int milliseconds = (int)((elapsed_seconds - (int)elapsed_seconds) * 100);
printf("\n ╔════════════════════════════╗\n");
printf(" ║ 秒表计时器 ║\n");
printf(" ╠════════════════════════════╣\n");
printf(" ║ %02d:%02d:%02d.%02d ║\n",
hours, minutes, seconds, milliseconds);
printf(" ║ 状态: %s ║\n",
sw->state == STOPWATCH_RUNNING ? "运行中" :
sw->state == STOPWATCH_PAUSED ? "已暂停" : "已停止");
printf(" ╚════════════════════════════╝\n");
// 显示计次
if (sw->lap_count > 0) {
printf("\n计次记录:\n");
for (int i = 0; i < sw->lap_count; i++) {
int lap_hours = (int)sw->lap_times[i] / 3600;
int lap_minutes = ((int)sw->lap_times[i] % 3600) / 60;
int lap_seconds = (int)sw->lap_times[i] % 60;
int lap_ms = (int)((sw->lap_times[i] - (int)sw->lap_times[i]) * 100);
printf(" 计次 %d: %02d:%02d:%02d.%02d\n",
i + 1, lap_hours, lap_minutes, lap_seconds, lap_ms);
}
}
}
2.12 倒计时头文件 (countdown.h)
#ifndef COUNTDOWN_H
#define COUNTDOWN_H
#include <stdio.h>
#include <time.h>
// 倒计时状态
typedef enum {
COUNTDOWN_STOPPED,
COUNTDOWN_RUNNING,
COUNTDOWN_FINISHED
} CountdownState;
// 倒计时结构体
typedef struct {
CountdownState state;
int hours;
int minutes;
int seconds;
time_t end_time;
} Countdown;
// 初始化倒计时
void init_countdown(Countdown *cd);
// 设置倒计时时间
void set_countdown_time(Countdown *cd, int hours, int minutes, int seconds);
// 开始倒计时
void start_countdown(Countdown *cd);
// 停止倒计时
void stop_countdown(Countdown *cd);
// 显示倒计时
void display_countdown();
// 更新倒计时显示
void update_countdown_display(Countdown *cd);
#endif
2.13 倒计时功能实现 (countdown.c)
#include "countdown.h"
#include "utils.h"
static Countdown countdown;
void init_countdown(Countdown *cd) {
cd->state = COUNTDOWN_STOPPED;
cd->hours = 0;
cd->minutes = 0;
cd->seconds = 0;
cd->end_time = 0;
}
void set_countdown_time(Countdown *cd, int hours, int minutes, int seconds) {
cd->hours = hours;
cd->minutes = minutes;
cd->seconds = seconds;
}
void start_countdown(Countdown *cd) {
if (cd->state == COUNTDOWN_STOPPED || cd->state == COUNTDOWN_FINISHED) {
int total_seconds = cd->hours * 3600 + cd->minutes * 60 + cd->seconds;
cd->end_time = time(NULL) + total_seconds;
cd->state = COUNTDOWN_RUNNING;
}
}
void stop_countdown(Countdown *cd) {
cd->state = COUNTDOWN_STOPPED;
}
void display_countdown() {
int choice;
int hours, minutes, seconds;
init_countdown(&countdown);
while (1) {
system("cls");
printf("=========================================\n");
printf(" 倒计时器\n");
printf("=========================================\n");
update_countdown_display(&countdown);
printf("\n请选择操作:\n");
printf("1. 设置时间并开始\n");
printf("2. 停止\n");
printf("3. 重置\n");
printf("0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("请输入倒计时时间 (时 分 秒): ");
scanf("%d %d %d", &hours, &minutes, &seconds);
set_countdown_time(&countdown, hours, minutes, seconds);
start_countdown(&countdown);
break;
case 2:
stop_countdown(&countdown);
break;
case 3:
init_countdown(&countdown);
break;
case 0:
return;
default:
printf("无效选择!\n");
Sleep(1000);
break;
}
// 检查倒计时是否结束
if (countdown.state == COUNTDOWN_RUNNING) {
if (time(NULL) >= countdown.end_time) {
countdown.state = COUNTDOWN_FINISHED;
printf("\n*** 倒计时结束! ***\n");
Beep(1000, 1000);
Sleep(2000);
}
}
}
}
void update_countdown_display(Countdown *cd) {
int remaining_seconds = 0;
if (cd->state == COUNTDOWN_RUNNING) {
remaining_seconds = (int)(cd->end_time - time(NULL));
if (remaining_seconds < 0) remaining_seconds = 0;
} else if (cd->state == COUNTDOWN_STOPPED) {
remaining_seconds = cd->hours * 3600 + cd->minutes * 60 + cd->seconds;
}
int hours = remaining_seconds / 3600;
int minutes = (remaining_seconds % 3600) / 60;
int seconds = remaining_seconds % 60;
printf("\n ╔════════════════════════════╗\n");
printf(" ║ 倒计时器 ║\n");
printf(" ╠════════════════════════════╣\n");
printf(" ║ %02d:%02d:%02d ║\n", hours, minutes, seconds);
printf(" ║ 状态: %s ║\n",
cd->state == COUNTDOWN_RUNNING ? "运行中" :
cd->state == COUNTDOWN_FINISHED ? "已结束" : "已停止");
printf(" ╚════════════════════════════╝\n");
}
2.14 工具函数头文件 (utils.h)
#ifndef UTILS_H
#define UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
// 清屏
void clear_screen();
// 延时
void delay_ms(int milliseconds);
// 获取星期几的名称
const char* get_weekday_name(int weekday);
// 播放提示音
void play_beep(int frequency, int duration);
#endif
2.15 工具函数实现 (utils.c)
#include "utils.h"
void clear_screen() {
system("cls");
}
void delay_ms(int milliseconds) {
Sleep(milliseconds);
}
const char* get_weekday_name(int weekday) {
static const char* weekdays[] = {
"日", "一", "二", "三", "四", "五", "六"
};
if (weekday >= 0 && weekday <= 6) {
return weekdays[weekday];
}
return "未知";
}
void play_beep(int frequency, int duration) {
Beep(frequency, duration);
}
2.16 编译脚本 (Makefile)
CC = gcc
CFLAGS = -Wall -Wextra -std=c99
LIBS = -lwinmm
TARGET = calendar_clock.exe
SRCS = main.c calendar.c clock.c lunar.c alarm.c stopwatch.c countdown.c utils.c
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
del /f *.o *.exe
run: $(TARGET)
$(TARGET)
.PHONY: all clean run
参考代码 多功能万年历时钟系统 www.youwenfan.com/contentcnv/117967.html
三、功能特点
数字时钟:显示当前时间、日期和星期
万年历:显示公历和农历日期
农历计算:天干地支、生肖、节气
节日提醒:自动识别节假日和周末
闹钟管理:支持多个闹钟,可设置重复提醒
秒表计时:精确到百分之一秒的计时器
倒计时器:可设置任意时间的倒计时
控制台界面:简洁易用的字符界面
数据持久化:闹钟设置自动保存
四、使用说明
4.1 编译运行
# 使用Makefile编译
make
# 或直接编译
gcc -o calendar_clock.exe main.c calendar.c clock.c lunar.c alarm.c stopwatch.c countdown.c utils.c -lwinmm
# 运行程序
calendar_clock.exe
4.2 主要功能
- 时钟显示:实时显示当前时间和日期
- 日历查看:显示当月日历,包含农历和节气信息
- 闹钟管理:添加、删除、启用/禁用闹钟
- 秒表计时:开始、暂停、重置和计次功能
- 倒计时器:设置倒计时时间并开始倒计时
4.3 操作说明
- 使用数字键选择功能
- 在闹钟管理中可以设置多个闹钟
- 秒表支持计次功能,记录分段成绩
- 倒计时结束会发出提示音
4.4 注意事项
- 程序运行在Windows控制台环境
- 需要Windows API支持(winmm.lib)
- 农历计算使用简化算法,实际精度可能有限
- 闹钟数据保存在alarms.dat文件中