类库: vc下如何按照当前系统的日期、时间格式显示时间

来源:互联网 发布:陕西水利预算软件 编辑:程序博客网 时间:2024/06/15 21:50

因为公司要统一所有产品的日期、时间显示格式,要求所有程序在显示日期时间的时候,都默认使用操作系统的时间格式。所以想着封装一个基础类供大家共用。

一开始打算使用EnumDateFormatsExEx和EnumTimeFormatsEx,在win7下开发的,结果同事拿到xp下之后发现直接异常了,然后一看msdn才发现这两个api只有vista之后的操作系统才支持。

所以要改用EnumDateFormatsEx和EnumTimeFormats,但是这两个api没有最后一个PARAM,在封装的时候无法把this传递进去,那么回调就只能把返回的数据存储在全局变量中,但是全局变量的话就无法实现线程安全,怎么办呢?

于是想到了之前看到的TLS,定义如下三个变量。

__declspec(thread)CString* _dateStr = NULL;__declspec(thread)CALID* _calendarID = NULL;__declspec(thread)CString* _timeStr = NULL;

回调直接把api返回的值存储到这三个TLS中,然后在类CDateFormatReader的构造函数中再去把他取出来,就ok了。

这样即时多个线程同时使用这个辅助类也没关系。


下面是示例代码:

示例代码如下:

voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetLongdateformat(){      COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;    strDate =currentTime.Format(CDateTimeFormatStringReader::GetLongDateFormat());    msg.Format(_T("format:%s, \nvalue: %s"),CDateTimeFormatStringReader::GetLongDateFormat(), strDate);    AfxMessageBox(msg);}  voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetLongtimeformat(){    COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;       strDate =currentTime.Format(CDateTimeFormatStringReader::GetLongTimeFormat());    msg.Format(_T("format:%s, \nvalue: %s"),CDateTimeFormatStringReader::GetLongTimeFormat(), strDate);    AfxMessageBox(msg);}  voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetLongdatetimeformat3(){    COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;    strDate =currentTime.Format(CDateTimeFormatStringReader::GetLongDateTimeFormat());    msg.Format(_T("format:%s, \nvalue: %s"),CDateTimeFormatStringReader::GetLongDateTimeFormat(), strDate);    AfxMessageBox(msg);}  voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetShortdateformat2(){    COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;    strDate =currentTime.Format(CDateTimeFormatStringReader::GetShortDateFormat());    msg.Format(_T("format:%s, \nvalue: %s"),CDateTimeFormatStringReader::GetShortDateFormat(), strDate);    AfxMessageBox(msg);}  voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetShorttimeformat2(){    COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;    strDate =currentTime.Format(CDateTimeFormatStringReader::GetShortTimeFormat());    msg.Format(_T("format:%s, \nvalue: %s"),CDateTimeFormatStringReader::GetShortTimeFormat(), strDate);    AfxMessageBox(msg);}  voidCTestGetSystemDateTimeFormatDlg::OnBnClickedBtnGetShortdatetimeformat4(){    COleDateTimecurrentTime =COleDateTime::GetCurrentTime();    CStringstrDate, msg;    strDate =currentTime.Format(CDateTimeFormatStringReader::GetShortDateTimeFormat());    msg.Format(_T("format:%s, \nvalue: %s"), CDateTimeFormatStringReader::GetShortDateTimeFormat(),strDate);    AfxMessageBox(msg);}


完整的封装类的代码如下:

DateTimeFormatStringReader.h

#pragma once/*** @class CLongDateTimeFormatStringReader* @brief 获取当前操作系统的日期、时间格式*/class CDateTimeFormatStringReader{private:/*** @class CDateFormatReader* @brief 日期格式读取器*/class CDateFormatReader{private:/** 获取到的时间格式 */CString m_dateFormat;/**  CalendarID*/CALID m_calendarID;/** 是否是短日期格式 */bool m_isShort;private:/** 用于配合api的回调 */static BOOL CALLBACK EnumDateFormatsProcEx(__in  LPTSTR lpDateFormatString,__in  CALID CalendarID);public:CDateFormatReader(bool isShort = false);public:CString GetOSDateFormat(){ return m_dateFormat;};CString GetDateFormat();CALID GetCalendarID(){ return m_calendarID;};};/*** @class CTimeFormatReader* @brief 获取系统时间格式*/class CTimeFormatReader{private:/** 获取到的时间字符串 */CString m_timeFormat;/** 是否为短时间格式 */bool m_isShort;private:static BOOL CALLBACK EnumTimeFormatsProc(__in  LPTSTR lpTimeFormatString);public:CTimeFormatReader(bool isShort = false);CString GetOSTimeFormat(){ return m_timeFormat;};CString GetTimeFormat();};public:static CString GetLongDateFormat();static CString GetLongTimeFormat();static CString GetLongDateTimeFormat();static CString GetShortDateFormat();static CString GetShortTimeFormat();static CString GetShortDateTimeFormat();/** 短期日、长时间格式,这是推荐的格式 */static CString GetShortDateLongTimeFormat();static CString GetShortDateLongTimeFormatWithMilliSecond();static CALID GetCalendarId();};


DateTimeFormatStringReader.cpp

#include "StdAfx.h"#include "DateTimeFormatStringReader.h"/*** 本来打算就使用几个文件内的局部变量来存放回调函数返回的只,* 但是这样的话就不是线程安全的了,所以改用线程局部变量来存储回调函数返回的值,这样就可以实现线程安全*/__declspec(thread)CString* _dateStr = NULL;__declspec(thread)CALID* _calendarID = NULL;__declspec(thread)CString* _timeStr = NULL;bool IsWindows7Later(){OSVERSIONINFO osvi;ZeroMemory(&osvi, sizeof(OSVERSIONINFO));osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);GetVersionEx(&osvi);TCHAR szVersion[10] = {0};CString strVersion;strVersion.Format(_T("%d.%d"), osvi.dwMajorVersion, osvi.dwMinorVersion);return strVersion.Compare(_T("6.1")) >= 0;}CDateTimeFormatStringReader::CDateFormatReader::CDateFormatReader( bool isShort ):m_isShort(isShort){m_dateFormat = "";m_calendarID = 0;DWORD dwFlags = DATE_LONGDATE;if(m_isShort)dwFlags = DATE_SHORTDATE;BOOL dwReturn = EnumDateFormatsEx(EnumDateFormatsProcEx, LOCALE_USER_DEFAULT, dwFlags);ASSERT(dwReturn);if(_dateStr != NULL){this->m_dateFormat = *_dateStr;delete _dateStr;_dateStr = NULL;}if(_calendarID != NULL){this->m_calendarID = *_calendarID;delete _calendarID;_calendarID = NULL;}}BOOL CALLBACK CDateTimeFormatStringReader::CDateFormatReader::EnumDateFormatsProcEx( __in LPTSTR lpDateFormatString, __in CALID calendarID){//把取过来的只存放在tls中,然后在后续的函数方法中去使用和释放//以便实现线程安全_dateStr = new CString(lpDateFormatString);_calendarID = new CALID(calendarID);return FALSE;}CString CDateTimeFormatStringReader::CDateFormatReader::GetDateFormat(){CString formatStr = GetOSDateFormat();formatStr.Replace(_T("'"), _T(""));if(formatStr.Find(_T("yyyy"))>=0)formatStr.Replace(_T("yyyy"), _T("%Y"));if(formatStr.Find(_T("yy"))>=0)formatStr.Replace(_T("yy"), _T("%y"));if(formatStr.Find(_T("MMMM"))>=0)formatStr.Replace(_T("MMMM"), _T("%B"));else if(formatStr.Find(_T("MMM"))>=0)formatStr.Replace(_T("MMM"), _T("%b"));else if(formatStr.Find(_T("MM"))>=0)formatStr.Replace(_T("MM"), _T("%m"));else if(formatStr.Find(_T("M"))>=0)formatStr.Replace(_T("M"), _T("%m"));if(formatStr.Find(_T("dddd"))>=0)formatStr.Replace(_T("dddd"), _T("%A"));if(formatStr.Find(_T("ddd"))>=0)formatStr.Replace(_T("ddd"), _T("%a"));if(formatStr.Find(_T("dd"))>=0)formatStr.Replace(_T("dd"), _T("%d"));else if(formatStr.Find(_T("d"))>=0)formatStr.Replace(_T("d"), _T("%d"));return formatStr;}//////////////////////////////////////////////////////////////////////////CDateTimeFormatStringReader::CTimeFormatReader::CTimeFormatReader(bool isShort):m_isShort(isShort){DWORD dwFlag = 0;bool isWin7OrLater = IsWindows7Later();if(isShort && isWin7OrLater)dwFlag |= TIME_NOSECONDS;BOOL dwReturn = EnumTimeFormats(EnumTimeFormatsProc, LOCALE_USER_DEFAULT, dwFlag);ASSERT(dwReturn);if(_timeStr != NULL){this->m_timeFormat = *_timeStr;if(isShort && !isWin7OrLater)m_timeFormat.Replace(_T(":ss"), _T(""));delete _timeStr;_timeStr = NULL;}}BOOL CALLBACK CDateTimeFormatStringReader::CTimeFormatReader::EnumTimeFormatsProc( __in LPTSTR lpTimeFormatString){//把取过来的只存放在tls中,然后在后续的函数方法中去使用和释放//以便实现线程安全_timeStr = new CString(lpTimeFormatString);return FALSE;}CString CDateTimeFormatStringReader::CTimeFormatReader::GetTimeFormat(){CString formatStr = GetOSTimeFormat();if(formatStr.Find(_T("HH"))>=0)formatStr.Replace(_T("HH"), _T("%H"));else if(formatStr.Find(_T("H"))>=0)formatStr.Replace(_T("H"), _T("%H"));if(formatStr.Find(_T("hh"))>=0)formatStr.Replace(_T("hh"), _T("%I"));else if(formatStr.Find(_T("h"))>=0)formatStr.Replace(_T("h"), _T("%I"));if(formatStr.Find(_T("mm"))>=0)formatStr.Replace(_T("mm"), _T("%M"));else if(formatStr.Find(_T("m"))>=0)formatStr.Replace(_T("m"), _T("%M"));if(formatStr.Find(_T("ss"))>=0)formatStr.Replace(_T("ss"), _T("%S"));else if(formatStr.Find(_T("s"))>=0)formatStr.Replace(_T("s"), _T("%S"));if(formatStr.Find(_T("tt"))>=0)formatStr.Replace(_T("tt"), _T("%p"));return formatStr;}//////////////////////////////////////////////////////////////////////////CString CDateTimeFormatStringReader::GetLongDateFormat(){CDateFormatReader dateFormatReader;return dateFormatReader.GetDateFormat();}CString CDateTimeFormatStringReader::GetLongTimeFormat(){CTimeFormatReader timeFormatReader;return timeFormatReader.GetTimeFormat();}CString CDateTimeFormatStringReader::GetLongDateTimeFormat(){CString result;result.Format(_T("%s %s"), GetLongDateFormat(), GetLongTimeFormat());return result;}CString CDateTimeFormatStringReader::GetShortDateFormat(){CDateFormatReader dateFormatReader(true);return dateFormatReader.GetDateFormat();}CString CDateTimeFormatStringReader::GetShortTimeFormat(){CTimeFormatReader timeFormatReader(true);return timeFormatReader.GetTimeFormat();}CString CDateTimeFormatStringReader::GetShortDateTimeFormat(){CString result;result.Format(_T("%s %s"), GetShortDateFormat(), GetShortTimeFormat());return result;}CALID CDateTimeFormatStringReader::GetCalendarId(){CDateFormatReader dateFormatReader(true);return dateFormatReader.GetCalendarID();}CString CDateTimeFormatStringReader::GetShortDateLongTimeFormat(){CString result;result.Format(_T("%s %s"), GetShortDateFormat(), GetLongTimeFormat());return result;}CString CDateTimeFormatStringReader::GetShortDateLongTimeFormatWithMilliSecond(){CString result;result.Format(_T("%s %s"), GetShortDateFormat(), GetLongTimeFormat());if(result.Find(_T("%S")) >= 0)result.Replace(_T("%S"), _T("%S.milliSecond"));return result;}


0 0