手寫日期加減邏輯極易出錯(閏年、大小月、跨年/跨世紀)。C 標準庫 `
#include#include #include #include #define SECONDS_PER_DAY (60 * 60 * 24) void nextDay(char *dateStr) { struct tm tm = {0}; time_t seconds; char *p; // 1. 解析字符串 p = strtok(dateStr, "/"); tm.tm_year = atoi(p) - 1900; // tm_year: 年份-1900 p = strtok(NULL, "/"); tm.tm_mon = atoi(p) - 1; // tm_mon: 0-11 p = strtok(NULL, "/"); tm.tm_mday = atoi(p); // tm_mday: 1-31 // 2. 設置固定時間(避免 DST 歧義) tm.tm_hour = 12; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; // 讓 mktime 自動判斷夏令時 // 3. 轉為 time_t 並加一天 seconds = mktime(&tm) + SECONDS_PER_DAY; // 4. 轉回 tm 並格式化輸出 struct tm *next = gmtime(&seconds); // 或 localtime 視時區需求 printf("%d/%d/%d\n", next->tm_year + 1900, next->tm_mon + 1, next->tm_mday); } int main() { char input[20]; printf("請輸入日期 (YYYY/MM/DD):"); scanf("%19s", input); nextDay(input); return 0; }
| 步驟 | 函數/字段 | 說明 |
|---|---|---|
| 解析 | strtok/atoi | 分割字符串,轉整數 |
| 填充 tm | tm_year/mon/mday | 注意年份-1900、月份-1 |
| 固定時分秒 | tm_hour=12 | 避免午夜 DST 切換導致日期跳變 |
| 轉時間戳 | mktime() | 自動修正無效日期(如 2/30→3/2),返回 time_t |
| 加一天 | + 86400 | time_t 通常以秒為單位 |
| 轉回日曆 | gmtime/localtime | gmtime 為 UTC,localtime 為本地時區 |
| 格式化輸出 | tm_year/mon/mday | 還原年/月/日 |
輸入:2004/12/31 → 輸出:2005/1/1 (跨年) 輸入:2020/2/28 → 輸出:2020/2/29 (閏年) 輸入:2021/2/28 → 輸出:2021/3/1 (平年) 輸入:2023/1/31 → 輸出:2023/2/1 (大月→小月) 輸入:2023/4/30 → 輸出:2023/5/1 (30天月份)