1. Linux平台下,利用 strptime() 函数解析字符串时间
利用 strftime() 函数可将 struct tm 类型转化为字符串格式的时间,同样也可将字符串格式的时间转化为 struct tm 类型。在 Linux 平台下,可以借助 strptime() 函数完成此功能。strptime() 共三个参数,一是待解析的字符串,二是待解析字符串的格式,三是解析完成后的 struct tm 类型的时间变量。返回值为未能解析的部分字符串。
#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>
void TestStrptime(){
// 获取日历时间
time_t current_time = time(NULL);
struct tm* calendar = localtime(¤t_time);
// 日历时间转为字符串,2021-08-10 08:30:00
char calendar_time[20];
strftime(calendar_time, 20, "%F %T", calendar);
puts(calendar_time);
// 字符串转化为 struct tm 日历时间
struct tm parsed_time;
// 三个参数,一是待解析的字符串,二是待解析字符串的格式,三是解析完成后的 struct tm 类型时间变量
char *unparsed_string = strptime(calendar_time, "%F %T", &parsed_time);
printf("%d/%d/%d %d:%d:%d\n",
parsed_time.tm_year + 1900, parsed_time.tm_mon + 1, parsed_time.tm_mday,
parsed_time.tm_hour, parsed_time.tm_min, parsed_time.tm_sec);
puts(unparsed_string);
}
注意,未能解析的部分字符串可以利用 sscanf() 函数按照一定格式再次解析。sscanf() 函数可以将字符串按照一定格式进行匹配,并将匹配结果放入到指定变量中。例如未能解析的字符串为 ".123",那么可以利用 ".%3d" 获取到 123 存入到指定变量。
void TestStrptime(){
char *time_example = "2021-08-10 08:40:00.123"; // 待解析字符串
// 字符串转化为 struct tm 日历时间
struct tm parsed_time;
// 三个参数,一是待解析的字符串,二是待解析字符串的格式,三是解析完成后的 struct tm 类型时间变量
char *unparsed_string = strptime(time_example, "%F %T", &parsed_time);
printf("%d/%d/%d %d:%d:%d\n",
parsed_time.tm_year + 1900, parsed_time.tm_mon + 1, parsed_time.tm_mday,
parsed_time.tm_hour, parsed_time.tm_min, parsed_time.tm_sec);
puts(unparsed_string); // .123,不能解析 .123 部分
// 未解析的可以利用sscanf() 函数进行解析
int millisecond;
sscanf(unparsed_string, ".%3d", &millisecond);
printf("millisecond: %d\n", millisecond);
}
2. Windows 平台下,利用 sscanf() 函数解析字符串时间
windows 平台无法使用 strptime() 函数。但可以按照给定字符串时间的格式,利用 sscanf() 函数将各个时间属性获取。解析过程中注意两点,一是 struct tm 类型存储的年份和月份分别是从 1900 和 0 开始的,解析之后需要减去 1900 和 1。二是在上述解析全部完成后,需要利用 mktime() 函数进行时间的格式化,以防给定的时间数据是非法的。
void TestSscanf(){
char *time_example = "2021-08-10 33:40:00.123"; // 待解析字符串
struct tm parsed_time;
int millisecond; // 存储毫秒
// 将对应的时间传给 parsed_time 各个属性
sscanf(time_example, "%4d-%2d-%2d %2d:%2d:%2d.%3d",
&parsed_time.tm_year, &parsed_time.tm_mon, &parsed_time.tm_mday,
&parsed_time.tm_hour, &parsed_time.tm_min, &parsed_time.tm_sec, &millisecond);
parsed_time.tm_year -= 1900; // 注意,该结构体的年份和月是从 1900 和 0 开始的
parsed_time.tm_mon -= 1;
mktime(&parsed_time); // 再经过一次格式化,确保各属性范围合法
printf("%d/%d/%d %d:%d:%d\n",
parsed_time.tm_year + 1900, parsed_time.tm_mon + 1, parsed_time.tm_mday,
parsed_time.tm_hour, parsed_time.tm_min, parsed_time.tm_sec);
printf("millisecond: %d", millisecond);
}