1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-11 10:44:53 +03:00
occt/src/Quantity/Quantity_Date.cxx
2012-03-05 19:23:40 +04:00

428 lines
12 KiB
C++
Executable File

// -------------------------------------------------------------
//
// Created by J.P BOUDIER J.P. TIRAULT Jan,5th 1993
// C matra datavision 1993
//
// Date class implementation.
//
// Updated :
//
// -------------------------------------------------------------
#include <Quantity_DateDefinitionError.hxx>
#include <Standard_OutOfRange.hxx>
#include <Quantity_Date.ixx>
static int month_table[12] = {
31, // January
28, // February
31, // March
30, // April
31, // May
30, // June
31, // July
31, // August
30, // September
31, // October
30, // November
31}; // December
static int SecondsByYear = 365 * 24 * 3600 ; // Normal Year
static int SecondsByLeapYear = 366 * 24 * 3600 ; // Leap Year
// -----------------------------------------
// Initialize a date to January,1 1979 00:00
// -----------------------------------------
Quantity_Date::Quantity_Date(): mySec(0),myUSec(0) {}
// -----------------------------------------------------------
// IsValid : Checks the validity of a date
// This is the complete way month, day, year, ... micro second
// -----------------------------------------------------------
Standard_Boolean Quantity_Date::IsValid(const Standard_Integer mm,
const Standard_Integer dd,
const Standard_Integer yy,
const Standard_Integer hh,
const Standard_Integer mn,
const Standard_Integer ss,
const Standard_Integer mis,
const Standard_Integer mics){
if (mm < 1 || mm > 12) return Standard_False;
if (yy < 1979 ) return Standard_False;
if ( Quantity_Date::IsLeap (yy) ) month_table[1] = 29;
else month_table[1] = 28;
if (dd < 1 || dd > month_table[mm-1]) return Standard_False;
if (hh < 0 || hh > 23) return Standard_False;
if (mn < 0 || mn > 59) return Standard_False;
if (ss < 0 || ss > 59) return Standard_False;
if (mis < 0 || mis > 999) return Standard_False;
if (mics < 0 || mics > 999) return Standard_False;
return Standard_True;
}
// -----------------------------------------------------------
// Initialize a Date :
// This is the complete way month, day, year, ... micro second
// -----------------------------------------------------------
Quantity_Date::Quantity_Date(const Standard_Integer mm,
const Standard_Integer dd,
const Standard_Integer yy,
const Standard_Integer hh,
const Standard_Integer mn,
const Standard_Integer ss,
const Standard_Integer mis,
const Standard_Integer mics){
SetValues (mm,dd,yy,hh,mn,ss,mis,mics);
}
// ------------------------------------------------------------
// Set values of a Date :
// This is the complete way month, day, year, ... micro second
// ------------------------------------------------------------
void Quantity_Date::SetValues(const Standard_Integer mm,
const Standard_Integer dd,
const Standard_Integer yy,
const Standard_Integer hh,
const Standard_Integer mn,
const Standard_Integer ss,
const Standard_Integer mis,
const Standard_Integer mics){
Standard_Integer i;
if ( ! Quantity_Date::IsValid (mm,dd,yy,hh,mn,ss,mis,mics))
Quantity_DateDefinitionError::Raise(
"Quantity_Date::Quantity_Date invalid parameters");
if ( Quantity_Date::IsLeap (yy) ) month_table[1] = 29;
else month_table[1] = 28;
mySec = 0;
myUSec = 0;
for(i = 1979; i < yy; i++) {
if ( ! Quantity_Date::IsLeap (i) ) mySec += SecondsByYear;
else mySec += SecondsByLeapYear;
}
for(i = 1; i< mm; i++) {
mySec += month_table[i-1] * 3600 * 24 ;
}
mySec += 3600 * 24 * (dd-1);
mySec += 3600 * hh;
mySec += 60 * mn;
mySec += ss;
myUSec += mis * 1000;
myUSec += mics;
}
// ---------------------------------------------
// Values : Returns the values of a date
// ~~~~~~
// ---------------------------------------------
void Quantity_Date::Values(Standard_Integer& mm,
Standard_Integer& dd,
Standard_Integer& yy,
Standard_Integer& hh,
Standard_Integer& mn,
Standard_Integer& ss,
Standard_Integer& mis,
Standard_Integer& mics)const{
Standard_Integer i,carry;
for(yy = 1979, carry = mySec ;; yy++) {
if ( ! Quantity_Date::IsLeap (yy) )
{
month_table[1] = 28; // normal year
if (carry >= SecondsByYear ) carry -= SecondsByYear;
else break;
}
else
{
month_table[1] = 29; // Leap year
if (carry >= SecondsByLeapYear) carry -= SecondsByLeapYear;
else break;
}
}
for(mm = 1 ; ; mm++) {
i = month_table[mm-1] * 3600 * 24;
if ( carry >= i ) carry -= i;
else break;
}
i = 3600 * 24;
for(dd = 1 ; ; dd++) {
if ( carry >= i ) carry -= i;
else break;
}
for(hh = 0 ; ; hh++) {
if ( carry >= 3600 ) carry -= 3600;
else break;
}
for(mn = 0 ; ; mn++) {
if ( carry >= 60 ) carry -= 60;
else break;
}
ss = carry;
mis = myUSec / 1000;
mics = myUSec - ( mis * 1000);
}
// ---------------------------------------------------------------------
// Difference : Subtract a date to a given date; the result is a period
// ~~~~~~~~~~ of time
// ---------------------------------------------------------------------
Quantity_Period Quantity_Date::Difference(const Quantity_Date& OtherDate){
Standard_Integer i1,i2;
if (mySec == 0 && myUSec == 0)
{
i1 = OtherDate.mySec;
i2 = OtherDate.myUSec;
}
else {
i1 = mySec - OtherDate.mySec ;
i2 = myUSec - OtherDate.myUSec;
}
if ( i1 >= 0 && i2 < 0 ) {
i1--;
i2 = 1000000 + i2 ;
}
else if ( i1 <0 && i2 >= 0 ) {
i1 = Abs(i1);
if ( i2 > 0 ){
i1--;
i2 = 1000000 - i2 ;
}
}
else if ( i1 <0 && i2 < 0 ) {
i1 = Abs(i1);
i2 = Abs(i2);
}
Quantity_Period result ( i1 , i2 );
return (result);
}
// ------------------------------------------------------------------
// Subtract : subtracts a period to a date and returns a date.
// ~~~~~~~~
// ------------------------------------------------------------------
Quantity_Date Quantity_Date::Subtract(const Quantity_Period& During){
Standard_Integer ss,mics;
Quantity_Date result;
result.mySec = mySec;
result.myUSec = myUSec;
During.Values (ss,mics);
result.mySec -= ss;
result.myUSec -= mics;
if ( result.mySec >= 0 && result.myUSec < 0 ) {
result.mySec--;
result.myUSec = 1000000 + result.myUSec ;
}
if ( result.mySec <0 )
Quantity_DateDefinitionError::Raise(
"Quantity_Date::Subtract : The result date is anterior to Jan,1 1979");
return (result);
}
// ----------------------------------------------------------------------
// Add : Adds a period of time to a date
// ~~~
// ----------------------------------------------------------------------
Quantity_Date Quantity_Date::Add(const Quantity_Period& During){
Quantity_Date result;
During.Values (result.mySec,result.myUSec);
result.mySec += mySec;
result.myUSec += myUSec;
if ( result.myUSec >= 1000000 ) {
result.mySec++;
result.myUSec -= 1000000;
}
return (result);
}
// ----------------------------------------------------------------------
// Year : Return the year of a date
// ~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Year(){
Standard_Integer dummy, year;
Values(dummy, dummy, year, dummy, dummy, dummy, dummy, dummy);
return (year);
}
// ----------------------------------------------------------------------
// Month : Return the month of a date
// ~~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Month(){
Standard_Integer dummy, month;
Values(month, dummy, dummy, dummy, dummy, dummy, dummy, dummy);
return(month);
}
// ----------------------------------------------------------------------
// Day : Return the day of a date
// ~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Day(){
Standard_Integer dummy, day;
Values(dummy, day, dummy, dummy, dummy, dummy, dummy, dummy);
return(day);
}
// ----------------------------------------------------------------------
// hour : Return the hour of a date
// ~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Hour(){
Standard_Integer dummy, hour;
Values(dummy, dummy, dummy, hour, dummy, dummy, dummy, dummy);
return(hour);
}
// ----------------------------------------------------------------------
// Minute : Return the minute of a date
// ~~~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Minute(){
Standard_Integer dummy, min;
Values(dummy, dummy, dummy, dummy, min, dummy, dummy, dummy);
return(min);
}
// ----------------------------------------------------------------------
// Second : Return the second of a date
// ~~~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::Second(){
Standard_Integer dummy, sec;
Values(dummy, dummy, dummy, dummy, dummy, sec , dummy, dummy);
return(sec);
}
// ----------------------------------------------------------------------
// millisecond : Return the millisecond of a date
// ~~~~~~~~~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::MilliSecond(){
Standard_Integer dummy, msec;
Values(dummy, dummy, dummy, dummy, dummy, dummy, msec, dummy);
return(msec);
}
// ----------------------------------------------------------------------
// Day : Return the day of a date
// ~~~
// ----------------------------------------------------------------------
Standard_Integer Quantity_Date::MicroSecond(){
Standard_Integer dummy, msec;
Values(dummy, dummy, dummy, dummy, dummy, dummy, dummy, msec);
return(msec);
}
// ----------------------------------------------------------------------
// IsEarlier : Return true if the date is earlier than an other date
// ~~~~~~~~~
// ----------------------------------------------------------------------
Standard_Boolean Quantity_Date::IsEarlier(const Quantity_Date& other)const{
if (mySec < other.mySec) return Standard_True;
else if (mySec > other.mySec) return Standard_False;
else return ( ( myUSec < other.myUSec ) ? Standard_True : Standard_False);
}
// ----------------------------------------------------------------------
// IsLater : Return true if the date is later than an other date
// ~~~~~~~
// ----------------------------------------------------------------------
Standard_Boolean Quantity_Date::IsLater(const Quantity_Date& other)const{
if (mySec > other.mySec) return Standard_True;
else if (mySec < other.mySec) return Standard_False;
else return ( ( myUSec > other.myUSec ) ? Standard_True : Standard_False);
}
// ----------------------------------------------------------------------
// IsEqual : Return true if the date is the same than an other date
// ~~~~~~~
// ----------------------------------------------------------------------
Standard_Boolean Quantity_Date::IsEqual(const Quantity_Date& other)const{
return ( ( myUSec == other.myUSec &&
mySec == other.mySec ) ? Standard_True : Standard_False);
}