timehelper.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 313 行
CPP
313 行
// TimeHelper.cpp: implementation of the TimeHelper class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TimeHelper.h"
#include <locale.h>
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const double MINS2HOURS = 60;
double CTimeHelper::HOURS2DAYS = 8; // user definable
double CTimeHelper::DAYS2WEEKS = 5; // user definable
const double WEEKS2MONTHS = 4.348;
const double MONTHS2YEARS = 12;
const double FUDGE = 1e-6;
CMap<int, int, char, char&> CTimeHelper::MAPUNIT2CH; // user definable
double CTimeHelper::GetTime(double dTime, int nFromUnits, int nToUnits)
{
if (nFromUnits == nToUnits)
return dTime;
else if (Compare(nFromUnits, nToUnits) > 0)
{
while (Compare(nFromUnits, nToUnits) > 0)
{
switch (nFromUnits)
{
case THU_HOURS:
dTime *= MINS2HOURS;
nFromUnits = THU_MINS;
break;
case THU_DAYS:
dTime *= HOURS2DAYS;
nFromUnits = THU_HOURS;
break;
case THU_WEEKS:
dTime *= DAYS2WEEKS;
nFromUnits = THU_DAYS;
break;
case THU_MONTHS:
dTime *= WEEKS2MONTHS;
nFromUnits = THU_WEEKS;
break;
case THU_YEARS:
dTime *= MONTHS2YEARS;
nFromUnits = THU_MONTHS;
break;
}
}
}
else // nFromUnits < nToUnits
{
while (Compare(nFromUnits, nToUnits) < 0)
{
switch (nFromUnits)
{
case THU_MINS:
dTime /= MINS2HOURS;
nFromUnits = THU_HOURS;
break;
case THU_HOURS:
dTime /= HOURS2DAYS;
nFromUnits = THU_DAYS;
break;
case THU_DAYS:
dTime /= DAYS2WEEKS;
nFromUnits = THU_WEEKS;
break;
case THU_WEEKS:
dTime /= WEEKS2MONTHS;
nFromUnits = THU_MONTHS;
break;
case THU_MONTHS:
dTime /= MONTHS2YEARS;
nFromUnits = THU_YEARS;
break;
}
}
}
return dTime;
}
CString CTimeHelper::FormatTime(double dTime, int nDecPlaces)
{
return FormatTime(dTime, 0, nDecPlaces);
}
CString CTimeHelper::FormatTime(double dTime, int nUnits, int nDecPlaces)
{
// handle locale specific decimal separator
setlocale(LC_NUMERIC, "");
CString sTime;
char cUnits;
if (nUnits && MAPUNIT2CH.Lookup(nUnits, cUnits))
sTime.Format("%.*f %c", nDecPlaces, dTime, cUnits);
else
sTime.Format("%.*f", nDecPlaces, dTime);
// restore decimal separator to '.'
setlocale(LC_NUMERIC, "English");
return sTime;
}
void CTimeHelper::SetUnits(int nUnits, char cUnits)
{
MAPUNIT2CH[nUnits] = cUnits;
}
void CTimeHelper::SetUnits(int nUnits, LPCTSTR szUnits)
{
if (szUnits && *szUnits)
SetUnits(nUnits, szUnits[0]);
}
char CTimeHelper::GetUnits(int nUnits)
{
char cUnits = 0;
MAPUNIT2CH.Lookup(nUnits, cUnits);
return cUnits;
}
CString CTimeHelper::FormatTimeHMS(double dTime, int nUnitsFrom, BOOL bDecPlaces)
{
// convert the time to minutes
double dMins = GetTime(dTime, nUnitsFrom, THU_MINS);
// and all the others up to years
double dHours = dMins / MINS2HOURS;
double dDays = dHours / HOURS2DAYS;
double dWeeks = dDays / DAYS2WEEKS;
double dMonths = dWeeks / WEEKS2MONTHS;
double dYears = dMonths / MONTHS2YEARS;
CString sTime;
if (dYears >= 1.0)
sTime = FormatTimeHMS(dYears, THU_YEARS, THU_MONTHS, MONTHS2YEARS, bDecPlaces);
else if (dMonths >= 1.0)
sTime = FormatTimeHMS(dMonths, THU_MONTHS, THU_WEEKS, WEEKS2MONTHS, bDecPlaces);
else if (dWeeks >= 1.0)
sTime = FormatTimeHMS(dWeeks, THU_WEEKS, THU_DAYS, DAYS2WEEKS, bDecPlaces);
else if (dDays >= 1.0)
sTime = FormatTimeHMS(dDays, THU_DAYS, THU_HOURS, HOURS2DAYS, bDecPlaces);
else if (dHours >= 1.0)
sTime = FormatTimeHMS(dHours, THU_HOURS, THU_MINS, MINS2HOURS, bDecPlaces);
else if (dMins >= 1.0)
sTime = FormatTimeHMS(dMins, THU_MINS, THU_MINS, 0, FALSE);
sTime.MakeLower();
return sTime;
}
CString CTimeHelper::FormatTimeHMS(double dTime, int nUnits, int nLeftOverUnits,
double dLeftOverMultiplier, BOOL bDecPlaces)
{
CString sTime;
if (bDecPlaces)
{
double dLeftOver = (dTime - (int)dTime) * dLeftOverMultiplier + FUDGE;
sTime.Format("%d%c%d%c", (int)dTime, GetUnits(nUnits),
(int)dLeftOver, GetUnits(nLeftOverUnits));
}
else
sTime.Format("%d%c", (int)(dTime + 0.5), GetUnits(nUnits));
return sTime;
}
/*
CString CTimeHelper::FormatTimeHMS(double dTime, int nUnitsFrom, BOOL bDecPlaces)
{
// convert the time to minutes
double dMins = GetTime(dTime, nUnitsFrom, THU_MINS);
// and all the others up to years
double dHours = dMins / MINS2HOURS;
double dDays = dHours / HOURS2DAYS;
double dWeeks = dDays / DAYS2WEEKS;
double dMonths = dWeeks / WEEKS2MONTHS;
double dYears = dMonths / MONTHS2YEARS;
CString sTime;
if (dYears >= 1.0)
{
dMonths = (dYears - (int)dYears) * MONTHS2YEARS + FUDGE;
sTime.Format("%d%c%d%c", (int)dYears, GetUnits(THU_YEARS),
(int)dMonths, GetUnits(THU_MONTHS));
}
else if (dMonths >= 1.0)
{
dWeeks = (dMonths - (int)dMonths) * WEEKS2MONTHS + FUDGE;
sTime.Format("%d%c%d%c", (int)dMonths, GetUnits(THU_MONTHS),
(int)dWeeks, GetUnits(THU_WEEKS));
}
else if (dWeeks >= 1.0)
{
dDays = (dWeeks - (int)dWeeks) * DAYS2WEEKS + FUDGE;
sTime.Format("%d%c%d%c", (int)dWeeks, GetUnits(THU_WEEKS),
(int)dDays, GetUnits(THU_DAYS));
}
else if (dDays >= 1.0)
{
dHours = (dDays - (int)dDays) * HOURS2DAYS + FUDGE;
sTime.Format("%d%c%d%c", (int)dDays, GetUnits(THU_DAYS),
(int)dHours, GetUnits(THU_HOURS));
}
else if (dHours >= 1.0)
{
dMins = (dHours - (int)dHours) * MINS2HOURS + FUDGE;
sTime.Format("%d%c%d%c", (int)dHours, GetUnits(THU_HOURS),
(int)dMins, GetUnits(THU_MINS));
}
else if (dMins >= 1.0)
{
sTime.Format("%d%c", (int)dMins, GetUnits(THU_MINS));
}
sTime.MakeLower();
return sTime;
}
*/
int CTimeHelper::Compare(int nFromUnits, int nToUnits)
{
if (nFromUnits == nToUnits)
return 0;
switch (nFromUnits)
{
case THU_MINS:
return -1; // less than everything else
case THU_HOURS:
return (nToUnits == THU_MINS) ? 1 : -1;
case THU_DAYS:
return (nToUnits == THU_HOURS || nToUnits == THU_MINS) ? 1 : -1;
case THU_WEEKS:
return (nToUnits == THU_YEARS || nToUnits == THU_MONTHS) ? -1 : 1;
case THU_MONTHS:
return (nToUnits == THU_YEARS) ? -1 : 1;
case THU_YEARS:
return 1; // greater than everything else
}
// else
return 0;
}
BOOL CTimeHelper::SetHoursInOneDay(double dHours)
{
if (dHours <= 0 || dHours > 24)
return FALSE;
HOURS2DAYS = dHours;
return TRUE;
}
BOOL CTimeHelper::SetDaysInOneWeek(double dDays)
{
if (dDays <= 0 || dDays > 7)
return FALSE;
DAYS2WEEKS = dDays;
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?