C语言多功能万年历时钟系统

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 主要功能

  1. 时钟显示:实时显示当前时间和日期
  2. 日历查看:显示当月日历,包含农历和节气信息
  3. 闹钟管理:添加、删除、启用/禁用闹钟
  4. 秒表计时:开始、暂停、重置和计次功能
  5. 倒计时器:设置倒计时时间并开始倒计时

4.3 操作说明

4.4 注意事项

  1. 程序运行在Windows控制台环境
  2. 需要Windows API支持(winmm.lib)
  3. 农历计算使用简化算法,实际精度可能有限
  4. 闹钟数据保存在alarms.dat文件中

专注于matlab/simulink,电子电路,编程