Skip to content

C 标准库 - <time.h>

概述

<time.h> 头文件提供了日期和时间处理功能,包括获取当前时间、格式化时间、计算时间差等。这是 C 语言中处理日期和时间的重要工具。

时间类型

time_t

表示日历时间的类型。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    printf("当前时间戳: %ld\n", current_time);
    
    return 0;
}

struct tm

表示分解时间的结构体。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    printf("年份: %d\n", local->tm_year + 1900);
    printf("月份: %d\n", local->tm_mon + 1);
    printf("日期: %d\n", local->tm_mday);
    printf("小时: %d\n", local->tm_hour);
    printf("分钟: %d\n", local->tm_min);
    printf("秒: %d\n", local->tm_sec);
    
    return 0;
}

struct timespec

表示高精度时间的结构体(POSIX)。

c
#include <stdio.h>
#include <time.h>

int main() {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    
    printf("秒: %ld\n", ts.tv_sec);
    printf("纳秒: %ld\n", ts.tv_nsec);
    
    return 0;
}

时间获取

time()

c
time_t time(time_t *tloc);

获取当前时间。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    
    current_time = time(NULL);
    printf("当前时间戳: %ld\n", current_time);
    
    time_t another_time;
    time(&another_time);
    printf("另一个时间戳: %ld\n", another_time);
    
    return 0;
}

clock()

c
clock_t clock(void);

获取程序运行的处理器时间。

c
#include <stdio.h>
#include <time.h>

int main() {
    clock_t start = clock();
    
    for (int i = 0; i < 100000000; i++) {
    }
    
    clock_t end = clock();
    double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    
    printf("运行时间: %.6f\n", elapsed);
    
    return 0;
}

gettimeofday()

c
int gettimeofday(struct timeval *tv, struct timezone *tz);

获取当前时间(POSIX)。

c
#include <stdio.h>
#include <sys/time.h>

int main() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    
    printf("秒: %ld\n", tv.tv_sec);
    printf("微秒: %ld\n", tv.tv_usec);
    
    return 0;
}

时间转换

localtime()

c
struct tm *localtime(const time_t *timep);

将时间戳转换为本地时间。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    printf("本地时间: %04d-%02d-%02d %02d:%02d:%02d\n",
           local->tm_year + 1900, local->tm_mon + 1, local->tm_mday,
           local->tm_hour, local->tm_min, local->tm_sec);
    
    return 0;
}

gmtime()

c
struct tm *gmtime(const time_t *timep);

将时间戳转换为 UTC 时间。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* utc = gmtime(&current_time);
    
    printf("UTC 时间: %04d-%02d-%02d %02d:%02d:%02d\n",
           utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
           utc->tm_hour, utc->tm_min, utc->tm_sec);
    
    return 0;
}

mktime()

c
time_t mktime(struct tm *timeptr);

将分解时间转换为时间戳。

c
#include <stdio.h>
#include <time.h>

int main() {
    struct tm timeinfo = {
        .tm_year = 124,
        .tm_mon = 0,
        .tm_mday = 1,
        .tm_hour = 0,
        .tm_min = 0,
        .tm_sec = 0
    };
    
    time_t timestamp = mktime(&timeinfo);
    printf("时间戳: %ld\n", timestamp);
    
    return 0;
}

asctime()

c
char *asctime(const struct tm *timeptr);

将分解时间转换为字符串。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    char* time_str = asctime(local);
    
    printf("时间字符串: %s", time_str);
    
    return 0;
}

ctime()

c
char *ctime(const time_t *timep);

将时间戳转换为字符串。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    char* time_str = ctime(&current_time);
    printf("时间字符串: %s", time_str);
    
    return 0;
}

strftime()

c
size_t strftime(char *s, size_t max, const char *format,
                const struct tm *tm);

格式化时间。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    char buffer[80];
    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local);
    printf("格式化时间: %s\n", buffer);
    
    return 0;
}

时间计算

difftime()

c
double difftime(time_t time1, time_t time0);

计算两个时间之间的差值。

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t start, end;
    
    time(&start);
    for (int i = 0; i < 100000000; i++) {
    }
    time(&end);
    
    double elapsed = difftime(end, start);
    printf("经过时间: %.2f\n", elapsed);
    
    return 0;
}

实际应用示例

1. 计时器

c
#include <stdio.h>
#include <time.h>

void start_timer(time_t* start) {
    time(start);
}

double stop_timer(time_t start) {
    time_t end;
    time(&end);
    return difftime(end, start);
}

int main() {
    time_t start;
    start_timer(&start);
    
    for (int i = 0; i < 100000000; i++) {
    }
    
    double elapsed = stop_timer(start);
    printf("执行时间: %.2f\n", elapsed);
    
    return 0;
}

2. 日期计算

c
#include <stdio.h>
#include <time.h>

void add_days(struct tm* date, int days) {
    date->tm_mday += days;
    mktime(date);
}

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* date = localtime(&current_time);
    
    printf("当前日期: %04d-%02d-%02d\n",
           date->tm_year + 1900, date->tm_mon + 1, date->tm_mday);
    
    add_days(date, 7);
    printf("7天后: %04d-%02d-%02d\n",
           date->tm_year + 1900, date->tm_mon + 1, date->tm_mday);
    
    return 0;
}

3. 时间格式化

c
#include <stdio.h>
#include <time.h>

void format_time(const char* format) {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    char buffer[100];
    strftime(buffer, sizeof(buffer), format, local);
    printf("%s\n", buffer);
}

int main() {
    printf("不同格式的时间:\n");
    format_time("%Y-%m-%d %H:%M:%S");
    format_time("%A, %B %d, %Y");
    format_time("%I:%M:%S %p");
    format_time("%Y年%m月%d%H时%M分%S秒");
    
    return 0;
}

4. 倒计时

c
#include <stdio.h>
#include <time.h>
#include <unistd.h>

void countdown(int seconds) {
    time_t start, current;
    time(&start);
    
    while (seconds > 0) {
        time(&current);
        double elapsed = difftime(current, start);
        
        if (elapsed >= 1.0) {
            printf("剩余时间: %d\n", seconds);
            seconds--;
            time(&start);
        }
    }
    
    printf("倒计时结束!\n");
}

int main() {
    countdown(5);
    return 0;
}

5. 性能测试

c
#include <stdio.h>
#include <time.h>

void measure_performance(void (*func)(void), const char* name) {
    clock_t start = clock();
    func();
    clock_t end = clock();
    
    double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    printf("%s: %.6f\n", name, elapsed);
}

void test_function() {
    for (int i = 0; i < 100000000; i++) {
    }
}

int main() {
    measure_performance(test_function, "测试函数");
    return 0;
}

6. 时间戳转换

c
#include <stdio.h>
#include <time.h>

void timestamp_to_string(time_t timestamp, char* buffer, size_t size) {
    struct tm* local = localtime(&timestamp);
    strftime(buffer, size, "%Y-%m-%d %H:%M:%S", local);
}

time_t string_to_timestamp(const char* str) {
    struct tm timeinfo = {0};
    sscanf(str, "%d-%d-%d %d:%d:%d",
           &timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
           &timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec);
    
    timeinfo.tm_year -= 1900;
    timeinfo.tm_mon -= 1;
    
    return mktime(&timeinfo);
}

int main() {
    time_t timestamp;
    time(&timestamp);
    
    char buffer[100];
    timestamp_to_string(timestamp, buffer, sizeof(buffer));
    printf("时间戳转字符串: %s\n", buffer);
    
    time_t new_timestamp = string_to_timestamp("2024-01-01 00:00:00");
    printf("字符串转时间戳: %ld\n", new_timestamp);
    
    return 0;
}

7. 时区转换

c
#include <stdio.h>
#include <time.h>

void show_timezone_info() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    struct tm* utc = gmtime(&current_time);
    
    printf("本地时间: %04d-%02d-%02d %02d:%02d:%02d\n",
           local->tm_year + 1900, local->tm_mon + 1, local->tm_mday,
           local->tm_hour, local->tm_min, local->tm_sec);
    
    printf("UTC 时间: %04d-%02d-%02d %02d:%02d:%02d\n",
           utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
           utc->tm_hour, utc->tm_min, utc->tm_sec);
    
    printf("时区偏移: %d 小时\n", local->tm_hour - utc->tm_hour);
}

int main() {
    show_timezone_info();
    return 0;
}

8. 日志时间戳

c
#include <stdio.h>
#include <time.h>

void log_message(const char* message) {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    char time_str[30];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", local);
    
    printf("[%s] %s\n", time_str, message);
}

int main() {
    log_message("程序启动");
    log_message("处理数据中...");
    log_message("任务完成");
    
    return 0;
}

9. 计算工作日

c
#include <stdio.h>
#include <time.h>

int is_weekday(struct tm* date) {
    int day = date->tm_wday;
    return (day != 0 && day != 6);
}

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* date = localtime(&current_time);
    
    const char* weekdays[] = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
    printf("今天是: %s\n", weekdays[date->tm_wday]);
    
    if (is_weekday(date)) {
        printf("今天是工作日\n");
    } else {
        printf("今天是周末\n");
    }
    
    return 0;
}

10. 高精度计时

c
#include <stdio.h>
#include <time.h>

void high_precision_timer() {
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    for (int i = 0; i < 100000000; i++) {
    }
    
    clock_gettime(CLOCK_MONOTONIC, &end);
    
    double elapsed = (end.tv_sec - start.tv_sec) + 
                    (end.tv_nsec - start.tv_nsec) / 1e9;
    
    printf("高精度计时: %.9f\n", elapsed);
}

int main() {
    high_precision_timer();
    return 0;
}

时间格式化说明符

常用格式化字符

  • %Y - 四位年份
  • %m - 月份 (01-12)
  • %d - 日期 (01-31)
  • %H - 小时 (00-23)
  • %M - 分钟 (00-59)
  • %S - 秒 (00-60)
  • %I - 小时 (01-12)
  • %p - AM/PM
  • %A - 星期名称
  • %B - 月份名称
  • %a - 星期缩写
  • %b - 月份缩写
  • %y - 两位年份
  • %j - 一年中的第几天
  • %U - 一年中的第几周 (周日开始)
  • %W - 一年中的第几周 (周一开始)
c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    
    printf("完整日期时间: %Y-%m-%d %H:%M:%S\n");
    printf("星期名称: %A\n");
    printf("月份名称: %B\n");
    printf("12小时制: %I:%M:%S %p\n");
    printf("一年中的第几天: %j\n");
    printf("一年中的第几周: %W\n");
    
    return 0;
}

注意事项

1. 时间戳范围

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t timestamp = time(NULL);
    
    printf("当前时间戳: %ld\n", timestamp);
    printf("最大时间戳: %ld\n", (time_t)-1);
    
    return 0;
}

2. 时区问题

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm* local = localtime(&current_time);
    struct tm* utc = gmtime(&current_time);
    
    printf("本地时间: %s", asctime(local));
    printf("UTC 时间: %s", asctime(utc));
    
    return 0;
}

3. 线程安全

c
#include <stdio.h>
#include <time.h>

int main() {
    time_t current_time;
    time(&current_time);
    
    struct tm local;
    localtime_r(&current_time, &local);
    
    printf("线程安全的时间: %04d-%02d-%02d\n",
           local.tm_year + 1900, local.tm_mon + 1, local.tm_mday);
    
    return 0;
}

4. 时钟精度

c
#include <stdio.h>
#include <time.h>

int main() {
    printf("CLOCKS_PER_SEC: %ld\n", CLOCKS_PER_SEC);
    
    clock_t start = clock();
    clock_t end = clock();
    
    double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    printf("最小可测时间: %.9f\n", elapsed);
    
    return 0;
}

总结

<time.h> 提供的时间处理功能是 C 语言编程的重要工具:

  1. 功能全面 - 涵盖时间获取、转换、格式化、计算等
  2. 易于使用 - 提供了简单直观的接口
  3. 广泛应用 - 几乎所有需要时间处理的程序都会使用

记住:

  • 注意时区问题,区分本地时间和 UTC 时间
  • 使用合适的函数进行时间转换
  • 注意时间戳的范围和精度
  • 在多线程环境中使用线程安全的函数
  • 根据需求选择合适的计时方法