Linux时间函数3-strftime时间格式转换、asctime时间固定格式、asctime_r线程安全、strftime/asctime/ctime区别

目录

1.strftime时间格式转换

1.1通用格式说明符:

1.2 strftime函数

1.2.1 C语言测试

1.2.2 shell脚本测试

2.asctime 函数‌

2.1 asctime多线程不安全

2.2 asctime_r线程安全版本

3.asctime、ctime、strftime区别


程序源码:https://pan.baidu.com/s/1j5_EM_ah-E__wGXKmJbasg?pwd=kmrf

1.strftime时间格式转换

strftime 是用于将时间格式化为字符串的函数。它的核心是通过格式说明符(如 %Y、%m 等)将日期和时间转换为自定义字符串。

1.1通用格式说明符:

符号含义示例
%Y四位年份2025
%m两位月份04
%d两位日期07
%H24 小时制小时15
%I12 小时制小时03
%M分钟30
%S45
%A星期全称Monday
%a星期简写Mon
%B月份全称April
%b月份简写Apr
%pAM/PMPM
%F等价于 %Y-%m-%d2025-04-07
%T等价于 %H:%M:%S15:30:45
%c本地日期时间Mon Apr 7 15:30:45 2025
%x

本地日期(等价于 %m/%d/%y

 04/07/25   (2025年4月7日)
%X本地时间(等价于 %H:%M:%S)20:33:42 
%Z时区名称 CST
%z时区偏移 +0800
%j一年中的第几天(001-366)097
%U一年中的第几周(周日为一周起始)14
%W一年中的第几周(周一为一周起始)14

1.2 strftime函数

1.2.1 C语言测试

函数原型:

#include <time.h>
size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr);

‌参数‌:
str:目标字符串缓冲区。
maxsize:缓冲区最大容量(防止溢出)。
format:格式字符串(使用 % 开头的符号)。
timeptr:指向 tm 结构体的指针(通过 localtime 或 gmtime 生成)。

程序:

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

/*
struct tm 
{
    int tm_sec;   // 秒 [0, 60](允许闰秒)
    int tm_min;   // 分 [0, 59]
    int tm_hour;  // 时 [0, 23]
    int tm_mday;  // 日 [1, 31]
    int tm_mon;   // 月 [0, 11](0 表示 1 月)
    int tm_year;  // 年(实际年份 = tm_year + 1900)
    int tm_isdst; // 夏令时标志(>0: 生效,0: 不生效,<0: 自动判断)
};
*/

/*
关键步骤‌
1.使用 time() 获取当前时间戳(time_t 类型)。
2.通过 localtime() 将时间戳转换为本地时间的 tm 结构体。
3.调用 strftime 将 tm 结构体格式化为字符串。
*/

int main() 
{
    time_t raw_time;
    struct tm *time_info;
    char buffer[64] = "";

    // 获取当前时间戳
    time(&raw_time);
    
    //将当前时间戳 转换为本地时间结构体
    time_info = localtime(&raw_time);

    // 格式化为字符串
    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S 星期:%A ", time_info);
    printf("strftime Time: %s\n", buffer); 

	/*
    %F	等价于 %Y-%m-%d		2025-04-07
	%T	等价于 %H:%M:%S		15:30:45
	*/
    strftime(buffer, sizeof(buffer), "%F %T 星期:%A ", time_info);
    printf("strftime Time: %s\n", buffer); 

	// Mon Apr  7 20:33:42 2025 - 04/07/25 - 20:33:42
    strftime(buffer, sizeof(buffer), "%c - %x - %X ", time_info);
    printf("strftime Time: %s\n", buffer); 

	// CST - +0800 - 097 - 14 - 14
    strftime(buffer, sizeof(buffer), "%Z - %z - %j - %U - %W", time_info);
    printf("strftime Time: %s\n", buffer); 

    return 0;
}

运行结果:

注意:buffer空间大小需要大于存储时间字节。

1.2.2 shell脚本测试

程序:

#!/bin/bash

echo "strftime 时间格式符 shell脚本测试"

# 示例:输出当前时间(格式:2025-04-07 15:30:45)
date +"%Y-%m-%d %H:%M:%S"

# 输出:Monday, April 07, 2025 03:30 PM
date +"%A, %B %d, %Y %I:%M %p"

# 输出时间戳(秒级)
date +"%s"


str=$(date +"%F %T")

#输出变量
echo "str:"
echo $str

运行结果:

2.asctime 函数‌

2.1 asctime多线程不安全

函数功能‌:

asctime 是 C 标准库中的函数,用于将 struct tm 时间结构体转换为‌固定格式的字符串‌。 输出格式示例:Wed Jun 30 21:49:08 1993\n(末尾自动添加换行符 \n 和终止符 \0

函数原型:

#include <time.h>
char *asctime(const struct tm *timeptr);

参数‌:
timeptr – 指向 struct tm 结构体的指针(通常由 localtime 或 gmtime 生成)。
‌返回值‌:
返回静态分配的字符串指针(格式固定),‌多线程不安全‌。

输出格式:

输出格式说明‌
生成的字符串格式固定为:
星期缩写 月份缩写 日 时:分:秒 年份\n\0

‌字段细节‌:
‌星期缩写‌:3 字母(如 Mon, Tue)。
‌月份缩写‌:3 字母(如 Jan, Apr)。
‌日‌:若为个位数,前方补空格(如 7 显示为 7)。
‌时间‌:24 小时制(如 15:30:45)。
‌年份‌:4 位数字(如 2025)。

程序:

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

/*
struct tm 
{
    int tm_sec;   // 秒 [0, 60](允许闰秒)
    int tm_min;   // 分 [0, 59]
    int tm_hour;  // 时 [0, 23]
    int tm_mday;  // 日 [1, 31]
    int tm_mon;   // 月 [0, 11](0 表示 1 月)
    int tm_year;  // 年(实际年份 = tm_year + 1900)
    int tm_isdst; // 夏令时标志(>0: 生效,0: 不生效,<0: 自动判断)
};
*/

int main() 
{
    time_t raw_time;
    struct tm *time_info;

    // 获取当前时间戳
    time(&raw_time);
    
    // 转换为本地时间的 tm 结构体
    time_info = localtime(&raw_time);

    // 转换为固定格式字符串
    char *time_str = asctime(time_info);
    printf("asctime: %s", time_str);
    // 输出示例:Wed Apr  7 15:30:45 2025

    return 0;
}

运行结果:

2.2 asctime_r线程安全版本

asctime_r 是 Linux 特有的线程安全函数,需手动提供缓冲区:

函数原型:

#include <time.h>
char *asctime_r(const struct tm *timeptr, char *buf);

参数‌:
timeptr:指向 struct tm 结构体的指针(通常由 localtime_r
 或 gmtime_r 生成)。

buf:用户提供的缓冲区,‌长度至少为 26 字节‌(固定格式字符串占 26 字节,
包含换行符 \n 和终止符 \0)。

‌返回值‌:
成功:返回指向 buf 的指针。
失败:返回 NULL(如 timeptr 或 buf 为非法指针)。

使用步骤:

  1. 定义缓冲区(≥26 字节)。
  2. 获取时间戳并转换为 struct tm(使用线程安全的 localtime_r 或 gmtime_r)。
  3. 调用 asctime_r 转换时间格式

程序:

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

/*
struct tm 
{
    int tm_sec;   // 秒 [0, 60](允许闰秒)
    int tm_min;   // 分 [0, 59]
    int tm_hour;  // 时 [0, 23]
    int tm_mday;  // 日 [1, 31]
    int tm_mon;   // 月 [0, 11](0 表示 1 月)
    int tm_year;  // 年(实际年份 = tm_year + 1900)
    int tm_isdst; // 夏令时标志(>0: 生效,0: 不生效,<0: 自动判断)
};
*/

int main()
{
    time_t raw_time;
    struct tm time_info;
    char buffer[64];  // 必须至少 26 字节

    // 获取当前时间戳
    time(&raw_time);
    
    // 转换为本地时间(线程安全)
    localtime_r(&raw_time, &time_info);
    
    // 转换为固定格式字符串
    if (asctime_r(&time_info, buffer) != NULL) 
    {
        printf("Time: %s", buffer);  // 输出示例:Mon Apr  7 15:30:45 2025\n
    } 
    else 
    {
        perror("asctime_r failed");
    }

    return 0;
}

运行结果:

3.asctime、ctime、strftime区别

特性asctimectimestrftime
输入类型struct tmtime_tstruct tm
输出格式固定格式固定格式(本地时间)完全自定义
线程安全
缓冲区来源静态内存静态内存用户提供
灵活性
替代方案asctime_r(线程安全)ctime_r(线程安全)无(本身安全)

1.关键区别

(1)输入参数:

  • asctime 处理 struct tm。
  • ctime 处理 time_t(自动转换为本地时间)。
  • strftime 处理 struct tm,但允许自定义格式。

(2)线程安全:

  • asctime 和 ctime 非线程安全(依赖静态内存)。
  • strftime 线程安全(需用户管理缓冲区)。

(3)格式控制:

  • asctime 和 ctime 输出固定格式。
  • strftime 支持任意格式(如 %Y-%m-%d)。

2.选择建议

  • 简单输出:单线程下用 asctime 或 ctime。
  • 多线程:改用 asctime_r/ctime_r 或 strftime。
  • 自定义格式:必须使用 strftime。

/opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:64:11: error: &#39;::clock&#39; has not been declared using ::clock; ^~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:65:11: error: &#39;::difftime&#39; has not been declared using ::difftime; ^~~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:66:11: error: &#39;::mktime&#39; has not been declared using ::mktime; ^~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:67:11: error: &#39;::time&#39; has not been declared using ::time; ^~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:68:11: error: &#39;::asctime&#39; has not been declared using ::asctime; ^~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:69:11: error: &#39;::ctime&#39; has not been declared using ::ctime; ^~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:70:11: error: &#39;::gmtime&#39; has not been declared using ::gmtime; ^~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:71:11: error: &#39;::localtime&#39; has not been declared using ::localtime; ^~~~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:72:11: error: &#39;::strftime&#39; has not been declared using ::strftime; ^~~~~~~~ In file included from /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/chrono:41:0, from /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/mutex:39, from /home/cwq/SourceLibrary/opencv/opencv_cross_compile/opencv/modules/core/include/opencv2/core/utility.hpp:62, from /home/cwq/SourceLibrary/opencv/opencv_cross_compile/opencv/modules/core/src/precomp.hpp:49, from /home/cwq/SourceLibrary/opencv/opencv_cross_compile/opencv/modules/core/src/arithm.dispatch.cpp:5: /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:64:11: error: &#39;::clock&#39; has not been declared using ::clock; ^~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:65:11: error: &#39;::difftime&#39; has not been declared using ::difftime; ^~~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:66:11: error: &#39;::mktime&#39; has not been declared using ::mktime; ^~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:67:11: error: &#39;::time&#39; has not been declared using ::time; ^~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:68:11: error: &#39;::asctime&#39; has not been declared using ::asctime; ^~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:69:11: error: &#39;::ctime&#39; has not been declared using ::ctime; ^~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:70:11: error: &#39;::gmtime&#39; has not been declared using ::gmtime; ^~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:71:11: error: &#39;::localtime&#39; has not been declared using ::localtime; ^~~~~~~~~ /opt/linux/x86-arm/aarch64-mix210-linux/aarch64-linux-gnu/include/c++/7.3.0/ctime:72:11: error: &#39;::strftime&#39; has not been declared using ::strftime; ^~~~~~~~ modules/core/CMakeFiles/opencv_core.dir/build.make:281: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/buffer_area.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/buffer_area.cpp.o] Error 1 make[2]: *** Waiting for unfinished jobs.... modules/core/CMakeFiles/opencv_core.dir/build.make:545: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/cuda_host_mem.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/cuda_host_mem.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:521: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/cuda_gpu_mat.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/cuda_gpu_mat.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:425: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/convert_c.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/convert_c.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:89: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/algorithm.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/algorithm.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:233: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/batch_distance.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/batch_distance.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:305: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/channels.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/channels.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:401: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/convert.dispatch.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/convert.dispatch.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:497: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/count_non_zero.dispatch.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/count_non_zero.dispatch.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:113: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/alloc.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/alloc.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:257: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/bindings_utils.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/bindings_utils.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:185: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/array.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/array.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:377: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/conjugate_gradient.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/conjugate_gradient.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:473: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/copy.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/copy.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:329: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/check.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/check.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:449: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/convert_scale.dispatch.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/convert_scale.dispatch.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:137: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/arithm.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/arithm.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:353: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/command_line_parser.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/command_line_parser.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:209: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/async.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/async.cpp.o] Error 1 modules/core/CMakeFiles/opencv_core.dir/build.make:161: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/src/arithm.dispatch.cpp.o&#39; failed make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/src/arithm.dispatch.cpp.o] Error 1 CMakeFiles/Makefile2:2622: recipe for target &#39;modules/core/CMakeFiles/opencv_core.dir/all&#39; failed make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2 Makefile:162: recipe for target &#39;all&#39; failed make: *** [all] Error 2
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值