📄 cdatetime.cpp
字号:
/*
CDateTime.cpp
Classe base per data/ora (CRT).
Luca Piergentili, 24/11/99
lpiergentili@yahoo.com
http://www.geocities.com/lpiergentili/
*/
#include "env.h"
#include "pragma.h"
#include "macro.h"
#include "typedef.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "CDateTime.h"
static char* day_array[8] = {
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
"???"
};
static char* month_array[13] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
"???"
};
static int dayinmonth_array[13] = {
/*Jan*/31,
/*Feb*/28,
/*Mar*/31,
/*Apr*/30,
/*May*/31,
/*Jun*/30,
/*Jul*/31,
/*Aug*/31,
/*Sep*/30,
/*Oct*/31,
/*Nov*/30,
/*Dec*/31,
/*???*/0
};
/*
operator=(&)
Copia dell'oggetto (per referenza)
*/
CDateTime& CDateTime::operator=(const CDateTime& d)
{
Copy(this,&d);
return(*this);
}
/*
operator=(*)
Copia dell'oggetto (per puntatore)
*/
CDateTime& CDateTime::operator=(const CDateTime* d)
{
Copy(this,d);
return(*this);
}
/*
Copy()
Copia un oggetto sull'altro.
*/
void CDateTime::Copy(CDateTime* d1,const CDateTime* d2)
{
if(d1!=d2)
{
d1->m_Date.format = d2->m_Date.format;
strcpy(d1->m_Date.datestr,d2->m_Date.datestr);
d1->m_Date.dayofweek = d2->m_Date.dayofweek;
d1->m_Date.day = d2->m_Date.day;
d1->m_Date.month = d2->m_Date.month;
d1->m_Date.year = d2->m_Date.year;
strcpy(d1->m_Date.daystr,d2->m_Date.daystr);
strcpy(d1->m_Date.monthstr,d2->m_Date.monthstr);
strcpy(d1->m_Date.yearstr,d2->m_Date.yearstr);
d1->m_Time.format = d2->m_Time.format;
strcpy(d1->m_Time.timestr,d2->m_Time.timestr);
d1->m_Time.hour = d2->m_Time.hour;
d1->m_Time.min = d2->m_Time.min;
d1->m_Time.sec = d2->m_Time.sec;
strcpy(d1->m_Time.hourstr,d2->m_Time.hourstr);
strcpy(d1->m_Time.minstr,d2->m_Time.minstr);
strcpy(d1->m_Time.secstr,d2->m_Time.secstr);
}
}
/*
CDateTime()
Imposta le strutture interne con i parametri o ricavando data/ora di sistema.
*/
CDateTime::CDateTime(DATEFORMAT datefmt/*=UNKNOW_DATEFORMAT*/,TIMEFORMAT timefmt/*=UNKNOW_TIMEFORMAT*/,int dayofweek/*=-1*/,int day/*=-1*/,int month/*=-1*/,int year/*=-1*/,int hour/*=-1*/,int min/*=-1*/,int sec/*=-1*/)
{
// inizializzazione
Reset();
// imposta data/ora (se chiamato senza parametri ricava data/ora di sistema)
m_Date.format = (datefmt==UNKNOW_DATEFORMAT ? BRITISH : datefmt);
SetDate(dayofweek,day,month,year);
m_Time.format = (timefmt==UNKNOW_TIMEFORMAT ? HHMMSS : timefmt);
SetTime(hour,min,sec);
}
CDateTime::CDateTime(const char* date,DATEFORMAT datefmt)
{
// inizializzazione
Reset();
// imposta data/ora analizzando la stringa
LoadFromString(date,datefmt);
}
/*
Reset()
Azzera l'oggetto.
*/
void CDateTime::Reset(void)
{
// azzera le strutture interne
memset(&m_Date,'\0',sizeof(DATE));
m_Date.format = BRITISH;
memset(&m_Time,'\0',sizeof(TIME));
m_Time.format = HHMMSS;
}
/*
SetDate()
Imposta la struttura interna con i parametri o con la data di sistema.
*/
void CDateTime::SetDate(int dayofweek/*=-1*/,int day/*=-1*/,int month/*=-1*/,int year/*=-1*/)
{
// controlla i parametri
if(dayofweek < 0 || dayofweek > 6)
dayofweek = 0;
if(day <= 0 || day > 31)
day = -1;
if(month <= 0 || month > 12)
month = -1;
if(year <= 0)
year = -1;
// il giorno della settimana e' a base 0
m_Date.dayofweek = dayofweek;
// se chiamata senza parametri ricava la data di sistema
if(day==-1 || month==-1 || year==-1)
{
GetOsDate();
}
else
{
m_Date.day = day;
_snprintf(m_Date.daystr,sizeof(m_Date.daystr)-1,"%.2d",m_Date.day);
m_Date.month = month;
_snprintf(m_Date.monthstr,sizeof(m_Date.monthstr)-1,"%.2d",m_Date.month);
m_Date.year = year;
_snprintf(m_Date.yearstr,sizeof(m_Date.yearstr)-1,"%.4d",m_Date.year);
}
}
/*
GetDate()
Imposta i parametri con i valori della struttura interna.
*/
void CDateTime::GetDate(int& dayofweek,int& day,int& month,int& year)
{
dayofweek = m_Date.dayofweek;
day = m_Date.day;
month = m_Date.month;
year = m_Date.year;
}
/*
SetTime()
Imposta la struttura interna con i parametri o con l'ora di sistema.
*/
void CDateTime::SetTime(int hour/*=-1*/,int min/*=-1*/,int sec/*=-1*/)
{
// controlla i parametri
if(sec < 0 || sec > 60)
sec = -1;
if(min < 0 || min > 60)
min = -1;
if(hour < 0 || hour > 24)
hour = -1;
// se chiamata senza parametri ricava l'ora di sistema
if(sec==-1 || min==-1 || hour==-1)
{
GetOsTime();
}
else
{
m_Time.sec = sec;
_snprintf(m_Time.secstr,sizeof(m_Time.secstr)-1,"%.2d",m_Time.sec);
m_Time.min = min;
_snprintf(m_Time.minstr,sizeof(m_Time.minstr)-1,"%.2d",m_Time.min);
m_Time.hour = hour;
_snprintf(m_Time.hourstr,sizeof(m_Time.hourstr)-1,"%.2d",m_Time.hour);
}
}
/*
GetTime()
Imposta i parametri con i valori della struttura interna.
*/
void CDateTime::GetTime(int& hour,int& min,int& sec)
{
hour = m_Time.hour;
min = m_Time.min;
sec = m_Time.sec;
}
/*
Get12HourTime()
Restituisce il puntatore all'ora nel formato hh:mm:ss <AM|PM>.
Passando TRUE come parametro ricava l'ora di sistema (aggiornando la struttura interna), con FALSE si
limita a riformattare l'ora presente nella struttura interna.
*/
const char* CDateTime::Get12HourTime(BOOL getsystime/*=TRUE*/)
{
char ampm[]="AM\0";
memset(&(m_Time.timestr),'\0',sizeof(m_Time.timestr));
// ricava l'ora di sistema e la converte nell'ora locale
if(getsystime)
{
time_t time_value;
struct tm* local_time;
::time(&time_value);
local_time = localtime(&time_value);
if(local_time->tm_hour > 12)
{
memcpy(ampm,"PM",2);
local_time->tm_hour -= 12;
}
if(local_time->tm_hour==0)
local_time->tm_hour = 12;
_snprintf(m_Time.timestr,sizeof(m_Time.timestr)-1,"%.8s %s",asctime(local_time) + 11,ampm);
}
else
{
if(m_Time.hour > 12)
{
m_Time.hour -= 12;
memcpy(ampm,"PM",2);
}
_snprintf(m_Time.timestr,sizeof(m_Time.timestr)-1,"%.2d:%.2d:%.2d %s",m_Time.hour,m_Time.min,m_Time.sec,ampm);
}
return(m_Time.timestr);
}
/*
GetElapsedTime()
Restituisce una stringa nel formato [[nn hours, ]nn min., ]nn.nn secs. relativa al tempo trascorso.
Non considera ne modifica la struttura interna.
*/
const char* CDateTime::GetElapsedTime(float seconds)
{
static char szElapsedTime[MAX_DATE_STRING+1];
long lHour = 0L;
long lMin = 0L;
float fSecs = seconds;
memset(szElapsedTime,'\0',sizeof(szElapsedTime));
if(fSecs > 60.0f)
{
lMin = (long)fSecs / 60L;
fSecs = (float)fmod(fSecs,60.0f);
if(lMin > 60L)
{
lHour = lMin / 60L;
lMin = lMin % 60L;
}
}
if(lHour > 0L)
_snprintf(szElapsedTime,sizeof(szElapsedTime)-1,"%ld hours, %ld min., %0.2f secs.",lHour,lMin,fSecs);
else if(lMin > 0L)
_snprintf(szElapsedTime,sizeof(szElapsedTime)-1,"%ld min., %0.2f secs.",lMin,fSecs);
else if(fSecs >= 0.0f)
_snprintf(szElapsedTime,sizeof(szElapsedTime)-1,"%0.2f secs.",fSecs);
return(szElapsedTime);
}
/*
GetFormattedDate()
Restituisce il puntatore alla data formattata secondo il formato corrente.
Passando TRUE come parametro ricava la data di sistema (aggiornando la struttura interna), con FALSE si
limita a riformattare la data presente nella struttura interna.
*/
const char* CDateTime::GetFormattedDate(BOOL getsysdate/*=TRUE*/)
{
// ricava la data di sistema
if(getsysdate)
GetOsDate();
memset(&(m_Date.datestr),'\0',sizeof(m_Date.datestr));
// imposta a seconda del formato corrente
switch(m_Date.format)
{
// mm/dd/yyyy
case AMERICAN:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d/%.2d/%.4d",
m_Date.month,
m_Date.day,
m_Date.year);
break;
// ANSI yyyy.mm.dd, ANSI_SHORT yyyymmdd
case ANSI:
case ANSI_SHORT:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.4d%s%.2d%s%.2d",
m_Date.year,
m_Date.format==ANSI ? "." : (m_Date.format==ANSI_SHORT ? "" : "?"),
m_Date.month,
m_Date.format==ANSI ? "." : (m_Date.format==ANSI_SHORT ? "" : "?"),
m_Date.day);
break;
// dd/mm/yyyy
case BRITISH:
case FRENCH:
default:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d/%.2d/%.4d",
m_Date.day,
m_Date.month,
m_Date.year);
break;
// dd.mm.yyyy
case GERMAN:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d.%.2d.%.4d",
m_Date.day,
m_Date.month,
m_Date.year);
break;
// dd-mm-yyyy
case ITALIAN:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d-%.2d-%.4d",
m_Date.day,
m_Date.month,
m_Date.year);
break;
// yyyy/mm/dd
case JAPAN:
case YMD:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.4d/%.2d/%.2d",
m_Date.year,
m_Date.month,
m_Date.day);
break;
// mm-dd-yyyy
case USA:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d-%.2d-%.4d",
m_Date.month,
m_Date.day,
m_Date.year);
break;
// mm/dd/yyyy
case MDY:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d/%.2d/%.4d",
m_Date.month,
m_Date.day,
m_Date.year);
break;
// dd/mm/yyyy
case DMY:
_snprintf(m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%.2d-%.2d-%.4d",
m_Date.day,
m_Date.month,
m_Date.year);
break;
// GMT_SHORT "Day, dd Mon yyyy hh:mm:ss" (assumendo GMT, ossia convertendo l'UTC in GMT)
// GMT "Day, dd Mon yyyy hh:mm:ss <-|+>nnnn" (con l'UTC, ossia il <-|+>nnnn, locale)
// GMT_TZ "Day, dd Mon yyyy hh:mm:ss <-|+>nnnn TZ" (con l'UTC, ossia il <-|+>nnnn, locale, dove TZ e' l'identificativo di tre caratteri per l'UTC)
case GMT_SHORT:
case GMT:
case GMT_TZ:
{
int i = 0;
// ricava data e ora e le converte nel formato locale
if(getsysdate)
{
GetOsTime();
// per GMT_SHORT deve convertire l'UTC (<-|+>nnnn) in assoluto (0), cambiando i valori di data/ora
if(m_Date.format==GMT_SHORT)
{
// aggiunge/sottrae la differenza oraria per ottenere il valore assoluto (GMT)
ModifyDateTime(HOUR,(int)((GetTimeZoneDiff()/60)/60));
}
}
// formatta i valori di data e ora
i = _snprintf( m_Date.datestr,
sizeof(m_Date.datestr)-1,
"%s, %.2d %s %.4d %.2d:%.2d:%.2d",
day_array[m_Date.dayofweek],
m_Date.day,
month_array[m_Date.month-1],
m_Date.year,
m_Time.hour,
m_Time.min,
m_Time.sec);
if(m_Date.format!=GMT_SHORT)
{
// ricava la differenza oraria rispetto al GMT (divide i secondi in minuti ed i minuti in ore)
long tzd = (GetTimeZoneDiff() / 60) / 60;
_snprintf(m_Date.datestr+i,
sizeof(m_Date.datestr)-(1+i),
" %s0%d00%s%s",
tzd==0 ? "" : (tzd > 0 ? "+" : "-"),
/*tzd < 0 ? (int)tzd * -1 : (int)tzd,*/
tzd,
m_Date.format==GMT ? "" : " ",
m_Date.format==GMT ? "" : GetTimeZoneName());
}
}
break;
}
return(m_Date.datestr);
}
/*
GetFormattedTime()
Restituisce il puntatore all'ora formattata secondo il formato hh:mm:ss.
Passando TRUE come parametro ricava l'ora di sistema (aggiornando la struttura interna), con FALSE si
limita a formattare l'ora presente nella struttura interna.
*/
const char* CDateTime::GetFormattedTime(BOOL getsystime/*=TRUE*/)
{
// ricava la data di sistema
if(getsystime)
GetOsTime();
memset(&(m_Time.timestr),'\0',sizeof(m_Time.timestr));
// imposta a seconda del formato corrente
switch(m_Time.format)
{
// "hh:mm:ss", "hhmmss"
case HHMMSS:
case HHMMSS_SHORT:
_snprintf(m_Time.timestr,
sizeof(m_Time.timestr)-1,
"%.2d%s%.2d%s%.2d",
m_Time.hour,
m_Time.format==HHMMSS ? ":" : (m_Time.format==HHMMSS_SHORT ? "" : "?"),
m_Time.min,
m_Time.format==HHMMSS ? ":" : (m_Time.format==HHMMSS_SHORT ? "" : "?"),
m_Time.sec);
break;
// "hh:mm:ss <AM|PM>"
case HHMMSS_AMPM:
{
char ampm[]="AM\0";
if(m_Time.hour > 12)
{
m_Time.hour -= 12;
memcpy(ampm,"PM",2);
}
_snprintf(m_Time.timestr,
sizeof(m_Time.timestr)-1,
"%.2d:%.2d:%.2d %s",
m_Time.hour,
m_Time.min,
m_Time.sec,
ampm);
break;
}
// "hh:mm:ss" (assumendo GMT, ossia convertendo l'UTC in GMT)
case HHMMSS_GMT_SHORT:
break;
// "hh:mm:ss <-|+>nnnn" (con l'UTC, ossia il <-|+>nnnn, locale)
case HHMMSS_GMT:
break;
// "hh:mm:ss <-|+>nnnn TZ" (con l'UTC, ossia il <-|+>nnnn, locale, dove TZ e' l'identificativo di tre caratteri per l'UTC)
case HHMMSS_GMT_TZ:
break;
}
return(m_Time.timestr);
}
const char* CDateTime::ConvertDate(DATEFORMAT fmtsrc,DATEFORMAT fmtdst,const char* pdate,const char* ptime)
{
char buf[MAX_DATE_STRING+1] = {0};
memset(&(m_Date.datestr),'\0',sizeof(m_Date.datestr));
switch(fmtsrc)
{
case AMERICAN:
break;
case ANSI:
break;
case ANSI_SHORT:
{
memset(buf,'\0',sizeof(buf));
memcpy(buf,pdate,4);
m_Date.year = atoi(buf);
memset(buf,'\0',sizeof(buf));
memcpy(buf,pdate+4,2);
m_Date.month = atoi(buf);
memset(buf,'\0',sizeof(buf));
memcpy(buf,pdate+6,2);
m_Date.day = atoi(buf);
memset(buf,'\0',sizeof(buf));
memcpy(buf,ptime,2);
m_Time.hour = atoi(buf);
memset(buf,'\0',sizeof(buf));
memcpy(buf,ptime+2,2);
m_Time.min = atoi(buf);
memset(buf,'\0',sizeof(buf));
memcpy(buf,ptime+4,2);
m_Time.sec = atoi(buf);
break;
}
case BRITISH:
break;
case FRENCH:
break;
case GERMAN:
break;
case ITALIAN:
break;
case JAPAN:
break;
case USA:
break;
case MDY:
break;
case DMY:
break;
case YMD:
break;
case GMT_SHORT:
case GMT:
case GMT_TZ:
{
int i;
char* p = (char*)pdate;
// salta fino al giorno (numerico)
while(*p && !isdigit(*p))
p++;
// ricava il giorno
if(*p && isdigit(*p))
{
memset(buf,'\0',sizeof(buf));
for(i = 0; i < sizeof(buf) && *p && isdigit(*p); i++)
buf[i] = *p++;
m_Date.day = atoi(buf);
}
// salta fino al mese (stringa)
while(isspace(*p) || *p=='-')
p++;
// ricava il mese
if(*p)
{
memset(buf,'\0',sizeof(buf));
for(i = 0; i < sizeof(buf) && *p && isalpha(*p) && *p!=' ' && *p!='-'; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -