当前位置: 首页 > news >正文

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区别


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。

 

http://www.dtcms.com/a/118153.html

相关文章:

  • 组合与括号生成(回溯)
  • 开源模型应用落地-Qwen2.5-Omni-7B模型-Gradio-部署 “光速” 指南(二)
  • 2012年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析
  • React-04React组件状态(state),构造器初始化state以及数据读取,添加点击事件并更改state状态值
  • 深度学习篇---Prophet时间序列预测工具
  • 使用stm32cubeide stm32f407 lan8720a freertos lwip 实现udp client网络数据转串口数据过程详解
  • Scala相关知识学习总结5
  • 简述Unity对多线程的支持限制和注意事项
  • 【橘子大模型】使用streamlit来构建自己的聊天机器人(下)
  • echarts生成3D立体地图react组件
  • T-SQL语言的压力测试
  • Redis 面经
  • 基础算法篇(4)(蓝桥杯常考点)—数据结构(进阶)
  • (三)深入了解AVFoundation-播放:AVPlayer 进阶 播放状态 进度监听全解析
  • Spring Boot 自动装配原理
  • 前端如何检测项目中新版本的发布?
  • 聊聊Spring AI的RedisVectorStore
  • Lua 第5部分 表
  • 图的储存+图的遍历
  • Spring Boot 整合 Servlet三大组件(Servlet / Filter / Listene)
  • 开源大语言模型智能体应用开发平台——Dify
  • 项目复杂业务的数据流解耦处理方案整理
  • Java命令模式详解
  • Java面试39-Zookeeper中的Watch机制的原理
  • 前端服务配置详解:从入门到实战
  • 鸿蒙版小红书如何让图库访问完全由“你”掌控
  • 2025.04.07【数据科学新工具】| dynverse:数据标准化、排序、模拟与可视化的综合解决方案
  • MQTT-Dashboard-数据集成-WebHook、日志管理
  • 深入理解STAR法则
  • 如何开通google Free Tier长期免费云服务器(1C/1G)