⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datetimeformat.cpp

📁 基于WINDOWS mobile 的用于创建一个窗体和自定义试图的工程
💻 CPP
字号:
// DateTimeFormat.cpp: implementation of the CDateTimeFormat class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NumericFormat.h"
#include "DateTimeFormat.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// Verifies will fail if the needed buffer size is too large
#define MAX_TIME_BUFFER_SIZE    128         // matches that in timecore.cpp
#define MIN_DATE                (-657434L)  // about year 100
#define MAX_DATE                2958465L    // about year 9999

// Half a second, expressed in days
#define HALF_SECOND  (1.0/172800.0)


BOOL	CDateTimeFormat::m_bStaticInit = FALSE;

CString	CDateTimeFormat::m_strMonAbbr	[13],
		CDateTimeFormat::m_strMonFull	[13],
		CDateTimeFormat::m_strDayAbbr	[7],
		CDateTimeFormat::m_strDayFull	[7],
		CDateTimeFormat::m_strAMPM		[2];
int		CDateTimeFormat::m_nMonthDays	[13] =
		{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CDateTimeFormat::CDateTimeFormat()
{
	ClearCounters();
	m_szRes[0] = 0;
	m_pszBuf = m_szRes;

	if(!m_bStaticInit)
		StaticInit();
}


CDateTimeFormat::~CDateTimeFormat()
{

}


// CDateTimeFormat::StaticInit
//
//		Initializes the static variables once
//
void CDateTimeFormat::StaticInit()
{
	TCHAR	szFmt[128];
	int		i;
	LCTYPE	lcDayAbbr[] = {	LOCALE_SABBREVDAYNAME7,		// Sunday
							LOCALE_SABBREVDAYNAME1,		// Monday
							LOCALE_SABBREVDAYNAME2,		// Tuesday
							LOCALE_SABBREVDAYNAME3,		// Wednesday
							LOCALE_SABBREVDAYNAME4,		// Thursday
							LOCALE_SABBREVDAYNAME5,		// Friday
							LOCALE_SABBREVDAYNAME6 };	// Saturday
	LCTYPE	lcDayFull[] = {	LOCALE_SDAYNAME7,
							LOCALE_SDAYNAME1,
							LOCALE_SDAYNAME2,
							LOCALE_SDAYNAME3,
							LOCALE_SDAYNAME4,
							LOCALE_SDAYNAME5,
							LOCALE_SDAYNAME6 };
	LCTYPE	lcMonAbbr[] = {	LOCALE_SABBREVMONTHNAME1,
							LOCALE_SABBREVMONTHNAME2,
							LOCALE_SABBREVMONTHNAME3,
							LOCALE_SABBREVMONTHNAME4,
							LOCALE_SABBREVMONTHNAME5,
							LOCALE_SABBREVMONTHNAME6,
							LOCALE_SABBREVMONTHNAME7,
							LOCALE_SABBREVMONTHNAME8,
							LOCALE_SABBREVMONTHNAME9,
							LOCALE_SABBREVMONTHNAME10,
							LOCALE_SABBREVMONTHNAME11,
							LOCALE_SABBREVMONTHNAME12,
							LOCALE_SABBREVMONTHNAME13	};
	LCTYPE	lcMonFull[] = {	LOCALE_SMONTHNAME1,
							LOCALE_SMONTHNAME2,
							LOCALE_SMONTHNAME3,
							LOCALE_SMONTHNAME4,
							LOCALE_SMONTHNAME5,
							LOCALE_SMONTHNAME6,
							LOCALE_SMONTHNAME7,
							LOCALE_SMONTHNAME8,
							LOCALE_SMONTHNAME9,
							LOCALE_SMONTHNAME10,
							LOCALE_SMONTHNAME11,
							LOCALE_SMONTHNAME12,
							LOCALE_SMONTHNAME13	};

	//
	// Initialize the day names
	//
	for(i = 0; i < 7; ++i)
	{
		GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, lcDayAbbr[i], szFmt, 127);
		m_strDayAbbr[i] = szFmt;

		GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, lcDayFull[i], szFmt, 127);
		m_strDayFull[i] = szFmt;
	}

	//
	// Initialize the month names
	//
	for(i = 0; i < 13; i++)
	{
		GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, lcMonAbbr[i], szFmt, 127);
		m_strMonAbbr[i] = szFmt;

		GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, lcMonFull[i], szFmt, 127);
		m_strMonFull[i] = szFmt;
	}

	//
	// Initialize the AM/PM inidcators
	//
	GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_S1159, szFmt, 127);
	m_strAMPM[0] = szFmt;

	GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_S2359, szFmt, 127);
	m_strAMPM[1] = szFmt;

	m_bStaticInit = TRUE;
}


// CDateTimeFormat::ClearCounters
//
//		Clears all the scanner's counters
//
void CDateTimeFormat::ClearCounters()
{
	m_nd =
	m_nM =
	m_ny =
	m_nw =
	m_nq =
	m_ng =
	m_nh =
	m_nH =
	m_nm =
	m_ns =
	m_nt = 0;
}


// CDateTimeFormat::SetDateTime
//
//		Sets the date and time values
//		This code was adapted from Microsoft's
//
BOOL CDateTimeFormat::SetDateTime(const COleDateTime &odt)
{

	long nDays;             // Number of days since Dec. 30, 1899
	long nDaysAbsolute;     // Number of days since 1/1/0
	long nSecsInDay;        // Time in seconds since midnight
	long nMinutesInDay;     // Minutes in day

	long n400Years;         // Number of 400 year increments since 1/1/0
	long n400Century;       // Century within 400 year block (0,1,2 or 3)
	long n4Years;           // Number of 4 year increments since 1/1/0
	long n4Day;             // Day within 4 year block
							//  (0 is 1/1/yr1, 1460 is 12/31/yr4)
	long n4Yr;              // Year within 4 year block (0,1,2 or 3)
	BOOL bLeap4 = TRUE;     // TRUE if 4 year block includes leap year

	double dblDate = odt.m_dt; // tempory serial date

/*
	m_nYear		= odt.GetYear();
	m_nMonth	= odt.GetMonth();
	m_nDay		= odt.GetDay();
	m_nHour		= odt.GetHour();
	m_nMinute	= odt.GetMinute();
	m_nSecond	= odt.GetSecond();
*/

	//
	// The legal range does not actually span year 0 to 9999.
	//
	if(odt.m_dt > MAX_DATE || odt.m_dt < MIN_DATE) // about year 100 to about 9999
		return FALSE;

	//
	// If a valid date, then this conversion should not overflow
	//
	nDays = (long)dblDate;

	//
	// Round to the second
	//
	dblDate += ((odt.m_dt > 0.0) ? HALF_SECOND : -HALF_SECOND);

	nDaysAbsolute = (long)dblDate + 693959L; // Add days from 1/1/0 to 12/30/1899

	dblDate		= fabs(dblDate);
	nSecsInDay	= (long)((dblDate - floor(dblDate)) * 86400.);

	//
	// Calculate the day of week (sun=1, mon=2...)
	//   -1 because 1/1/0 is Sat.  +1 because we want 1-based
	//
	m_nDayOfWeek = (int)((nDaysAbsolute - 1) % 7L) + 1;

	//
	// Leap years every 4 yrs except centuries not multiples of 400.
	//
	n400Years = (long)(nDaysAbsolute / 146097L);

	//
	// Set nDaysAbsolute to day within 400-year block
	//
	nDaysAbsolute %= 146097L;

	//
	// -1 because first century has extra day
	//
	n400Century = (long)((nDaysAbsolute - 1) / 36524L);

	//
	// Non-leap century
	//
	if (n400Century != 0)
	{
		// Set nDaysAbsolute to day within century
		nDaysAbsolute = (nDaysAbsolute - 1) % 36524L;

		//
		// +1 because 1st 4 year increment has 1460 days
		//
		n4Years = (long)((nDaysAbsolute + 1) / 1461L);

		if(n4Years != 0)
			n4Day = (long)((nDaysAbsolute + 1) % 1461L);
		else
		{
			bLeap4 = FALSE;
			n4Day = (long)nDaysAbsolute;
		}
	}
	else
	{
		//
		// Leap century - not special case!
		//
		n4Years	= (long)(nDaysAbsolute / 1461L);
		n4Day	= (long)(nDaysAbsolute % 1461L);
	}

	if(bLeap4)
	{
		//
		// -1 because first year has 366 days
		//
		n4Yr = (n4Day - 1) / 365;

		if(n4Yr != 0)
			n4Day = (n4Day - 1) % 365;
	}
	else
	{
		n4Yr = n4Day / 365;
		n4Day %= 365;
	}

	//
	// n4Day is now 0-based day of year. Save 1-based day of year, year number
	//
	m_nDayOfYear	= (int)n4Day + 1;
	m_nYear			= n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr;

	//
	// Handle leap year: before, on, and after Feb. 29.
	//
	if(n4Yr == 0 && bLeap4)
	{
		//
		// Leap Year
		//
		if(n4Day == 59)
		{
			/* Feb. 29 */
			m_nMonth	= 2;
			m_nDay		= 29;
			goto DoTime;
		}

		//
		// Pretend it's not a leap year for month/day comp.
		//
		if(n4Day >= 60)
			--n4Day;
	}

	//
	// Make n4DaY a 1-based day of non-leap year and compute
	//  month/day for everything but Feb. 29.
	//
	++n4Day;

	//
	// Month number always >= n/32, so save some loop time
	//
	for(m_nMonth = (n4Day >> 5) + 1;
		n4Day > m_nMonthDays[m_nMonth]; ++m_nMonth);

	m_nDay = (int)(n4Day - m_nMonthDays[m_nMonth-1]);

DoTime:
	if(nSecsInDay == 0)
		m_nHour = m_nMinute = m_nSecond = 0;
	else
	{
		m_nSecond		= (int)nSecsInDay % 60L;
		nMinutesInDay	= nSecsInDay / 60L;
		m_nMinute		= (int)nMinutesInDay % 60;
		m_nHour			= (int)nMinutesInDay / 60;
	}

	return TRUE;
}


// CDateTimeFormat::SetDateTime
//
//		Sets the date and time values
//
void CDateTimeFormat::SetDateTime(const CTime &t)
{
	m_nYear		= t.GetYear();
	m_nMonth	= t.GetMonth();
	m_nDay		= t.GetDay();
	m_nHour		= t.GetHour();
	m_nMinute	= t.GetMinute();
	m_nSecond	= t.GetSecond();
}

#ifdef __oledb_h__

// CDateTimeFormat::SetDateTime
//
//		Sets the time from a DBTIMESTAMP pointer
//
void CDateTimeFormat::SetDateTime(const DBTIMESTAMP &DbTs)
{
	m_nYear		= DbTs.year;
	m_nMonth	= DbTs.month;
	m_nDay		= DbTs.day;
	m_nHour		= DbTs.hour;
	m_nMinute	= DbTs.minute;
	m_nSecond	= DbTs.second;
}

#endif


// CDateTimeFormat::GetDayOfYear
//
//		Returns the number of days in a year
//
int CDateTimeFormat::GetDayOfYear(int y, int m, int d)
{
	int		nDays[] = {31,28,31,30,31,30,31,31,30,31,30,31},
			nTot	= 0,
			i;

	//
	// Loop through all the previous months.
	// m_nMonth is in the 1-12 range
	//
	for(i = 0; i < m - 2; ++i)
		nTot += nDays[i];
	nTot += d;

	if(IsLeapYear(y))
		++nTot;

	return nTot;
}


// CDateTimeFormat::GetDayOfWeek
//
//		Calculate the day of week
//
int CDateTimeFormat::GetDayOfWeek(int y, int m, int d)
{
	int		nTot,
			y1		= y - 1;

	nTot = GetDayOfYear(y,m,d) + y1 + y1 / 4 - y1 / 100 + y1 / 400;
	return nTot % 7;
}


// CDateTimeFormat::FormatDay
//
//		Formats a day
//
void CDateTimeFormat::FormatDay()
{
	TCHAR	szFmt[8];
	int		n;

	switch(m_nd)
	{
	case 1:
		_tcscat(m_pszBuf, Format(m_nDay, szFmt, 8));
		break;

	case 2:
		_tcscat(m_pszBuf, Format(m_nDay, szFmt, 8, 2));
		break;

	case 3:
		n = GetDayOfWeek(m_nYear, m_nMonth, m_nDay);
		_tcscat(m_pszBuf, m_strDayAbbr[n]);
		break;

	case 4:
		n = GetDayOfWeek(m_nYear, m_nMonth, m_nDay);
		_tcscat(m_pszBuf, m_strDayFull[n]);
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	};
}


// CDateTimeFormat::FormatWeek
//
//		Formats a week number
//
void CDateTimeFormat::FormatWeek()
{
	TCHAR			szFmt[8];
	int				nDayOfYear	= GetDayOfYear(m_nYear, m_nMonth, m_nDay),
					nDoy1		= GetDayOfYear(m_nYear, 1, 1),
					nWeek;

	nWeek = (nDayOfYear + nDoy1) / 7 + 1;

	switch(m_nw)
	{
	case 1:
		_tcscat(m_pszBuf, Format(nWeek, szFmt, 8));
		break;

	case 2:
		_tcscat(m_pszBuf, Format(nWeek, szFmt, 8, 2));
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	}
}


// CDateTimeFormat::FormatMonth
//
//		Formats a month
//
void CDateTimeFormat::FormatMonth()
{
	TCHAR	szFmt[8];

	switch(m_nM)
	{
	case 1:
		_tcscat(m_pszBuf, Format(m_nMonth, szFmt, 8));
		break;

	case 2:
		_tcscat(m_pszBuf, Format(m_nMonth, szFmt, 8, 2));
		break;

	case 3:
		_tcscat(m_pszBuf, m_strMonAbbr[m_nMonth-1]);
		break;

	case 4:
		_tcscat(m_pszBuf, m_strMonFull[m_nMonth-1]);
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	}
}


// CDateTimeFormat::FormatQuarter
//
//		Formats a quarter number
//
void CDateTimeFormat::FormatQuarter()
{
	TCHAR	szFmt[8];

	switch(m_nq)
	{
	case 1:
		_tcscat(m_pszBuf, Format((m_nMonth - 1) / 3 + 1, szFmt, 8));
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	}
}


// CDateTimeFormat::FormatYear
//
//		Formats a year
//
void CDateTimeFormat::FormatYear()
{
	TCHAR	szFmt[8];

	switch(m_ny)
	{
	case 1:
		_tcscat(m_pszBuf, Format(m_nYear, szFmt, 8));
		break;

	case 2:
		_tcscat(m_pszBuf, Format(m_nYear % 100, szFmt, 8, 2));
		break;

	case 4:
		_tcscat(m_pszBuf, Format(m_nYear, szFmt, 8, 4));
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	};
}


// CDateTimeFormat::FormatHour
//
//		Formats an hour
//
void CDateTimeFormat::FormatHour()
{
	TCHAR	szFmt[8];
	int		nHour = m_nHour;
	int		nDig;

	//
	// Check if we are formatting for a 12-hour clock
	//
	if(m_nh)
	{
		if(nHour > 12)
			nHour -= 12;
		nDig = m_nh;
	}
	else
		nDig = m_nH;

	switch(nDig)
	{
	case 1:
		_tcscat(m_pszBuf, Format(nHour, szFmt, 8));
		break;

	case 2:
		_tcscat(m_pszBuf, Format(nHour, szFmt, 8, 2));
		break;

	default:
		_tcscat(m_pszBuf, _T("???"));
	}
}


// CDateTimeFormat::FormatAMPM
//
//		Inserts the AM / PM symbols
//
void CDateTimeFormat::FormatAMPM()
{
	if(m_nt > 0 && m_nt < 3)
		_tcscat(m_pszBuf, m_strAMPM[m_nHour < 12 ? 0 : 1]);
	else
		_tcscat(m_pszBuf, _T("???"));
}


// CDateTimeFormat::FormatSection
//
//		Come here whenever a section is ready to be formatted
//
void CDateTimeFormat::FormatSection()
{
	CString	str;

	if(m_nd)
	{
		FormatDay();
	}
	else if(m_nM)
	{
		FormatMonth();
	}
	else if(m_ny)
	{
		FormatYear();
	}
	else if(m_nq)
	{
		FormatQuarter();
	}
	else if(m_nw)
	{
		FormatWeek();
	}
	else if(m_ng)
	{
		// Not yet implemented
	}
	else if(m_nh || m_nH)
	{
		FormatHour();
	}
	else if(m_nm)
	{
		TCHAR	szFmt[8];
		_tcscat(m_pszBuf, Format(m_nMinute, szFmt, 8, m_nm == 1 ? 0 : 2));
	}
	else if(m_ns)
	{
		TCHAR	szFmt[8];
		_tcscat(m_pszBuf, Format(m_nSecond, szFmt, 8, m_ns == 1 ? 0 : 2));
	}
	else if(m_nt)
	{
		FormatAMPM();
	}
	else
		_tcscat(m_pszBuf, _T("???") );

	ClearCounters();
}


// CDateTimeFormat::SetFormat
//
//		Set and scan the format string
//		Generates the result string
//
void CDateTimeFormat::SetFormat(LPCTSTR pszFormat)
{
	LPCTSTR	p;
	TCHAR	c = 0;
	BOOL	fFmt = FALSE,			// Formatting
			fLit = FALSE;			// Literal characters
	TCHAR	szChar[2]	= {0, 0},
			szLit[128]	= {0};
	TCHAR*	pLit		= szLit;

	m_pszBuf[0] = 0;	// Clear the string the C way
	ClearCounters();	// Clear the internal counters

	for(p = pszFormat; *p; p++)
	{
		//
		// Scanning formats?
		//
		if(fFmt)
		{
			if(*p != c)				// Did the format char changed?
			{
				if(szLit[0])
				{
					*pLit = 0;
					wcscat(m_pszBuf, szLit);

					pLit = szLit;
					*pLit = 0;
				}

				FormatSection();	// So format the section,
				fFmt = FALSE;		// and say we are not formatting
			}
		}
		c = *p;

		//
		// What literal mode?
		//
		if(!fLit)
		{
			//
			// Not in literal mode
			//
			switch(c)
			{
			case _T('d'):	m_nd++; fFmt = TRUE; break;
			case _T('M'):	m_nM++; fFmt = TRUE; break;
			case _T('y'):	m_ny++; fFmt = TRUE; break;
			case _T('g'):	m_ng++; fFmt = TRUE; break;
			case _T('h'):	m_nh++; fFmt = TRUE; break;
			case _T('H'):	m_nH++; fFmt = TRUE; break;
			case _T('m'):	m_nm++; fFmt = TRUE; break;
			case _T('s'):	m_ns++; fFmt = TRUE; break;
			case _T('t'):	m_nt++; fFmt = TRUE; break;
			case _T('w'):	m_nw++; fFmt = TRUE; break;
			case _T('q'):	m_nq++; fFmt = TRUE; break;
			case _T('\''):	fLit = TRUE; break;
			default:
				*pLit++ = c;
				break;
			}
		}
		else
		{
			//
			// In literal mode
			//
			if(c == _T('\''))
			{
				fLit = FALSE;				// Terminate the literal mode
				*pLit = 0;					// Terminate the literal string
				wcscat(m_pszBuf, szLit);	// Append the literal string

				pLit = szLit;				// Reinitialize the literal string
				*pLit = 0;
			}
			else
				*pLit++ = c;				// Copy character to literal string
		}
	}

	//
	// Last check for a pending format
	//
	if(fFmt)
	{
		if(*szLit)
		{
			*pLit = 0;
			wcscat(m_pszBuf, szLit);
		}

		FormatSection();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -