📄 cdate.cpp
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// NRDB Pro is part of the Natural Resources Database Project
//
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
//
#include "stdafx.h"
#include "nrdb.h"
#include <math.h>
#include <strstrea.h>
#include "cdate.h"
///////////////////////////////////////////////////////////////////////////////
//
// Static variable declarations
//
// Declare the number of days in each month, also the date values for
// specific decades as an optimisation
//
const int CDateTime::m_anMonthLen[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
const int CDateTime::m_anMonthJul[] = {0,0,31,59,90,120,151,181,212,243,273,304,334};
CString CDateTime::m_sMonth;
///////////////////////////////////////////////////////////////////////////////
inline int CDateTime::DaysInYear(int nYear) {return IsLeapYear(nYear) ? 366 : 365;}
inline int CDateTime::LeapDays(int nYear) {return nYear/4 - nYear/100 + nYear/400;}
inline BOOL CDateTime::IsLeapYear(int nYear)
{
return !(nYear % 4) && ((nYear % 100) || (!(nYear % 400)));
};
///////////////////////////////////////////////////////////////////////////////
void CDateTime::JulAsDate(int nYear, int nJul, int &nMonth, int &nDay)
{
for (int i = 1; i <= 12; i++)
{
if (nJul > GetDaysMonth(i, nYear))
{
nJul -= GetDaysMonth(i, nYear);
} else
{
nMonth = i;
nDay = nJul;
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// int GetJulDay(int nYear, nMonth, nDay)
//
int CDateTime::GetJulDay(int nYear, int nMonth, int nDay)
{
int nJDay = nDay + m_anMonthJul[nMonth];
if (nMonth > 2 && IsLeapYear(nYear))
{
nJDay++;
};
return nJDay;
};
///////////////////////////////////////////////////////////////////////////////
//
// Constructor for CDateTime
//
CDateTime::CDateTime(int nYear, int nMonth, int nDay,
int nHours, int nMinutes, int nSeconds)
{
DateAsLong(nYear,nMonth,nDay,&m_lDate);
TimeAsLong(nHours,nMinutes,nSeconds, &m_lTime);
ASSERT(IsValid());
}
///////////////////////////////////////////////////////////////////////////////
//
// CDateTime::CDateTime()
//
// Constructor for CDateTime
//
CDateTime::CDateTime(long lDate, long lTime)
{
m_lDate = lDate;
m_lTime = lTime;
ASSERT(IsValid() || (m_lDate == 0 && m_lTime == 0));
}
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::DateAsString(CString&)
//
// Copies the date in the format DD/MM/YYYY to the given string
//
BOOL CDateTime::DateAsString(CString& strDate)
{
int nDay, nMonth, nYear;
CString sMonth;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
if (IsDateValid(nYear, nMonth, nDay))
{
if (nMonth == 0 && nDay == 0)
{
strDate.Format("%d",nYear);
}
else
{
sMonth.LoadString(IDS_JAN+nMonth-1);
sMonth = sMonth.Left(3);
if (nDay == 0)
{
strDate.Format("%s %d",(LPCSTR)sMonth, nYear);
}
else
{
strDate.Format("%d %s %d",nDay, (LPCSTR)sMonth, nYear);
}
}
} else
{
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::TimeAsString(CString&)
//
// Copies the time in the format HH:MM to the given string
//
BOOL CDateTime::TimeAsString(CString& strTime)
{
BOOL bOK = TRUE;
// Null string indicated by -1
if (m_lTime == -1)
{
strTime = "";
return TRUE;
}
// Extract components of time
int nHour, nMinute, nSecond;
bOK = LongAsTime(m_lTime, &nHour, &nMinute, &nSecond);
// Write the text to the string
if (bOK)
{
strTime.Format("%02i:%02i",nHour, nMinute);
};
return bOK;
}
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::StringAsDate()
//
// Converts a string in the format DD-MMM-YYYY or MMM-YYYY or YYYY
// to a datetime structure
//
BOOL CDateTime::StringAsDate(CString sDate)
{
BOOL bOK = TRUE;
int nDay = 0, nMonth = 0, nYear = 0;
CString sMonth, sDay, sYear, s;
int nTmp;
sDate.TrimLeft();
sDate.TrimRight();
// First scan for Excel and dBase formats
if (sscanf(sDate,"%d-%d-%d %d:%d:%d", &nYear,&nMonth,&nDay,&nTmp,&nTmp,&nTmp) != 6 &&
(sscanf(sDate,"%d-%d-%d", &nYear,&nMonth,&nDay) != 3 || nYear < 100) &&
!ExcelYear(sDate, &nYear))
{
// Determine format of string
sDate.TrimLeft(" ");
sDate.TrimRight(" ");
int i = sDate.FindOneOf(".,-/ ");
for (int j = sDate.GetLength()-1; j >= 0 && CString(" -/").Find(sDate[j]) == -1; j--);
if (i == -1 && j == -1) sYear = sDate;
else if (i == j)
{
sMonth = sDate.Left(i);
sYear = sDate.Mid(i+1);
} else
{
sDay = sDate.Left(i);
sMonth = sDate.Mid(i+1, j-i-1);
sYear = sDate.Mid(j+1);
};
sDay.TrimLeft();
sDay.TrimRight();
sMonth.TrimLeft();
sMonth.TrimRight();
sYear.TrimLeft();
sYear.TrimRight();
// If the month is numeric and the day contains characters then swap
if (sMonth.FindOneOf("0123456789") != -1 && sDay.FindOneOf("0123456789") == -1)
{
s = sDay;
sDay = sMonth;
sMonth = s;
}
// Determine day
if (!sDay.IsEmpty())
{
bOK = sscanf(sDay, "%d", &nDay);
};
// Determine month
if (bOK && !sMonth.IsEmpty())
{
for (int i = 1; i <= 12 && nMonth == 0; i++)
{
s.LoadString(IDS_JAN+i-1);
if (strnicmp(sMonth, s, sMonth.GetLength())== 0 &&
sMonth.GetLength() >= 3)
{
nMonth = i;
};
};
if (nMonth == 0)
{
bOK = FALSE;
};
}
// Determine year
if (bOK)
{
bOK = sscanf(sYear,"%d", &nYear);
}
};
// Construct the new datetime if the values are valid
if (bOK && IsDateValid(nYear,nMonth,nDay))
{
DateAsLong(nYear,nMonth,nDay,&m_lDate);
m_lTime = 0;
} else
{
bOK = FALSE;
}
return bOK;
}
///////////////////////////////////////////////////////////////////////////////
//
// Check for dates of the form 1999.0 as imported from Excel
//
BOOL CDateTime::ExcelYear(LPCSTR psDate, int* pnYear)
{
*pnYear = 0;
// Skip space
while (isspace(*psDate)) pnYear++;
// Create number
while (isdigit(*psDate))
{
*pnYear = *pnYear*10 + *psDate-'0';;
psDate++;
}
// Ensure that the last two digits are .0
if (psDate[0] != '.' || psDate[1] != '0') return FALSE;
return IsDateValid(*pnYear,0,0);
}
///////////////////////////////////////////////////////////////////////////////
//
// Converts a string in the format DD-MM-YYYY or DD MMM YYYY
// to a datetime structure
//
BOOL CDateTime::StringAsDateTime(LPCSTR sDate, LPCSTR sTime)
{
return StringAsDate(sDate) &&
StringAsTime(sTime);
};
///////////////////////////////////////////////////////////////////////////////
//
// CDateTime& CDateTime::operator=(const CDateTime& rSrcDateTime)
//
// Assignment operator
//
CDateTime& CDateTime::operator=(const CDateTime& rSrcDateTime)
{
//ASSERT(rSrcDateTime.IsValid());
m_lDate = rSrcDateTime.m_lDate;
m_lTime = rSrcDateTime.m_lTime;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
//
// CDateTime& CDateTime::Advance()
//
// Advance the date for the number of days (or fraction there of) provided
//
CDateTime& CDateTime::Advance(long lDays, long lSecs)
{
ASSERT(IsValid());
DateAddDays(&m_lDate, lDays);
m_lTime += lSecs;
if (m_lTime >= 86400)
{
DateAddDays(&m_lDate, m_lTime / 86400);
m_lTime -= (m_lTime / 86400) * 86400;
}
else if (m_lTime < 0)
{
long lDays = ((m_lTime+1) / 86400)-1;
DateAddDays(&m_lDate, lDays);
m_lTime -= lDays * 86400;
};
return *this;
}
///////////////////////////////////////////////////////////////////////////////
//
// Access functions
//
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetYear()
//
int CDateTime::GetYear()
{
int nDay, nMonth, nYear;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
return nYear;
}
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetMonth()
//
int CDateTime::GetMonth()
{
int nDay, nMonth, nYear;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
return nMonth;
}
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetDay()
//
int CDateTime::GetDay()
{
int nDay, nMonth, nYear;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
return nDay;
}
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetHour()
//
int CDateTime::GetHour()
{
int nHour, nMinute, nSecond;
LongAsTime(m_lTime,&nHour,&nMinute,&nSecond);
return nHour;
}
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetMinute()
//
int CDateTime::GetMinute()
{
int nHour, nMinute, nSecond;
LongAsTime(m_lTime,&nHour,&nMinute,&nSecond);
return nMinute;
}
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::GetSecond()
//
int CDateTime::GetSecond()
{
int nHour, nMinute, nSecond;
LongAsTime(m_lTime,&nHour,&nMinute,&nSecond);
return nSecond;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::IsTimeValid(CString&)
//
// Determines if a time, in string format is valid e.g. 15:30:12
// returns true if it is. Will also allow the seconds value to be missed
// in which case this would default to zero
//
BOOL CDateTime::IsTimeValid(const CString& strTime)
{
UINT nHour, nMinute, nSecond = 0;
BOOL bValid = TRUE;
// Extract values from the string
if (sscanf(strTime,"%u%*c%u%*c%u",&nHour, &nMinute, &nSecond) < 2)
{
bValid = FALSE;
}
if (bValid && IsTimeValid(nHour,nMinute,nSecond) == FALSE)
{
bValid = FALSE;
}
return bValid;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -