Skip to content

Commit

Permalink
WIP step 1
Browse files Browse the repository at this point in the history
Probleme detecte par Nicolas:
- les dates ou timestamps avec annee 9999 ne sont pas reconnus comme format valide, par le détecteur de format
- c'est normal: la limite dans Khiops est l'an 4000, depuis la prise en compte des timezone dans les timestamps
- introduire une tolerance?
  - si annee > 4000, accepter le format, mais traiter la valeur comme valeur manquante

Solution fonctionnelle:
- etendre a nouveau la limite des annee a 9999
- en diminuant legerement la precsiiobn des fraction de scondes (et 1/10000 a 1/1000)
- meilleurs compromis utilisateur
  - moins d'anomalies dans la lecture de bases existantes
    - le 9999 est souvent utilise pour recoder les valeurs manquantes
    - il est important de detecter correctement les format timestamps dans ce cas
  - tout en gardant un precsion de une millisconde
    - perdre le dixieme de millisecondes est peu important
    - si on veut passer a plus fin, ce sera la micro-secondes
      - besoin pei frequent
      - necessitera de toutes facon a un autre format (donne numerique directement, probablement)

Impact dans la documentation utilisateur, a prendre en compte

Impact technique
- les classe Date et Time etait chacune codee avec un int, et timestamp avec un longint concatenant les deux
- ce n'est plus possible, car il faut recuperer 2 bits de Time pour les utiliser dans Date
- solution plus complexe mise en place

TEMPORAIRE
- main de MODL: tests unitaires pour la mise au point
- Time
  - classe Timestamp en friend
  - type TimeValue avec unsigned long long int et nFillerDate
  - Reset: mise a 0 uniuement des champs Time
  - Check: test uniquement de la presence des champs Time
  - ForbiddenValue: a faire
- Date
  - classe Timestamp en friend
  - type DateValue avec unsigned long long int et nFillerDate
  - Reset: mise a 0 uniuement des champs Date
  - Check: test uniquement de la presence des champs Date
  - ForbiddenValue: a faire
- Timestamp
  - type unsigned long long int lTimestamp  au lieu de nDate et nTime
  - GetDate: mise a 0 des champs Time
  - SetDate: modification uniquement des champs Date
  - GetTime: mise a 0 des champs Date
  - SetTime: modification uniquement des champs Time
  - Test: plus d'assert sur la taille des type
- TimestampTS
  - Test: plus d'assert sur la taille des type
  • Loading branch information
marcboulle committed Nov 24, 2023
1 parent 8fe164e commit f899364
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 17 deletions.
17 changes: 14 additions & 3 deletions src/Learning/KWData/KWDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class Date : public SystemObject
///////////////////////////////////////////////////////////////////////////////////////////////
// La date peut stocker une partie time zone, utile quand elle est utilisee par les TimestampTZ
// qui doivent gerer les time zones
friend class Timestamp;
friend class TimestampTZ;
friend class KWTimestampTZFormat;

Expand Down Expand Up @@ -159,7 +160,7 @@ class Date : public SystemObject
// La partie time zone est invalide si elle vaut 0 (une time zone -00:00 est codee +00:00 pour etre valide).
union DateValue
{
unsigned int nDate;
unsigned long long int nDate;
struct DateFields
{
unsigned int nYear : 12;
Expand All @@ -168,6 +169,7 @@ class Date : public SystemObject
unsigned int nTimeZoneSign : 1;
unsigned int nTimeZoneHour : 4;
unsigned int nTimeZoneMinute : 6;
unsigned int nFillerTime : 32;
} dateFields;
} dateValue;
};
Expand Down Expand Up @@ -291,7 +293,13 @@ class KWDateFormat : public Object

inline void Date::Reset()
{
dateValue.nDate = 0;
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
Expand All @@ -307,7 +315,10 @@ inline boolean Date::operator!=(const Date& dtValue) const
inline boolean Date::Check() const
{
require(not IsForbiddenValue());
return dateValue.nDate != 0;
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
Expand Down
17 changes: 14 additions & 3 deletions src/Learning/KWData/KWTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ class Time : public SystemObject
//////////////////////////////////////////////////////
//// Implementation
protected:
///////////////////////////////////////////////////////////////////////////////////////////////
// La time peut stocker une partie timestamp
friend class Timestamp;

// Modification des champs de la Time
void SetHour(int nValue);
void SetMinute(int nValue);
Expand All @@ -102,9 +106,10 @@ class Time : public SystemObject
// Une time est invalide si elle vaut 0 (heure a 0; validite de 1 a 24), et interdite si elle vaut 0xFFFFFFFF
union TimeValue
{
unsigned int nTime;
unsigned long long int nTime;
struct TimeFields
{
unsigned int nFillerDate : 32;
unsigned int nHour : 5;
unsigned int nMinute : 6;
unsigned int nSecond : 6;
Expand Down Expand Up @@ -248,7 +253,11 @@ class KWTimeFormat : public Object

inline void Time::Reset()
{
timeValue.nTime = 0;
timeValue.timeFields.nHour = 0;
timeValue.timeFields.nMinute = 0;
timeValue.timeFields.nSecond = 0;
timeValue.timeFields.nFrac = 0;
//DDD timeValue.nTime = 0;
}

inline boolean Time::operator==(const Time& tmValue) const
Expand All @@ -264,7 +273,9 @@ inline boolean Time::operator!=(const Time& tmValue) const
inline boolean Time::Check() const
{
require(not IsForbiddenValue());
return timeValue.nTime != 0;
return timeValue.timeFields.nHour != 0 or timeValue.timeFields.nMinute != 0 or
timeValue.timeFields.nSecond != 0 or timeValue.timeFields.nFrac != 0;
//return timeValue.nTime != 0;
}

inline int Time::GetHour() const
Expand Down
2 changes: 1 addition & 1 deletion src/Learning/KWData/KWTimestamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ void Timestamp::Test()
int nTotalSecondNumber;

cout << "sizeof(Timestamp): " << sizeof(Timestamp) << endl;
assert(sizeof(Timestamp) == sizeof(Date) + sizeof(Time));
//DDD assert(sizeof(Timestamp) == sizeof(Date) + sizeof(Time));
assert(sizeof(Timestamp) == 2 * sizeof(int));
tsCurrent.SetCurrentTimestamp();
cout << "SYSTEM\tCurrent Timestamp\t" << tsCurrent << "\t" << tsCurrent.GetDate().GetWeekDay() << endl;
Expand Down
73 changes: 64 additions & 9 deletions src/Learning/KWData/KWTimestamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,16 @@ class Timestamp : public SystemObject
// et le sizeof(Timestamp) fait plus de 8 octets si on utilise les type Date et Time
// (ce probleme apparait meme si on utilise les primitives specifiques a Linux pour desactiver le packing.
// on n'a pas ce probleme sous windows)
unsigned int nDate;
unsigned int nTime;
unsigned long long int lTimestamp;
//DDD unsigned int nDate;
//DDD unsigned int nTime;

// Classes en friend pour acceder aux informations interne de Date et Time
friend class KWTimestampFormat;
friend class TimestampTZ;

// Acces aux attributs en mode mise a jour
// L'acces par reference permet de les utilisater en affectation
// L'acces par reference permet de les utiliser en affectation
// Exemple: GetInternalDate() = myDate, ou GetInternalDate().Reset()
Date& GetInternalDate() const;
Time& GetInternalTime() const;
Expand Down Expand Up @@ -256,22 +257,74 @@ inline boolean Timestamp::Check() const

inline const Date Timestamp::GetDate() const
{
return (const Date)GetInternalDate();
Timestamp tsTmp;

tsTmp = *this;
tsTmp.GetInternalTime().timeValue.timeFields.nHour = 0;
tsTmp.GetInternalTime().timeValue.timeFields.nMinute = 0;
tsTmp.GetInternalTime().timeValue.timeFields.nSecond = 0;
tsTmp.GetInternalTime().timeValue.timeFields.nFrac = 0;
return (const Date)tsTmp.GetInternalDate();
//DDD return (const Date)GetInternalDate();
}

inline void Timestamp::SetDate(const Date dtValue)
{
GetInternalDate() = dtValue;
/*DDD
static const unsigned long long lTimeMask = 0X00000000FFFFFFFF;
static const unsigned long long lDateMask = 0XFFFFFFFF00000000;
unsigned long long lTmpDate;
unsigned long long lTmpTime;
Timestamp tsTmp;
lTmpDate = dtValue.dateValue.nDate;
lTmpDate &= lDateMask;
lTmpTime = lTimestamp;
lTmpTime &= lTimeMask;
lTimestamp = lTmpDate | lTmpTime;
*/
GetInternalDate().dateValue.dateFields.nYear = dtValue.dateValue.dateFields.nYear;
GetInternalDate().dateValue.dateFields.nMonth = dtValue.dateValue.dateFields.nMonth;
GetInternalDate().dateValue.dateFields.nDay = dtValue.dateValue.dateFields.nDay;
GetInternalDate().dateValue.dateFields.nTimeZoneSign = dtValue.dateValue.dateFields.nTimeZoneSign;
GetInternalDate().dateValue.dateFields.nTimeZoneHour = dtValue.dateValue.dateFields.nTimeZoneHour;
GetInternalDate().dateValue.dateFields.nTimeZoneMinute = dtValue.dateValue.dateFields.nTimeZoneMinute;
//DDD GetInternalDate() = dtValue;
}

inline const Time Timestamp::GetTime() const
{
return (const Time)GetInternalTime();
Timestamp tsTmp;

tsTmp = *this;
tsTmp.GetInternalDate().dateValue.dateFields.nYear = 0;
tsTmp.GetInternalDate().dateValue.dateFields.nMonth = 0;
tsTmp.GetInternalDate().dateValue.dateFields.nDay = 0;
tsTmp.GetInternalDate().dateValue.dateFields.nTimeZoneSign = 0;
tsTmp.GetInternalDate().dateValue.dateFields.nTimeZoneHour = 0;
tsTmp.GetInternalDate().dateValue.dateFields.nTimeZoneMinute = 0;
return (const Time)tsTmp.GetInternalTime();
//DDD return (const Time)GetInternalTime();
}

inline void Timestamp::SetTime(const Time tmValue)
{
GetInternalTime() = tmValue;
/*DDD
static const unsigned long long lTimeMask = 0X00000000FFFFFFFF;
static const unsigned long long lDateMask = 0XFFFFFFFF00000000;
unsigned long long lTmpDate;
unsigned long long lTmpTime;
lTmpDate = lTimestamp & lDateMask;
lTmpTime = tmValue.timeValue.nTime & lTimeMask;
lTimestamp = lTmpDate | lTmpTime;
*/
GetInternalTime().timeValue.timeFields.nHour = tmValue.timeValue.timeFields.nHour;
GetInternalTime().timeValue.timeFields.nMinute = tmValue.timeValue.timeFields.nMinute;
GetInternalTime().timeValue.timeFields.nSecond = tmValue.timeValue.timeFields.nSecond;
GetInternalTime().timeValue.timeFields.nFrac = tmValue.timeValue.timeFields.nFrac;

//DDD GetInternalTime() = tmValue;
}

inline double Timestamp::GetAbsoluteSecond() const
Expand Down Expand Up @@ -339,12 +392,14 @@ inline boolean Timestamp::IsForbiddenValue() const

inline Date& Timestamp::GetInternalDate() const
{
return (Date&)nDate;
//DDD return (Date&)nDate;
return (Date&)lTimestamp;
}

inline Time& Timestamp::GetInternalTime() const
{
return (Time&)nTime;
//DDD return (Time&)nTime;
return (Time&)lTimestamp;
}

// KWTimestampFormat
Expand Down
2 changes: 1 addition & 1 deletion src/Learning/KWData/KWTimestampTZ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void TimestampTZ::Test()
int i;

cout << "sizeof(TimestampTZ): " << sizeof(TimestampTZ) << endl;
assert(sizeof(TimestampTZ) == sizeof(Date) + sizeof(Time));
//DDD assert(sizeof(TimestampTZ) == sizeof(Date) + sizeof(Time));
assert(sizeof(TimestampTZ) == 2 * sizeof(int));

// Test de quelques time zones
Expand Down
13 changes: 13 additions & 0 deletions src/Learning/MODL/MODL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ int main(int argc, char** argv)
{
MDKhiopsLearningProject learningProject;

//DDD
/*DDD
cout << "TEST Time\n";
Time::Test();
cout << "TEST Date\n";
Date::Test();
*/
cout << "TEST Timestamp\n";
Timestamp::Test();
cout << "TEST TimestampTZ\n";
TimestampTZ::Test();
return 0;

// Activation de la gestion des signaux via des erreurs, pour afficher des messages d'erreur explicites
// A potentiellement commenter sur certains IDE lors des phases de debuggage
Global::ActivateSignalErrorManagement();
Expand Down

0 comments on commit f899364

Please sign in to comment.