Skip to content

Commit

Permalink
WIP setp 5
Browse files Browse the repository at this point in the history
Utilisation systématique de l'uniin DateTime dans les type Date, Time, Timestamp, TimestampTZ
- ok avec tous les tests unitaires
  • Loading branch information
marcboulle committed Nov 27, 2023
1 parent 281ad84 commit 58785f8
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 87 deletions.
70 changes: 54 additions & 16 deletions src/Learning/KWData/KWDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Date;
class KWDateFormat;

#include "Object.h"
#include "KWDateTime.h"
#include "Vector.h"

////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -147,6 +148,10 @@ class Date : public SystemObject
// Affichage de la partie time zone au format zzzzzz si bExtended vaut true, zzzzz sinon
const char* const TimeZoneToString(boolean bExtended) const;

// Utilisation d'une union DateTime pour acceder au champs Date, dans une structure commune aux type temporels
union DateTime dateValue;

/*DDD
// Stockage optimise d'une Date sous forme d'un entier
// On utilise un champ de bits pour stocker a la fois les information de Date et de time zone, utilises
// potentiellement dans les cas des TimestampTZ
Expand All @@ -172,6 +177,7 @@ class Date : public SystemObject
unsigned int nFillerTime : 32;
} dateFields;
} dateValue;
*/
};

// Ecriture dans un stream
Expand Down Expand Up @@ -293,50 +299,64 @@ class KWDateFormat : public Object

inline void Date::Reset()
{
dateValue.lBytes = 0;
/*DDD
dateValue.dateFields.nYear = 0;
dateValue.dateFields.nMonth = 0;
dateValue.dateFields.nDay = 0;
dateValue.dateFields.nTimeZoneSign = 0;
dateValue.dateFields.nTimeZoneHour = 0;
dateValue.dateFields.nTimeZoneMinute = 0;
*/
//DDD dateValue.nDate = 0;
}

inline boolean Date::operator==(const Date& dtValue) const
{
return (dateValue.nDate == dtValue.dateValue.nDate);
return (dateValue.lBytes == dtValue.dateValue.lBytes);
//DDD return (dateValue.parts.nDate == dtValue.dateValue.parts.nDate);
//DDD return (dateValue.nDate == dtValue.dateValue.nDate);
}

inline boolean Date::operator!=(const Date& dtValue) const
{
return (dateValue.nDate != dtValue.dateValue.nDate);
return (dateValue.lBytes != dtValue.dateValue.lBytes);
//DDD return (dateValue.parts.nDate != dtValue.dateValue.parts.nDate);
//DDD return (dateValue.nDate != dtValue.dateValue.nDate);
}

inline boolean Date::Check() const
{
require(not IsForbiddenValue());
return dateValue.lBytes != 0;
//DDD return dateValue.parts.nDate != 0;
/*DDD
return dateValue.dateFields.nYear != 0 or dateValue.dateFields.nMonth != 0 or dateValue.dateFields.nDay != 0 or
dateValue.dateFields.nTimeZoneSign != 0 or dateValue.dateFields.nTimeZoneHour != 0 or
dateValue.dateFields.nTimeZoneMinute != 0;
*/
//DDD return dateValue.nDate != 0;
}

inline int Date::GetYear() const
{
require(Check());
return dateValue.dateFields.nYear;
return dateValue.fields.nYear;
//DDD return dateValue.dateFields.nYear;
}

inline int Date::GetMonth() const
{
require(Check());
return dateValue.dateFields.nMonth;
return dateValue.fields.nMonth;
//DDD return dateValue.dateFields.nMonth;
}

inline int Date::GetDay() const
{
require(Check());
return dateValue.dateFields.nDay;
return dateValue.fields.nDay;
//DDD return dateValue.dateFields.nDay;
}

inline int Date::Diff(const Date dtOtherDate) const
Expand Down Expand Up @@ -367,29 +387,34 @@ inline int Date::Compare(const Date dtOtherDate) const
inline void Date::SetYear(int nValue)
{
require(1 <= nValue and nValue <= 4000);
dateValue.dateFields.nYear = nValue;
dateValue.fields.nYear = nValue;
//DDD dateValue.dateFields.nYear = nValue;
}

inline void Date::SetMonth(int nValue)
{
require(1 <= nValue and nValue <= 12);
dateValue.dateFields.nMonth = nValue;
dateValue.fields.nMonth = nValue;
//DDD dateValue.dateFields.nMonth = nValue;
}

inline void Date::SetDay(int nValue)
{
require(1 <= nValue and nValue <= 31);
dateValue.dateFields.nDay = nValue;
dateValue.fields.nDay = nValue;
//DDD dateValue.dateFields.nDay = nValue;
}

inline void Date::SetForbiddenValue()
{
dateValue.nDate = 0xFFFFFFFF;
dateValue.lBytes = DateTime::lForbiddenValue;
//DDD dateValue.nDate = 0xFFFFFFFF;
}

inline boolean Date::IsForbiddenValue() const
{
return (dateValue.nDate == 0xFFFFFFFF);
return (dateValue.lBytes == DateTime::lForbiddenValue);
//DDD return (dateValue.nDate == 0xFFFFFFFF);
}

inline boolean Date::InitTimeZone(int nSign, int nHour, int nMinute)
Expand Down Expand Up @@ -447,51 +472,64 @@ inline int Date::GetTimeZoneTotalMinutes() const
inline void Date::SetTimeZoneSign(int nValue)
{
require(nValue == -1 or nValue == 1);
dateValue.dateFields.nTimeZoneSign = (nValue + 1) / 2;
dateValue.fields.nTimeZoneSign = (nValue + 1) / 2;
//DDD dateValue.dateFields.nTimeZoneSign = (nValue + 1) / 2;
}

inline int Date::GetTimeZoneSign() const
{
require(CheckTimeZone());
return (dateValue.dateFields.nTimeZoneSign * 2) - 1;
return (dateValue.fields.nTimeZoneSign * 2) - 1;
//DDD return (dateValue.dateFields.nTimeZoneSign * 2) - 1;
}

inline void Date::SetTimeZoneHour(int nValue)
{
require(0 <= nValue and nValue <= 14);
dateValue.dateFields.nTimeZoneHour = nValue;
dateValue.fields.nTimeZoneHour = nValue;
//DDD dateValue.dateFields.nTimeZoneHour = nValue;
}

inline int Date::GetTimeZoneHour() const
{
require(CheckTimeZone());
return dateValue.dateFields.nTimeZoneHour;
return dateValue.fields.nTimeZoneHour;
//DDD return dateValue.dateFields.nTimeZoneHour;
}

inline void Date::SetTimeZoneMinute(int nValue)
{
require(0 <= nValue and nValue <= 59);
dateValue.dateFields.nTimeZoneMinute = nValue;
dateValue.SetTimeZoneMinute(nValue);
//DDD dateValue.dateFields.nTimeZoneMinute = nValue;
}

inline int Date::GetTimeZoneMinute() const
{
require(CheckTimeZone());
return dateValue.dateFields.nTimeZoneMinute;
return dateValue.GetTimeZoneMinute();
//DDD return dateValue.dateFields.nTimeZoneMinute;
}

inline void Date::ResetTimeZone()
{
//DDD
dateValue.SetTimeZone(0);
/*DDD
dateValue.dateFields.nTimeZoneSign = 0;
dateValue.dateFields.nTimeZoneHour = 0;
dateValue.dateFields.nTimeZoneMinute = 0;
*/
}

inline boolean Date::CheckTimeZone() const
{
require(not IsForbiddenValue());
return dateValue.GetTimeZone() != 0;
/*DDD
return dateValue.dateFields.nTimeZoneSign != 0 or dateValue.dateFields.nTimeZoneHour != 0 or
dateValue.dateFields.nTimeZoneMinute != 0;
*/
}

// KWDateFormat
Expand Down
10 changes: 8 additions & 2 deletions src/Learning/KWData/KWDateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ void DateTime::Test()
cout << "DateTime: " << sizeof(DateTime) << "\n";
assert(sizeof(DateTime) == sizeof(longint));

// Contenu a 0
dtDateTimeValue.lBytes = 0;
// Nombre de digits des fractions de scondes
cout << "Frac seconds digits: " << nFracSecondsDigitNumber << "\n";
cout << "Frac seconds max: " << nMaxFracSeconds << "\n";
assert(10 * (nMaxFracSeconds / 10) == nMaxFracSeconds);
assert(int(pow(10, nFracSecondsDigitNumber)) == nMaxFracSeconds),

// Contenu a 0
dtDateTimeValue.lBytes = 0;
cout << "\nDateTime invalid value\n", dtDateTimeValue.WriteInternalFields(cout);

// Contenu interdit
Expand Down
13 changes: 10 additions & 3 deletions src/Learning/KWData/KWDateTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ union DateTime
//////////////////////////////////////////////////////////////////////////
//// Implementation
protected:
// Acces aux classes ayant besoin de connaitre l'implementation
// Classes ayant besoin de connaitre l'implementation en friend
friend class Date;
friend class Time;
friend class Timestamp;
friend class TimestampTS;
friend class TimestampTZ;
friend class KWTimeFormat;

// Affichage detaille de tous les champs
void WriteInternalFields(ostream& ost) const;
Expand Down Expand Up @@ -64,7 +65,7 @@ union DateTime
// de la timezone sont coupes en deux

// Pour manipuler tous les champs en une seule operation
unsigned long long lBytes;
longint lBytes;

// Pour manipuler les champs de detail individuellement
struct DateTimeFields
Expand All @@ -91,6 +92,12 @@ union DateTime
unsigned int nTime : 32; // sous-partie des champs Time
} parts;

// Nombre de digits utilises pour les fraction de secondes
static const int nFracSecondsDigitNumber = 4;

// Valeur max des fractions de secondes, en puissance de 10
static const int nMaxFracSeconds = 10000;

// Constante utilisee pour gerer la valeur interdite de tous les types date time
static const longint lForbiddenValue = 0xFFFFFFFFFFFFFFFF;
};
Expand Down
53 changes: 25 additions & 28 deletions src/Learning/KWData/KWTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,24 @@ const char* const Time::ToString() const
sTime[0] = '\0';
else
{
nSecondFrac = timeValue.timeFields.nFrac;
nSecondFrac = timeValue.fields.nFrac;
//DDD nSecondFrac = timeValue.timeFields.nFrac;

// Cas ou il n'y a pas de fraction de secondes
if (nSecondFrac == 0)
snprintf(sTime, BUFFER_LENGTH, "%02d:%02d:%02d", GetHour(), GetMinute(),
(int)timeValue.timeFields.nSecond);
(int)timeValue.fields.nSecond);
//DDD (int)timeValue.timeFields.nSecond);
// Cas avec fraction de secondes
else
{
nLength = snprintf(sTime, BUFFER_LENGTH, "%02d:%02d:%02d.%04d", GetHour(), GetMinute(),
(int)timeValue.timeFields.nSecond, nSecondFrac);
nLength =
snprintf(sTime, BUFFER_LENGTH, "%02d:%02d:%02d.%0*d", GetHour(), GetMinute(),
(int)timeValue.fields.nSecond, DateTime::nFracSecondsDigitNumber, nSecondFrac);
//DDD (int)timeValue.timeFields.nSecond, nSecondFrac);

// Supression des zero en fin pour ne garder que la partie utile des decimales de secondes
for (i = 0; i < 4; i++)
for (i = 0; i < DateTime::nFracSecondsDigitNumber; i++)
{
if (sTime[nLength - 1 - i] == '0')
sTime[nLength - 1 - i] = '\0';
Expand Down Expand Up @@ -524,20 +528,16 @@ Time KWTimeFormat::StringToTime(const char* const sValue) const
assert(sValue[nOffset - 1] == '.');

// Parcours de la fin de chaine a partir du sepateur decimal des secondes
nUnit = 1000;
nUnit = DateTime::nMaxFracSeconds;
for (i = nOffset; i < nLength; i++)
{
cChar0 = sValue[i];
bCheck = isdigit(cChar0);
if (bCheck)
{
// On ne prend en compte que les decimales utiles au 1/10000 ieme
if (nUnit > 0)
{
nSecondFrac += nUnit * (cChar0 - '0');
nUnit /= 10;
}
}

// On ne prend en compte que les decimales utiles de la fraction de secondes
nUnit /= 10;
if (bCheck and nUnit == 0)
nSecondFrac += nUnit * (cChar0 - '0');
else
break;
}
Expand Down Expand Up @@ -613,20 +613,16 @@ Time KWTimeFormat::StringToTime(const char* const sValue) const
if (bCheck and nDecimalPointOffset != -1)
{
// Parcours de la fin de chaine a partir du sepateur decimal des secondes
nUnit = 1000;
nUnit = DateTime::nMaxFracSeconds;
for (i = nDecimalPointOffset + 1; i < nLength; i++)
{
cChar0 = sValue[i];
bCheck = isdigit(cChar0);
if (bCheck)
{
// On ne prend en compte que les decimales utiles au 1/10000 ieme
if (nUnit > 0)
{
nSecondFrac += nUnit * (cChar0 - '0');
nUnit /= 10;
}
}

// On ne prend en compte que les decimales utiles de la fraction de secondes
nUnit /= 10;
if (bCheck and nUnit == 0)
nSecondFrac += nUnit * (cChar0 - '0');
else
break;
}
Expand All @@ -636,7 +632,7 @@ Time KWTimeFormat::StringToTime(const char* const sValue) const

// Conversion vers la Time
if (bCheck)
tmConvertedString.Init(nHour, nMinute, nSecond + nSecondFrac / 10000.0);
tmConvertedString.Init(nHour, nMinute, nSecond + nSecondFrac / (double)DateTime::nMaxFracSeconds);

return tmConvertedString;
}
Expand Down Expand Up @@ -705,8 +701,9 @@ const char* const KWTimeFormat::TimeToString(Time tmValue) const
if (nDecimalPointOffset != -1)
{
// Calcul des fractions de secondes
nSecondFrac = (int)floor((tmValue.GetSecond() - nSecond + dEpsilon) * 10000);
if (nSecondFrac == 10000)
nSecondFrac =
(int)floor((tmValue.GetSecond() - nSecond + dEpsilon) * DateTime::nMaxFracSeconds);
if (nSecondFrac == DateTime::nMaxFracSeconds)
nSecondFrac--;

// Ecriture des fractions de secondes
Expand Down
Loading

0 comments on commit 58785f8

Please sign in to comment.