获取系统日期时间的简单方法


不用MFC类,直接使用C/C++ANSI标准库函数

1.time.h简介

日常编程中,常常需要获取系统的日期时间或对相关日期时间进行简单处理等。我常常使用MFC类库中的CMonthCalCtrl、 CDateTimeCtrl

CTime/CTimeSpan、COleDateTime/COleDateTimeSpan等类,它们提供了很强大的功能。但有时仅仅只需要获取当前的日期/时间,使用MFC类库感觉是大材小用啦(杀鸡焉用宰牛刀)。无意中发现,C/C++库或者系统API也为我们提供了相关的函数,简单搞定。能简单的就简单搞定,这也是一种境界哦(条条道路通罗马,只是看那条路好走/距离近)。查看MSDN,得到了关于日期时间的函数说明:

================================================================================================================================

Run-Time Library Reference

Time Management

Updated: November 2007

Use these functions to get the current time and convert, adjust, and storeit as necessary. The current time is the system time.

The _ftime and localtime routines use theTZenvironment variable. IfTZ is not set, the run-time library attempts touse the time-zone information specified by the operating system. If thisinformation is unavailable, these functions use the default value of PST8PDT.For more information onTZ, see_tzset; also see _daylight, timezone, and _tzname.

Time Routines

 

Function

Use

.NET Framework equivalent

 asctime, 

 _wasctime,

 asctime_s,

 _wasctime_s

Convert time from type struct tm to character

string.The versions of these functions with 

the_s suffix are more secure.

System::DateTime::ToLongDateString,

System::DateTime::ToLongTimeString, 

System::DateTime::ToShortDateString, 

System::DateTime::ToShortTimeString, 

System::DateTime::ToString

 clock

Return elapsed CPU time for process.

Not applicable. To call the standard C

 function, use PInvoke. For more

 information, see Platform Invoke

 Examples.

 ctime,

 _ctime32,

 _ctime64,

 _wctime, 

 _wctime32,

 _wctime64,

 _ctime_s,

 _ctime32_s,

 _ctime64_s,

 _wctime_s,

 _wctime32_s, 

 _wctime64_s

Convert time from type time_t, __time32_t

or __time64_t to character string. The

versions of these functions with the _s

suffix are more secure.

System::DateTime::GetDateTimeFormats, 

System::DateTime::ToString, 

System::DateTime::ToLongTimeString, 

System::DateTime::ToShortTimeString

 difftime,

 _difftime32,

 _difftime64

Compute difference between two times.

System::DateTime::Subtract

 _ftime,

 _ftime32, 

 _ftime64,

 _ftime_s,

 _ftime32_s,

 _ftime64_s

Store current system time in variable of 

type struct _timeb or type struct __timeb64

 The versions of these functions with the 

_s suffix are more secure.

System::DateTime::Now

 _futime, 

 _futime32, 

 _futime64

Set modification time on open file

System::IO::File::SetLastAccessTime, 

System::IO::File::SetLastWriteTime, 

System::IO::File::SetCreationTime

 gmtime, 

 _gmtime32,

 _gmtime64,

 _gmtime_s, 

 _gmtime32_s, 

 _gmtime64_s

Convert time from type time_t to struct

tm or from type __time64_t to struct tm.

The versions of these functions with the

_s suffix are more secure.

System::DateTime::UtcNow, 

System::DateTime::ToUniversalTime

 localtime,

 _localtime32, 

 _localtime64,

 localtime_s, 

 _localtime32_s, 

 _localtime64_s

Convert time from type time_t to struct 

tm or from type __time64_t to struct tm

with local correction. The versions of 

these functions with the _s suffix are 

more secure.

System::DateTime::ToLocalTime

 _mkgmtime,

 _mkgmtime32,

 _mkgmtime64

Convert time to calendar value in 

Greenwich Mean Time.

System::DateTime::ToUniversalTime

 mktime, 

 _mktime32,

 _mktime64

Convert time to calendar value.

System::DateTime::DateTime

 _strdate,

 _wstrdate,

 _strdate_s, 

 _wstrdate_s

Return current system date as string. 

The versions of these functions with 

the _s suffix are more secure.

System::DateTime::Parse

 strftime, 

 wcsftime, 

 _strftime_l,

 _wcsftime_l

Format date-and-time string for

international use.

System::DateTime::ToLongDateString,

 System::DateTime::ToLongTimeString, 

System::DateTime::ToShortDateString, 

System::DateTime::ToShortTimeString, 

System::DateTime::ToString

 _strtime, 

 _wstrtime,

 _strtime_s,

 _wstrtime_s

Return current system time as string.

The versions of these functions with 

the _s suffix are more secure.

System::DateTime::ToLongDateString,

 System::DateTime::ToLongTimeString, 

System::DateTime::ToShortDateString, 

System::DateTime::ToShortTimeString, 

System::DateTime::ToString

 time,

 _time32,

 _time64

Get current system time as type time_t,

__time32_t or as type __time64_t.

Not applicable. To call the standard C 

function, use PInvoke. For more

 information, see Platform Invoke

 Examples.

 _tzset

Set external time variables from environment 

time variable TZ.

Not applicable. To call the standard C

 function,use PInvoke. For more

 information, see Platform Invoke 

Examples.

 _utime,

 _utime32, 

 _utime64,

 _wutime,

 _wutime32, 

 _wutime64

Set modification time for specified file using

either current time or time value stored in 

structure.

Not applicable. To call the standard C 

function, use PInvoke. For more 

information, see Platform Invoke 

Examples.

以上函数都包含在time.h中,time.h是C标准函数库中获取时间与日期、对时间与日期数据操作及格式化的头文件。下面结合MSDN,用实例对它们的使用做一个大体的介绍和演示,具体请参考MSDN.

2.基本相关概念:

在使用上面的相关函数之前,先了解一些“时间”和“日期”的概念,主要有以下几个: 

Coordinated Universal Time(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。

Calendar Time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。 

epoch:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。 

clock tick:时钟计时单元(而不把它叫做时钟滴答次数),一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。 

我们可以使用ANSI标准库中的time.h头文件。这个头文件中定义的时间和日期所使用的方法,无论是在结构定义,还是命名,都具有明显的C语言风格。下面,我将说明在C/C++中怎样使用日期的时间功能。

3. 获取日历时间:

    time_tltime;

ltime = time(NULL);//或者time(&m_nEdit1)

注意:使用time(NULL)函数得到是距离1970-01-01 00:00:00经历的秒数。要想得到一般的日期时间格式还需要转换。

常用为:srand((unsigned)time(NULL));//产生随机数种子,想必大家都见过的。

4.获取日期和时间:

这里说的日期和时间就是我们平时所说的年、月、日、时、分、秒等信息。这些信息都保存在一个名为tm的结构体中,tm的标准定义为:

#ifndef _TM_DEFINED

struct tm {

       int tm_sec;     /* seconds afterthe minute - [0,59] */

       int tm_min;     /* minutes afterthe hour - [0,59] */

       int tm_hour;    /* hours sincemidnight - [0,23] */

       int tm_mday;    /* day of themonth - [1,31] */

       int tm_mon;     /* months sinceJanuary - [0,11] */

       int tm_year;    /* years since1900 */

       int tm_wday;    /* days sinceSunday - [0,6] */

       int tm_yday;    /* days sinceJanuary 1 - [0,365] */

       int tm_isdst;   /* daylightsavings time flag */

       };

#define _TM_DEFINED

#endif

那么如何将一个日历时间(time_t)保存为一个tm结构的对象呢?

我们可以使用的函数是gmtime()和localtime(),这两个函数的原型为: 

struct tm *gmtime(consttime_t *timer);  
struct tm *localtime(const time_t * timer); 

其中gmtime()函数是将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间,而localtime()函数是将日历时间转化为本地时间。比如现在用gmtime()函数获得的世界标准时间是2005年7月30日7点18分20秒,那么我用localtime()函数在中国地区获得的本地时间会比世界标准时间晚8个小时,即2005年7月30日15点18分20秒。

5.格式转换:

(1)固定格式

我们可以通过asctime()函数和ctime()函数将时间以固定的格式显示出来,两者的返回值都是char*型的字符串。返回的时间格式为: 

星期几 月份 日期 时:分:秒 年\n\0  
例如:Wed Jan 02 02:03:55 1980\n\0 

其中\n是一个换行符,\0是一个空字符,表示字符串结束。

下面是两个函数的原型: 

char*asctime(const structtm* timeptr); 
char *ctime(const time_t *timer); 

其中asctime()函数是通过tm结构来生成具有固定格式的保存时间信息的字符串,而ctime()是通过日历时间来生成时间字符串。这样的话,asctime()函数只是把tm结构对象中的各个域填到时间字符串的相应位置就行了,而ctime()函数需要先参照本地的时间设置,把日历时间转化为本地时间,然后再生成格式化后的字符串。

也可以使用_strdate()和_strtime()函数直接输出固定格式的日期好时间,两个函数的原型: 

char*_strdate(char *datestr );//返回固定格式的本地日期

char*_strtime(char *timestr );// 返回固定格式的本地时间

我一般使用这两个函数来获取当前的系统日期和时间,比使用CTime类快捷多了,也推荐大家使用。

(2)自定义格式

可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下: 

size_tstrftime(  
char *strDest,  
size_t maxsize,  
const char *format,  
const struct tm *timeptr  
);  
我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。  具体格式请参看MSDN.

6.时间计时:

有时候在实际应用中要计算一个事件持续的时间长度,比如计算打字速度。可以使用clock()函数和difftime()函数,clock()可以精确到毫秒,difftime()只能精确到秒。函数的定义如下: 

clock_t clock( void ); 

double difftime(time_t time1, time_ttime0); 

clock()函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock)。其中clock_t是用来保存时间的数据类型,在time.h文件中,我们可以找到对它的定义: 

#ifndef _CLOCK_T_DEFINED  
typedef long clock_t;  
#define _CLOCK_T_DEFINED  
#endif 

很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下: 

#define CLOCKS_PER_SEC((clock_t)1000) 

可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间.

Difftime()函数虽然返回的以秒计算的时间间隔是double类型的,但这并不说明该时间具有同double一样的精确度,这是由它的参数觉得的(time_t是以秒为单位计算的)。

7.tm结构时间转化为日历时间 :

可以使用mktime()函数将用tm结构表示的时间转化为日历时间。其函数原型如下: 

time_tmktime(struct tm * timeptr); 

其返回值就是转化后的日历时间。这样我们就可以先制定一个分解时间,然后对这个时间进行操作了.

8. Windows API:

系统还提供标准的Windows API 函数供使用;来获取和设置系统日期时间,函数原型为:

void  WINAPI  GetLocalTime(LPSYSTEMTIME lpSystemTime);

BOOL WINAPI  SetLocalTime(constSYSTEMTIME* lpSystemTime);

void  WINAPI  GetSystemTime(LPSYSTEMTIME lpSystemTime);

BOOL WINAPI  SetSystemTime(constSYSTEMTIME* lpSystemTime);

GetLocalTime()返回的是本地系统的时间,在不同的机器中会有不同的结果,这和你在控制面板中的时区设置有关. 该函数是获取的系统当前所属时区的时间, 比如说, 在北京时区, 那么获取的该时间的时间。而GetSystemTime()返回的是格林尼治时间(UTC), 是全球标准时间。SYSTEMTIME结果和TM结构很像,详情请参考MSDN.

9.注意事项:

(1)time.h中提供的各类函数中,每类函数中有几种形式,支持不同的系统设置,如单字节字符集合\多字节字符集(_w)、32位的\64位的,还有就是_s结尾的,表示比较安全的函数,推荐使用哦。不要被他们吓到了哈。

(2)若仅仅是想得到当前的日期和时间,推荐使用_strdate()和_strtime()函数,快捷方便,并直接返回你要的结果,不如意的就是格式是固定的,但格式是比较的通用的,也可以接受。

10.实例演示:

BOOL CGetDateTimeDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    // 关于...菜单项添加到系统菜单中。

    // IDM_ABOUTBOX 必须在系统命令范围内。

    ASSERT((IDM_ABOUTBOX& 0xFFF0) ==IDM_ABOUTBOX);

    ASSERT(IDM_ABOUTBOX< 0xF000);


    CMenupSysMenuGetSystemMenu(FALSE);

    if (pSysMenu !=NULL)

    {

       BOOL bNameValid;

       CString strAboutMenu;

       bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);

       ASSERT(bNameValid);

       if (!strAboutMenu.IsEmpty())

       {

           pSysMenu->AppendMenu(MF_SEPARATOR);

          pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);

       }

    }

    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

    //  执行此操作

    SetIcon(m_hIcon,TRUE);        //设置大图标

    SetIcon(m_hIcon,FALSE);   //设置小图标

    // TODO: 在此添加额外的初始化代码

    m_stMail.SetURL("cbnotes@sina.com");

    m_stWeb.SetURL("http://blog.csdn.net/cbnotes");

    //先得到日历时间:此时距离-01-01 00:00:00经历的秒数

   //time_t ltime;

    m_nEdit1 = time(NULL);//或者time(&m_nEdit1)

    //将日历时间转化为标准的日期和时间格式及tm结构体形式

    tm *gm,*local;

    gm = gmtime(&m_nEdit1); //得到UTC(世界标准时间或格林尼治时间)建议使用gmtime_s(&gm,&m_nEdit1);比较安全

    m_szEdit2.Format("%d/%02d/%02d %02d:%02d:%02d第%d天星期%d (%d)",gm->tm_year+1900,gm->tm_mon+1,gm->tm_mday,gm->tm_hour,gm->tm_min,gm->tm_sec,gm->tm_yday,gm->tm_wday,gm->tm_isdst);

    local = localtime(&m_nEdit1);//得到本地时间,中国时间比UTC时间晚小时

    m_szEdit3.Format("%d/%02d/%02d %02d:%02d:%02d第%d天星期%d (%d)",local->tm_year+1900,local->tm_mon+1,local->tm_mday,local->tm_hour,local->tm_min,local->tm_sec,local->tm_yday,local->tm_wday,local->tm_isdst);

    //返回固定的时间格式:

    char *buf =NULL;

   //buf = asctime(gm);//注意使用时结果将出错,原因大概就是没有使用安全函数gmtime_s吧,值被改变了

    buf = asctime(gmtime(&m_nEdit1));//返回tm格式的固定格式:返回UTC时间

    //buf = asctime(localtime(&m_nEdit1));//返回本地时间

    //buf = ctime(&m_nEdit1);  //返回日历时间的固定格式

    m_szEdit4.Format("%s",buf);

    //固定格式:_strdate()格式为:mm/dd/yy  _strtime()格式为:hh:mm:ss

    char tempBuf1[9], tempBuf2[9];

    m_szEdit5.Format("%s %s",_strdate(tempBuf1),_strtime(tempBuf2));

    //自定义时间格式:推荐使用:%x(日期) %X(时间)  %c(本地日期时间)%#c(Tuesday, March 14, 1995, 12:41:29) %#x(Tuesday, March 14, 1995) %a(星期简写) %b(月份简写)

    char tmpbuf[128];

    strftime(tmpbuf,128,"%Y年%m月%d日第%W周星期%w 第%j天",localtime(&m_nEdit1));

    m_szEdit6.Format("%s",tmpbuf);

    strftime(tmpbuf,128,"%Y-%m-%d %a %I:%M:%S %p",localtime(&m_nEdit1));

    m_szEdit7.Format("%s",tmpbuf);

    strftime(tmpbuf,128,"%#c",localtime(&m_nEdit1));

    m_szEdit8.Format("%s",tmpbuf);

   //计算持续时间的长度

  // clock();//精确到毫秒级:该函数返回值是硬件滴答数,要换算成秒或者毫秒,需要除以CLK_TCK或者CLK_TCK CLOCKS_PER_SEC

   //difftime()//只能精确到秒

    //分解时间转化为日历时间

    //将时间tm转换为日历时间

    //计算-04-12是星期几?

    tm t;

    t.tm_year =1989 - 1900;

    t.tm_mon = 3;

    t.tm_mday = 12;

   t.tm_hour= 0;

    t.tm_min = 0;

    t.tm_sec = 1;

    t.tm_isdst = 0;

    time_t t_of_daymktime(&t); 

    m_szEdit12.Format("%s",ctime(&t_of_day));

    //mktime();//将本地时间转换为日历时间

    //_mkgmtime();//将UTC时间转换为UTC的日历时间

    //The Win32 API GetLocalTime and SetLocalTime should beused instead

    SYSTEMTIME systm;

    GetLocalTime(&systm);//能得到毫秒级

    m_szEdit13.Format("%d年%02d月%02d日星期%d:%02d:%02d:%02d:%d",systm.wYear,systm.wMonth,systm.wDay,systm.wDayOfWeek,systm.wHour,systm.wMinute,systm.wSecond,systm.wMilliseconds);

    GetSystemTime(&systm);//能得到毫秒级

    m_szEdit11.Format("%d年%02d月%02d日星期%d:%02d:%02d:%02d:%d",systm.wYear,systm.wMonth,systm.wDay,systm.wDayOfWeek,systm.wHour,systm.wMinute,systm.wSecond,systm.wMilliseconds);

    //SetLocalTime();//修改本地的时间就不演示了。就是先设置systm值,再调用该函数。

    UpdateData(FALSE);

    return TRUE;  // 除非将焦点设置到控件,否则返回TRUE

}

//计时计算

void CGetDateTimeDlg::OnBnClickedButton1()

{

    // TODO: 在此添加控件通知处理程序代码

    CString szText;

   GetDlgItem(IDC_BUTTON1)->GetWindowText(szText);

    if (szText =="开始计时")

    {

       GetDlgItem(IDC_BUTTON1)->SetWindowText("停止计时");

       m_szEdit9 = "等待结束...";

       m_szEdit10 = "等待结束...";

       UpdateData(FALSE);

       m_start1 = clock();

       m_start2 = time(NULL);

    }

    else

    {

       m_end2 = time(NULL);

       m_end1 = clock();

       double result1 = (double)(m_end1 -m_start1)/CLOCKS_PER_SEC;

       double   result2 = difftime(m_end2,m_start2);

       m_szEdit9.Format("%d个滴答= %f秒",m_end1 -m_start1,result1);

       m_szEdit10.Format("%f秒",result2);

       UpdateData(FALSE);

       GetDlgItem(IDC_BUTTON1)->SetWindowText("开始计时");

    }

}

11.运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值