C语言关于localtime_s()和asctime_s()两个函数的用法。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言关于localtime_s()和asctime_s()两个函数的用法。相关的知识,希望对你有一定的参考价值。

我是个C语言初学者,请教各位C高手,关于localtime_s()和asctime_s()的问题。
在visual studio 6.0里面,可以直接用localtime()把时间变量转换成结构体,然后再用 asctime()把这个结构体转换成ASCII码,然后可以用于显示。
比如:
#include <stdio.h>
#include <time.h>

void get_time(void);

int main()

get_time();
return 0;


void get_time(void)

time_t now;
time(&now);
printf("Current time is: %s\n",
asctime(localtime(&now)));

这个程序可以显示当前时间。
但是在visual studio .net 2005里面,有很多涉及到安全性的问题,很多函数都有变化,比如strcpy()就变成strcpy_s(),而且参数也多了一个。现在的问题是,localtime()变成了localtime_s(),asctime()变成了asctime_s(),而且函数的参数也变了。我看了help的讲解,但是还是用不对这两个函数。请各位C高手给予指点,给我讲讲新老格式的区别,并且将我上面的程序用localtime_s()和asctime_s()改写一下。万分感谢。恳请各位C高手指导我这个菜鸟一下。
嗯,是的,就是类型被强化以后,我总是改不对了。还请03013110这位高手能帮我把上面那段程序用localtime_s()和asctime_s()改写一下。要不然我还是不能明白。多谢了。

1、localtime函数:
原型:struct tm * localtime(const time_t * clock);
功能:把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地时间, 其中clock为秒数时间;
返回值:返回一个tm结构体的指针。tm结构体是time.h中定义的用于分别存储时间的各个量(年月日等)的结构体。
2、asctime函数:
原型:char* asctime (const struct tm * timeptr);
功能:把timeptr指向的tm结构体中储存的时间转换为字符串;
返回值:一个固定格式的字符串。字符串格式为:Www Mmm dd hh:mm:ss yyyy。其中Www为星期,Mmm为月份,dd为日,hh为时,mm为分,ss为秒,yyyy为年份;
3、例程:

#include<time.h>
#include<stdio.h>
int main()
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);//使用localtime函数把秒数时间rawtime转换为本地时间以tm结构体保存,并把tm结构体地址储存到timeinfo当中
    printf("当前日期为: %s",asctime(timeinfo));//使用asctime函数把tm结构体中储存的时间转换为字符串,并输出
    return 0;

参考技术A #include <stdio.h>
#include <time.h>

#define TIME_MAX 32

void get_time(void);

int main()

get_time();
getchar();
return 0;


void get_time(void)

time_t now;
time(&now);

// 定义两个变量,存储转换结果
struct tm tmTmp;
char stTmp[TIME_MAX];

// 转换为tm结构
localtime_s(&tmTmp,&now);

// 转换为字符串并输出
asctime_s(stTmp,&tmTmp);
printf("Current time is: %s\n",stTmp);
参考技术B 看帮助还不明白?不至于吧……
所谓的_s不过是把类型稍微的强化了一下,还有就是长度的控制,以防溢出而已……

Windows 上 localtime_s() 多线程性能不佳的解决方法

【中文标题】Windows 上 localtime_s() 多线程性能不佳的解决方法【英文标题】:Workaround for poor multithreaded performance of localtime_s() on Windows 【发布时间】:2016-03-02 14:46:38 【问题描述】:

似乎localtime_s()(相当于标准localtime_r)在MSVC 中包含一个临界区。

为了比较,这里有 2 个示例应用,一个在循环中执行 localtime_s,另一个在循环中执行 gmtime_s

http://rextester.com/OQJ48177 http://rextester.com/JNDR45936

分析显示从common_localtime_s&lt;__int64&gt; 调用的isindst 内部存在严重的锁争用:

gmtime 没有出现问题:

如果我的进程确实需要本地时间,是否有任何方法可以解决此问题以在多线程环境中获得稳定的localtime_s 性能?

【问题讨论】:

你真的经常调用这个函数以至于它是一个瓶颈吗? 是的,它目前占用了所有已用时间的 70%(64 个 CPU)。 是的,我也遇到过同样的问题。 localtime_s 在多线程环境中很慢。我无法找到解决方案。 锁保护了一些用于缓存DST计算结果的静态变量。你对此无能为力。如果您无法按照建议处理偏移量,您可能必须使用转换的替代实现。请注意,_localtime64_s 也调用了__tzset,它也需要一些锁,所以我敢打赌,即使你在_isindst 周围工作,它们仍然会咬你一些。 但是localtime 根据输入时间戳计算偏移量。如果输入位于 DST 中,则它会添加 DST 偏移量。没有一种简单的方法可以使用固定偏移量来解决这个问题。 【参考方案1】:

这是一个建议的解决方案:

以最快的速度记录所有时间。当通过 GUI、日志文件或其他方式将它们呈现给用户时,请转换为本地时间。

由于大多数 GUI 和日志输出都是单线程的,这应该消除程序其余部分的争用。

如果程序从不向用户呈现数据,那么只需将其以快速时间格式写出来,然后使用后处理工具对其进行转换或显示。

【讨论】:

确实,我最终在内部使用了gmtime。但我也通过复制 MS CRT 实现并将所有static 变量设置为thread_local 来实现localtime_lockfree(当然还要移除锁)。不幸的是,我无法共享生成的代码,因为 MSCRT 许可证禁止共享修改后的源:(【参考方案2】:

由于标准实现使用锁并且没有简单的解决方法,您可能不得不使用不同的实现。我建议尝试以GetTimeZoneInformationForYear 为基础,这将为您提供标准和 DST 时间以及 DST 处于活动状态的日期与 UTC 的偏移量。您还可以选择为您关心的每一年调用一次,并缓存结果以供所有线程使用。

由于gmtime_s 的表现可以接受,我建议您使用它来获取年份。 (注意这是localtime_s 所做的。)减去GetTimeZoneInformationForYear 提供的适当偏差值,然后再次使用gmtime_s 将其拆分为日期组件。

【讨论】:

非常有趣。似乎 MS CRT 中的实现不使用此 API,但始终使用当前时区 (GetTimeZoneInformation),因此这样做实际上可以更准确。顺便说一句,CRT 实现还支持 TZ 环境变量作为覆盖。

以上是关于C语言关于localtime_s()和asctime_s()两个函数的用法。的主要内容,如果未能解决你的问题,请参考以下文章

C语言如何返回格式化日期时间?(将日期和时间以字符串格式输出)ctime()asctime()localtime()

c语言,如何进行日期格式转换??

asctime与ctime的区别

vs2013写c++程序,其中localtime_s函数不接受一个参数怎么解决?!

localtime vs localtime_s 和适当的输入参数

如何用c语言获取当前系统时间