//================================================================================================== // C a l e n d a r Interface // G r e g o r i a n // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to manipulate date and time information in the Gregorian calendar. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "calendar/gregorian.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guCalendarGregorian #define guCalendarGregorian
// Headers //--------------------------------------------------------------------------------------- #include <bpp/standard.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef CALENDAR_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area calendarGregorian #define private_area calendarGregorian_private
namespace public_area { using namespace standard; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniCalendarGregorian has_initializer;
// Macrocommands //---------------------------------------------------------------------------------
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes class clGregorian; //-----------------------------------------------------------------------------------Variable Types /*TYPE*/ /* Symbolic constants for the months. */ enumeration { january=1, february=2, march=3, april=4, may=5, june=6, july=7, august=8, september=9, october=10, november=11, december=12 } tyMonth;
/*TYPE*/ /* Symbolic constants for the week days. */ enumeration { sunday=1, monday=2, tuesday=3, wednesday=4, thursday=5, friday=6, saturday=7 } tyWeekDay;
/*TYPE*/ /* Symbolic constants for the kind of year. */ enumeration { normalYear=false, leapYear=true } tyYearKind;
/*TYPE*/ /* Symbolic constants for the string format of the date. */ enumeration { dayFirstLongDate, dayFirstShortDate, monthFirstLongDate, monthFirstShortDate } tyDateFormat;
/*TYPE*/ /* Symbolic constants for the string format of the time. */ enumeration { americanLongTime, americanShortTime, militaryLongTime, militaryShortTime } tyTimeFormat; //-----------------------------------------------------------------------------------Constant Types typedef const clGregorian ctGregorian;
typedef const tyMonth tcMonth; typedef const tyWeekDay tcWeekDay; typedef const tyYearKind tcYearKind;
typedef const tyDateFormat tcDateFormat; typedef const tyTimeFormat tcTimeFormat; }
namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { inline tyInteger monthLength(tyMonth,tyYearKind=normalYear); inline tcString monthName(tyMonth); inline tyInteger nbDaySinceNewYear(tyMonth,tyYearKind); inline tcString weekDayName(tyWeekDay);
inline tyBoolean operator == (ctGregorian &,ctGregorian &); inline tyBoolean operator < (ctGregorian &,ctGregorian &); inline tyBoolean operator != (ctGregorian &,ctGregorian &); inline tyBoolean operator > (ctGregorian &,ctGregorian &); inline tyBoolean operator <= (ctGregorian &,ctGregorian &); inline tyBoolean operator >= (ctGregorian &,ctGregorian &);
inline clOutStream & operator << (clOutStream &,ctGregorian &); function clInStream & operator >> (clInStream &,clGregorian &);
function clGregorian current(void); }
namespace private_area { testing_mode ( function void autoTest(void); function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erInvalidAbsoluteDay; /* Invalid absolute day number. */ /*ERROR*/ extern_error erInvalidDateString; /* Invalid date string. */ /*ERROR*/ extern_error erInvalidHour; /* Invalid hour number. */ /*ERROR*/ extern_error erInvalidHundredth; /* Invalid hundredth number. */ /*ERROR*/ extern_error erInvalidMinute; /* Invalid minute number. */ /*ERROR*/ extern_error erInvalidMonth; /* Invalid month number. */ /*ERROR*/ extern_error erInvalidMonthDay; /* Invalid month day number. */ /*ERROR*/ extern_error erInvalidSecond; /* Invalid second number. */ /*ERROR*/ extern_error erInvalidTimeString; /* Invalid time string. */ /*ERROR*/ extern_error erInvalidWeekDay; /* Invalid week day number. */ /*ERROR*/ extern_error erInvalidYear; /* Invalid year number. */
/*ERROR*/ extern_error erTimeZoneParameterMissing; /* The <CODE>time_zone</CODE> parameter is missing in the initialization file. */ }
// Constants & Variables //------------------------------------------------------------------------- /*CONSTANT*/ /* Week day of the 1/1/1. */ extern_static_constant(public,tyWeekDay,goFirstWeekDay,firstWeekDay);
/*CONSTANT*/ /* Current time zone. */ extern_static_constant(public,tyInteger,goTimeZone,timeZone);
/*CONSTANT*/ /* String indicating the current time zone. */ extern_static_constant(public,tyString,goTimeZoneString,timeZoneString);
/*CONSTANT*/ /* Number of hours per day. */ extern_static_constant(public,tyInteger,goHourPerDay,hourPerDay);
/*CONSTANT*/ /* Number of minutes per day. */ extern_static_constant(public,tyInteger,goMinutePerDay,minutePerDay);
/*CONSTANT*/ /* Number of seconds per day. */ extern_static_constant(public,tyInteger,goSecondPerDay,secondPerDay);
/*CONSTANT*/ /* Number of hundredths per second. */ extern_static_constant(public,tyInteger,goHundredthPerSecond,hundredthPerSecond);
/*CONSTANT*/ /* Number of hundredths per minute. */ extern_static_constant(public,tyInteger,goHundredthPerMinute,hundredthPerMinute);
/*CONSTANT*/ /* Number of hundredths per hour. */ extern_static_constant(public,tyInteger,goHundredthPerHour,hundredthPerHour);
/*CONSTANT*/ /* Number of hundredths per day. */ extern_static_constant(public,tyInteger,goHundredthPerDay,hundredthPerDay);
extern_dynamic_constant(private,clString,goDataLocation,?);
extern_static_constant(private,tyInteger,goMonthLengthS[13][2],?); extern_static_constant(private,tcString,goMonthNameS[13],?); extern_static_constant(private,tyInteger,goNbDaySinceNewYearS[13][2],?); extern_static_constant(private,tcString,goWeekDayNameS[8],?);
// G r e g o r i a n Interface //------------------------------------------------------------------ namespace public_area { /*CLASS clGregorian */ /* Represents a date-and-time in the Gregorian calendar. */ class clGregorian { //-----------------------------------------------------------------------------------------Private private_property void computeAbsoluteDay(void); private_property void computeAbsoluteHundredth(void);
private_property void computeDate(void); private_property void computeTime(void);
private_property void update(tyInteger,tyInteger); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clGregorian */ /* Absolute day number (from 1 to +oo). */ read_only_attribute(tyInteger,atAbsoluteDay,absoluteDay);
/*ATTRIBUTE clGregorian */ /* Absolute hundreth number in the day (from 0 to 8,639,999). */ read_only_attribute(tyInteger,atAbsoluteHundredth,absoluteHundredth);
/*ATTRIBUTE clGregorian */ /* Year number (from 1 to +oo). */ read_only_attribute(tyInteger,atYear,year);
/*ATTRIBUTE clGregorian */ /* Month of the year (from 1 to 12). */ read_only_attribute(tyMonth,atMonth,month);
/*ATTRIBUTE clGregorian */ /* Day of the month (from 1 to 31). */ read_only_attribute(tyInteger,atMonthDay,monthDay);
/*ATTRIBUTE clGregorian */ /* Hour of the day (from 0 to 23). */ read_only_attribute(tyInteger,atHour,hour);
/*ATTRIBUTE clGregorian */ /* Minute of the hour (from 0 to 59). */ read_only_attribute(tyInteger,atMinute,minute);
/*ATTRIBUTE clGregorian */ /* Second of the minute (from 0 to 59). */ read_only_attribute(tyInteger,atSecond,second);
/*ATTRIBUTE clGregorian */ /* Hundredth of the second (from 0 to 99). */ read_only_attribute(tyInteger,atHundredth,hundredth);
public_property tyInteger yearDay(void) const; public_property tyWeekDay weekDay(void) const;
public_property tyYearKind yearKind(void) const;
public_property constructor clGregorian(tyInteger=1,tyMonth=january,tyInteger=1, tyInteger=0,tyInteger=0,tyInteger=0,tyInteger=0);
public_property constructor clGregorian(ctGregorian &); public_property destructor clGregorian(void);
public_property clGregorian & operator = (ctGregorian &);
public_property clString date(tyDateFormat=monthFirstShortDate,tyBoolean=true) const; public_property clString time(tyTimeFormat=militaryShortTime) const;
public_property clString dateAndTime(tyDateFormat=monthFirstShortDate, tyTimeFormat=militaryShortTime,tyBoolean=true) const;
public_property void addYears(tyInteger); public_property void addMonths(tyInteger); public_property void addDays(tyInteger); public_property void addHours(tyInteger); public_property void addMinutes(tyInteger); public_property void addSeconds(tyInteger); public_property void addHundredths(tyInteger);
public_property void setYear(tyInteger); public_property void setMonth(tyInteger); public_property void setYearDay(tyInteger); public_property void setMonthDay(tyInteger); public_property void setWeekDay(tyInteger); public_property void setHour(tyInteger); public_property void setMinute(tyInteger); public_property void setSecond(tyInteger); public_property void setHundredth(tyInteger);
public_property void setDate(tyInteger=1,tyMonth=january,tyInteger=1); public_property void setDate(tcString); public_property void setTime(tyInteger=0,tyInteger=0,tyInteger=0,tyInteger=0); public_property void setTime(tcString); }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area { //--------------------------------------------------------------------------------------MonthLength /*FUNCTION*/ /* Returns the number of days in a month. */ inline tyInteger monthLength(tyMonth agMonth,tyYearKind agYearKind) { if (not (agMonth>=1 and agMonth<=12)) send_inline_error(erInvalidMonth,"monthLength"); return (private_area::goMonthLengthS[agMonth][agYearKind]); } //----------------------------------------------------------------------------------------MonthName /*FUNCTION*/ /* Returns the name of a month. */ inline tcString monthName(tyMonth agMonth) { if (not (agMonth>=1 and agMonth<=12)) send_inline_error(erInvalidMonth,"monthName"); return (private_area::goMonthNameS[agMonth]); } //--------------------------------------------------------------------------------NbDaySinceNewYear /*FUNCTION*/ /* Returns the number of days elapsed from the 1st of January to the 1st of a given month, according to a kind of year (leap or not). */ inline tyInteger nbDaySinceNewYear(tyMonth agMonth,tyYearKind agYearKind) { if (not (agMonth>=1 and agMonth<=12)) send_inline_error(erInvalidMonth,"nbDaysSinceNewYear"); return (private_area::goNbDaySinceNewYearS[agMonth][agYearKind]); } //--------------------------------------------------------------------------------------WeekDayName /*FUNCTION*/ /* Returns the name of a week day. */ inline tcString weekDayName(tyWeekDay agWeekDay) { if (not (agWeekDay>=1 and agWeekDay<=7)) send_inline_error(erInvalidWeekDay,"weekDayName"); return (private_area::goWeekDayNameS[agWeekDay]); } //--------------------------------------------------------------------------------------Operator == /*FUNCTION*/ /* Checks if two calendars are equal. */ inline tyBoolean operator == (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (agCalendar1.absoluteDay()==agCalendar2.absoluteDay() and agCalendar1.absoluteHundredth()==agCalendar2.absoluteHundredth()); } //---------------------------------------------------------------------------------------Operator < /*FUNCTION*/ /* Checks if a calendar is before another one. */ inline tyBoolean operator < (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (agCalendar1.absoluteDay()<agCalendar2.absoluteDay() or (agCalendar1.absoluteDay()==agCalendar2.absoluteDay() and agCalendar1.absoluteHundredth()<agCalendar2.absoluteHundredth())); } //--------------------------------------------------------------------------------------Operator != /*FUNCTION*/ /* Checks if two calendars are different. */ inline tyBoolean operator != (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (not (agCalendar1==agCalendar2)); } //---------------------------------------------------------------------------------------Operator > /*FUNCTION*/ /* Checks if a calendar is after another one. */ inline tyBoolean operator > (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (agCalendar2<agCalendar1); } //--------------------------------------------------------------------------------------Operator <= /*FUNCTION*/ /* Checks if a calendar is before or equal to another one. */ inline tyBoolean operator <= (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (not (agCalendar2<agCalendar1)); } //--------------------------------------------------------------------------------------Operator >= /*FUNCTION*/ /* Checks if a calendar is after or equal to another one. */ inline tyBoolean operator >= (ctGregorian & agCalendar1,ctGregorian & agCalendar2) { return (not (agCalendar1<agCalendar2)); } //--------------------------------------------------------------------------------------Operator << /*FUNCTION*/ /* Writes a calendar into a stream. */ inline clOutStream & operator << (clOutStream & agStream,ctGregorian & agCalendar) { agStream << agCalendar.dateAndTime(monthFirstShortDate,militaryLongTime,false); if (agStream.fail()) send_inline_error(erStreamWriting,"gregorian::operator <<"); return (agStream); } }
namespace private_area {}
// C a l e n d a r Inline //----------------------------------------------------------------------- namespace public_area { //-----------------------------------------------------------------------------------------YearKind /*METHOD clGregorian */ /* Returns the kind of the year (leap or not). */ inline tyYearKind clGregorian::yearKind(void) const { if (atYear%400==0) return (leapYear); if (atYear%4==0 and not (atYear%100==0)) return (leapYear); return (normalYear); } //-------------------------------------------------------------------------------ComputeAbsoluteDay inline void clGregorian::computeAbsoluteDay(void) { tyInteger lcPreviousYear = atYear-1;
atAbsoluteDay = atMonthDay + nbDaySinceNewYear(atMonth,yearKind()) + lcPreviousYear*365 + lcPreviousYear/4 - lcPreviousYear/100 + lcPreviousYear/400; } //-------------------------------------------------------------------------ComputeAbsoluteHundredth inline void clGregorian::computeAbsoluteHundredth(void) { atAbsoluteHundredth = ((atHour*60 + atMinute)*60 + atSecond)*100 + atHundredth; } //-------------------------------------------------------------------------------------------Update inline void clGregorian::update(tyInteger agDays,tyInteger agHundredths) { tyInteger lcOldDay = atAbsoluteDay;
atAbsoluteDay += agDays + agHundredths/hundredthPerDay() - (agHundredths<0); if (atAbsoluteDay<1) send_inline_error(erInvalidAbsoluteDay,"gregorian::update"); if (atAbsoluteDay!=lcOldDay) computeDate();
atAbsoluteHundredth=(hundredthPerDay()+agHundredths)%hundredthPerDay(); computeTime(); } //---------------------------------------------------------------------------------------Destructor /*METHOD clGregorian */ /* Destructs the calendar. */ inline clGregorian::~clGregorian(void) {} //------------------------------------------------------------------------------------------YearDay /*METHOD clGregorian */ /* Returns the day of the year (from 1 to 366). */ inline tyInteger clGregorian::yearDay(void) const { tyYearKind lcYearKind = yearKind();
return (nbDaySinceNewYear(atMonth,lcYearKind) + atMonthDay); } //------------------------------------------------------------------------------------------WeekDay /*METHOD clGregorian */ /* Returns the day of the week (from 1 = Sunday to 7 = Saturday). */ inline tyWeekDay clGregorian::weekDay(void) const { return (tyWeekDay((atAbsoluteDay+private_area::firstWeekDay()-2)%7 + 1)); } //------------------------------------------------------------------------------------------SetYear /*METHOD clGregorian */ /* Sets the year. */ inline void clGregorian::setYear(tyInteger agNumber) { if (agNumber<1) send_inline_error(erInvalidYear,"gregorian::setYear"); addYears(agNumber-atYear); } //-----------------------------------------------------------------------------------------SetMonth /*METHOD clGregorian */ /* Sets the month. */ inline void clGregorian::setMonth(tyInteger agNumber) { if (agNumber<1 or agNumber>12) send_inline_error(erInvalidMonth,"gregorian::setMonth"); addMonths(agNumber-atMonth); } //---------------------------------------------------------------------------------------SetYearDay /*METHOD clGregorian */ /* Sets the day of the year. */ inline void clGregorian::setYearDay(tyInteger agNumber) { if (agNumber<1 or agNumber>(yearKind()==leapYear ? 366 : 365)) send_inline_error(erInvalidYear,"gregorian::setYearDay");
addDays(agNumber-yearDay()); } //--------------------------------------------------------------------------------------SetMonthDay /*METHOD clGregorian */ /* Sets the day of the month. */ inline void clGregorian::setMonthDay(tyInteger agNumber) { if (agNumber<1 or agNumber>monthLength(atMonth,yearKind())) send_inline_error(erInvalidMonthDay,"gregorian::setMonthDay");
addDays(agNumber-atMonthDay); } //---------------------------------------------------------------------------------------SetWeekDay /*METHOD clGregorian */ /* Sets the day of the week. */ inline void clGregorian::setWeekDay(tyInteger agNumber) { if (agNumber<1 or agNumber>7) send_inline_error(erInvalidWeekDay,"gregorian::setWeekDay"); addDays(agNumber-weekDay()); } //------------------------------------------------------------------------------------------SetHour /*METHOD clGregorian */ /* Sets the hour. */ inline void clGregorian::setHour(tyInteger agNumber) { if (agNumber<0 or agNumber>23) send_inline_error(erInvalidHour,"gregorian::setHour"); atAbsoluteHundredth+=(agNumber-atHour)*hundredthPerHour(); atHour=agNumber; } //----------------------------------------------------------------------------------------SetMinute /*METHOD clGregorian */ /* Sets the minute. */ inline void clGregorian::setMinute(tyInteger agNumber) { if (agNumber<0 or agNumber>59) send_inline_error(erInvalidMinute,"gregorian::setMinute"); atAbsoluteHundredth+=(agNumber-atMinute)*hundredthPerMinute(); atMinute=agNumber; } //----------------------------------------------------------------------------------------SetSecond /*METHOD clGregorian */ /* Sets the second. */ inline void clGregorian::setSecond(tyInteger agNumber) { if (agNumber<0 or agNumber>59) send_inline_error(erInvalidSecond,"gregorian::setSecond"); atAbsoluteHundredth+=(agNumber-atSecond)*hundredthPerSecond(); atSecond=agNumber; } //-------------------------------------------------------------------------------------SetHundredth /*METHOD clGregorian */ /* Sets the hundredth. */ inline void clGregorian::setHundredth(tyInteger agNumber) { if (agNumber<0 or agNumber>99) send_inline_error(erInvalidHundredth,"gregorian::setHundredth"); atAbsoluteHundredth+=(agNumber-atHundredth); atHundredth=agNumber; } }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #endif |
//================================================================================================== // C a l e n d a r Implementation // G r e g o r i a n // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "calendar/gregorian.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define CALENDAR_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/calendar/gregorian.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area calendarGregorian #define private_area calendarGregorian_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Calendar/Gregorian");
// Initialization //-------------------------------------------------------------------------------- #undef iniCalendarGregorian static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erInvalidAbsoluteDay; static_error erInvalidDateString; static_error erInvalidHour; static_error erInvalidHundredth; static_error erInvalidMinute; static_error erInvalidMonth; static_error erInvalidMonthDay; static_error erInvalidSecond; static_error erInvalidTimeString; static_error erInvalidWeekDay; static_error erInvalidYear; static_error erTimeZoneParameterMissing; }
// Constants & Variables //------------------------------------------------------------------------- static_constant(tyWeekDay,goFirstWeekDay); static_constant(tyInteger,goTimeZone); static_constant(tyString,goTimeZoneString);
static_constant(tyInteger,goHourPerDay); static_constant(tyInteger,goMinutePerDay); static_constant(tyInteger,goSecondPerDay);
static_constant(tyInteger,goHundredthPerSecond); static_constant(tyInteger,goHundredthPerMinute); static_constant(tyInteger,goHundredthPerHour); static_constant(tyInteger,goHundredthPerDay);
dynamic_constant(clString,goDataLocation);
static_constant(tyInteger,goMonthLengthS[13][2]); static_constant(tcString,goMonthNameS[13]); static_constant(tyInteger,goNbDaySinceNewYearS[13][2]); static_constant(tcString,goWeekDayNameS[8]);
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Operator >> /*FUNCTION*/ /* Reads a calendar from a stream. */ function clInStream & operator >> (clInStream & agStream,clGregorian & agCalendar) { method_name("gregorian::operator >>");
clString lcString;
agStream >> lcString; agCalendar.setDate(lcString.data()); agStream >> lcString; agCalendar.setTime(lcString.data());
if (agStream.fail()) send_error(erStreamReading); return (agStream); } //------------------------------------------------------------------------------------------Current /*FUNCTION*/ /* Returns the current date-and-time. */ function clGregorian current(void) { clGregorian lcCurrent(1970,january,1,0,0,0,0);
lcCurrent.addSeconds(time(nil)); lcCurrent.addHours(timeZone()); return (lcCurrent); } }
namespace private_area {}
// G r e g o r i a n Implementation //------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------ComputeDate property void clGregorian::computeDate(void) { tyInteger lcTempoDay; tyInteger lcYearDay; tyYearKind lcYearKind;
// Year and day of the year // atYear=tyInteger(tyReal(atAbsoluteDay)/365.2425); lcYearDay=atAbsoluteDay-(365*atYear + atYear/4 - atYear/100 + atYear/400);
if (lcYearDay>365) { atYear++; lcTempoDay=atAbsoluteDay-(365*atYear + atYear/4 - atYear/100 + atYear/400);
if (lcTempoDay>0) { lcYearDay=lcTempoDay; atYear++; } } else { if (lcYearDay<1) { atYear--; lcYearDay=atAbsoluteDay-(365*atYear + atYear/4 - atYear/100 + atYear/400); }
atYear++; }
// Month and day of the month // lcYearKind=yearKind(); atMonth=tyMonth(lcYearDay/32 + 1);
atMonthDay=lcYearDay-nbDaySinceNewYear(atMonth,lcYearKind);
if (atMonthDay>monthLength(atMonth,lcYearKind)) { atMonthDay-=monthLength(atMonth,lcYearKind); nextSymbol(atMonth); } } //--------------------------------------------------------------------------------------ComputeTime property void clGregorian::computeTime(void) { tyInteger lcNbHundredth = atAbsoluteHundredth;
atHour=lcNbHundredth/hundredthPerHour(); lcNbHundredth%=hundredthPerHour(); atMinute=lcNbHundredth/hundredthPerMinute(); lcNbHundredth%=hundredthPerMinute(); atSecond=lcNbHundredth/hundredthPerSecond(); atHundredth=lcNbHundredth%hundredthPerSecond(); } //--------------------------------------------------------------------------------------Constructor /*METHOD clGregorian */ /* Builds a calendar from separated information. */ property clGregorian::clGregorian(tyInteger agYear,tyMonth agMonth,tyInteger agMonthDay, tyInteger agHour,tyInteger agMinute,tyInteger agSecond, tyInteger agHundredth) : atYear(),atMonth(january),atMonthDay(),atHour(),atMinute(),atSecond(),atHundredth() { setDate(agYear,agMonth,agMonthDay); setTime(agHour,agMinute,agSecond,agHundredth); } //--------------------------------------------------------------------------------------Constructor /*METHOD clGregorian */ /* Builds a calendar from another one. */ property clGregorian::clGregorian(ctGregorian & agCalendar) : atAbsoluteDay(agCalendar.atAbsoluteDay),atAbsoluteHundredth(agCalendar.atAbsoluteHundredth), atYear(agCalendar.atYear),atMonth(agCalendar.atMonth),atMonthDay(agCalendar.atMonthDay), atHour(agCalendar.atHour),atMinute(agCalendar.atMinute),atSecond(agCalendar.atSecond), atHundredth(agCalendar.atHundredth) {} //---------------------------------------------------------------------------------------Operator = /*METHOD clGregorian */ /* Copies a calendar. */ property clGregorian & clGregorian::operator = (ctGregorian & agCalendar) { atAbsoluteDay=agCalendar.atAbsoluteDay; atAbsoluteHundredth=agCalendar.atAbsoluteHundredth;
atYear=agCalendar.atYear; atMonth=agCalendar.atMonth; atMonthDay=agCalendar.atMonthDay;
atHour=agCalendar.atHour; atMinute=agCalendar.atMinute; atSecond=agCalendar.atSecond; atHundredth=agCalendar.atHundredth;
return (*this); } //-----------------------------------------------------------------------------------------AddYears /*METHOD clGregorian */ /* Add years to the calendar. */ property void clGregorian::addYears(tyInteger agNumber) { method_name("gregorian::addYears");
atYear+=agNumber; if (atYear<1) send_error(erInvalidYear); computeAbsoluteDay(); } //----------------------------------------------------------------------------------------AddMonths /*METHOD clGregorian */ /* Add months to the calendar. */ property void clGregorian::addMonths(tyInteger agNumber) { method_name("gregorian::addMonths");
tyInteger lcMonth = tyInteger(atMonth)-1+agNumber%12;
atYear+=agNumber/12+lcMonth/12-(lcMonth<0); atMonth=tyMonth((12+lcMonth)%12 + 1); if (atYear<1) send_error(erInvalidYear); computeAbsoluteDay(); } //------------------------------------------------------------------------------------------AddDays /*METHOD clGregorian */ /* Add days to the calendar. */ property void clGregorian::addDays(tyInteger agNumber) { method_name("gregorian::addDays");
atAbsoluteDay+=agNumber; if (atAbsoluteDay<1) send_error(erInvalidAbsoluteDay); computeDate(); } //-----------------------------------------------------------------------------------------AddHours /*METHOD clGregorian */ /* Add hours to the calendar. */ property void clGregorian::addHours(tyInteger agNumber) { tyInteger lcDays = agNumber/hourPerDay();
update(lcDays,atAbsoluteHundredth+(agNumber-lcDays*hourPerDay())*hundredthPerHour()); } //---------------------------------------------------------------------------------------AddMinutes /*METHOD clGregorian */ /* Add minutes to the calendar. */ property void clGregorian::addMinutes(tyInteger agNumber) { tyInteger lcDays = agNumber/minutePerDay();
update(lcDays,atAbsoluteHundredth+(agNumber-lcDays*minutePerDay())*hundredthPerMinute()); } //---------------------------------------------------------------------------------------AddSeconds /*METHOD clGregorian */ /* Add seconds to the calendar. */ property void clGregorian::addSeconds(tyInteger agNumber) { tyInteger lcDays = agNumber/secondPerDay();
update(lcDays,atAbsoluteHundredth+(agNumber-lcDays*secondPerDay())*hundredthPerSecond()); } //------------------------------------------------------------------------------------AddHundredths /*METHOD clGregorian */ /* Add hundredths to the calendar. */ property void clGregorian::addHundredths(tyInteger agNumber) { tyInteger lcDays = agNumber/hundredthPerDay();
update(lcDays,atAbsoluteHundredth+(agNumber-lcDays*hundredthPerDay())); } //------------------------------------------------------------------------------------------SetDate /*METHOD clGregorian */ /* Sets the date from separated information. */ property void clGregorian::setDate(tyInteger agYear,tyMonth agMonth,tyInteger agMonthDay) { method_name("gregorian::setDate");
if (agYear<1) send_error(erInvalidYear); atYear=agYear;
if (agMonth<1 or agMonth>12) send_error(erInvalidMonth); atMonth=agMonth;
if (agMonthDay<1 or agMonthDay>monthLength(agMonth,yearKind())) send_error(erInvalidMonthDay); atMonthDay=agMonthDay;
computeAbsoluteDay(); } //------------------------------------------------------------------------------------------SetDate /*METHOD clGregorian */ /* Sets the date from a string. */ property void clGregorian::setDate(tcString agString) { method_name("gregorian::setDate");
tyString lcString = new_array(tyCharacter,size(agString)+1); tcString lcBuffer = lcString;
tyInteger lcMonth; tyInteger lcMonthDay; tyInteger lcYear;
copy(lcString,agString); replace(lcString,'/',' '); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcMonth); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcMonthDay); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcYear);
delete_array(lcString); if (lcBuffer==nil) send_error(erInvalidDateString); setDate(lcYear,tyMonth(lcMonth),lcMonthDay); } //------------------------------------------------------------------------------------------SetTime /*METHOD clGregorian */ /* Sets the time from separated information. */ property void clGregorian::setTime(tyInteger agHour,tyInteger agMinute,tyInteger agSecond, tyInteger agHundredth) { method_name("gregorian::setTime");
if (agHour<0 or agHour>23) send_error(erInvalidHour); if (agMinute<0 or agMinute>59) send_error(erInvalidMinute); if (agSecond<0 or agSecond>59) send_error(erInvalidSecond); if (agHundredth<0 or agHundredth>99) send_error(erInvalidHundredth);
atHour=agHour; atMinute=agMinute; atSecond=agSecond; atHundredth=agHundredth; computeAbsoluteHundredth(); } //------------------------------------------------------------------------------------------SetTime /*METHOD clGregorian */ /* Sets the time from a string. */ property void clGregorian::setTime(tcString agString) { method_name("gregorian::setTime");
tyString lcString = new_array(tyCharacter,size(agString)+1); tcString lcBuffer = lcString;
tyInteger lcHour; tyInteger lcHundredth; tyInteger lcMinute; tyInteger lcSecond;
copy(lcString,agString); replace(lcString,':',' '); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcHour); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcMinute); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcSecond); lcBuffer=bpp::low::string::toInteger(lcBuffer,lcHundredth);
delete_array(lcString); if (lcBuffer==nil) send_error(erInvalidTimeString); setTime(lcHour,lcMinute,lcSecond,lcHundredth); } //---------------------------------------------------------------------------------------------Date /*METHOD clGregorian */ /* Returns a string representing the date in a given format. */ property clString clGregorian::date(tyDateFormat agFormat,tyBoolean agWeekDay) const { tyCharacter lcBuffer[64]; tyCharacter lcString[80];
switch (agFormat) { case dayFirstLongDate: if (agWeekDay) { bpp::low::string::copy(lcString,weekDayName(weekDay())); bpp::low::string::concatenate(lcString,", "); } else bpp::low::string::copy(lcString,"");
bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMonthDay)); bpp::low::string::concatenate(lcString," "); bpp::low::string::concatenate(lcString,monthName(atMonth)); bpp::low::string::concatenate(lcString," "); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atYear));
break;
case dayFirstShortDate: if (agWeekDay) { bpp::low::string::copy(lcString,weekDayName(weekDay())); bpp::low::string::concatenate(lcString,", "); } else bpp::low::string::copy(lcString,"");
bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMonthDay)); bpp::low::string::concatenate(lcString,"/");
bpp::low::string::concatenate(lcString, bpp::low::string::toString(lcBuffer,tyInteger(atMonth)));
bpp::low::string::concatenate(lcString,"/"); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atYear));
break;
case monthFirstLongDate: if (agWeekDay) { bpp::low::string::copy(lcString,weekDayName(weekDay())); bpp::low::string::concatenate(lcString,", "); } else bpp::low::string::copy(lcString,"");
bpp::low::string::concatenate(lcString,monthName(atMonth)); bpp::low::string::concatenate(lcString," "); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMonthDay)); bpp::low::string::concatenate(lcString,", "); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atYear));
break;
default: if (agWeekDay) { bpp::low::string::copy(lcString,weekDayName(weekDay())); bpp::low::string::concatenate(lcString,", "); } else bpp::low::string::copy(lcString,"");
bpp::low::string::concatenate(lcString, bpp::low::string::toString(lcBuffer,tyInteger(atMonth)));
bpp::low::string::concatenate(lcString,"/"); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMonthDay)); bpp::low::string::concatenate(lcString,"/"); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atYear)); }
return (clString(lcString)); } //---------------------------------------------------------------------------------------------Time /*METHOD clGregorian */ /* Returns a string representing the time in a given format. */ property clString clGregorian::time(tyTimeFormat agFormat) const { tyCharacter lcBuffer[64]; tyCharacter lcString[20];
tyInteger lcHour;
switch (agFormat) { case americanLongTime: lcHour=atHour%12; if (lcHour==0) lcHour=12;
bpp::low::string::copy(lcString,(lcHour<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,lcHour)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atMinute<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMinute)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atSecond<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atSecond)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atHundredth<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atHundredth)); bpp::low::string::concatenate(lcString," "); bpp::low::string::concatenate(lcString,(atHour<12 ? "AM" : "PM"));
break;
case americanShortTime: lcHour=atHour%12; if (lcHour==0) lcHour=12;
bpp::low::string::copy(lcString,(lcHour<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,lcHour)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atMinute<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMinute)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atSecond<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atSecond)); bpp::low::string::concatenate(lcString," "); bpp::low::string::concatenate(lcString,(atHour<12 ? "AM" : "PM"));
break;
case militaryLongTime: bpp::low::string::copy(lcString,(atHour<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atHour)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atMinute<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMinute)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atSecond<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atSecond)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atHundredth<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atHundredth));
break;
default: bpp::low::string::copy(lcString,(atHour<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atHour)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atMinute<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atMinute)); bpp::low::string::concatenate(lcString,":"); bpp::low::string::concatenate(lcString,(atSecond<10 ? "0" : "")); bpp::low::string::concatenate(lcString,bpp::low::string::toString(lcBuffer,atSecond)); }
return (clString(lcString)); } //--------------------------------------------------------------------------------------DateAndTime /*METHOD clGregorian */ /* Returns a string representing the date-and-time in a given format. */ property clString clGregorian::dateAndTime(tyDateFormat agDateFormat,tyTimeFormat agTimeFormat, tyBoolean agWeekDay) const { tyCharacter lcString[100];
bpp::low::string::copy(lcString,date(agDateFormat,agWeekDay).data()); bpp::low::string::concatenate(lcString,", "); bpp::low::string::concatenate(lcString,time(agTimeFormat).data());
return (clString(lcString)); } }
namespace private_area {}
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { tyCardinal lcMonth;
if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
method_name("initializer::constructor");
tyCharacter lcBuffer[64];
erInvalidAbsoluteDay.create("Gregorian Calendar - Invalid absolute day number."); erInvalidDateString.create("Gregorian Calendar - Invalid date string."); erInvalidHour.create("Gregorian Calendar - Invalid hour number."); erInvalidHundredth.create("Gregorian Calendar - Invalid hundredth number."); erInvalidMinute.create("Gregorian Calendar - Invalid minute number."); erInvalidMonth.create("Gregorian Calendar - Invalid month number."); erInvalidMonthDay.create("Gregorian Calendar - Invalid month day number."); erInvalidSecond.create("Gregorian Calendar - Invalid second number."); erInvalidTimeString.create("Gregorian Calendar - Invalid time string."); erInvalidWeekDay.create("Gregorian Calendar - Invalid week day number."); erInvalidYear.create("Gregorian Calendar - Invalid year number."); erTimeZoneParameterMissing.create("The 'time_zone' parameter is missing.");
if (environment::parameters().count(clString("time_zone"))==0) send_error(erTimeZoneParameterMissing);
goFirstWeekDay = monday; goTimeZone = integer(environment::parameter(clString("time_zone")).data()); goTimeZoneString = new_array(tyCharacter,20);
if (goTimeZone==0) bpp::low::string::copy(goTimeZoneString,"GMT"); else if (goTimeZone<0) { bpp::low::string::copy(goTimeZoneString,"GMT ");
bpp::low::string::concatenate(goTimeZoneString, bpp::low::string::toString(lcBuffer,goTimeZone)); } else { bpp::low::string::copy(goTimeZoneString,"GMT +");
bpp::low::string::concatenate(goTimeZoneString, bpp::low::string::toString(lcBuffer,goTimeZone)); }
goHourPerDay = 24; goMinutePerDay = goHourPerDay*60; goSecondPerDay = goMinutePerDay*60;
goHundredthPerSecond = 100; goHundredthPerMinute = goHundredthPerSecond*60; goHundredthPerHour = goHundredthPerMinute*60; goHundredthPerDay = goHundredthPerHour*24;
goDataLocation = new_object(clString(environment::dataLocation()+fileNameSeparator()+"calendar" +fileNameSeparator()+"gregorian"));
goMonthLengthS[january][normalYear] = 31; goMonthLengthS[february][normalYear] = 28; goMonthLengthS[march][normalYear] = 31; goMonthLengthS[april][normalYear] = 30; goMonthLengthS[may][normalYear] = 31; goMonthLengthS[june][normalYear] = 30; goMonthLengthS[july][normalYear] = 31; goMonthLengthS[august][normalYear] = 31; goMonthLengthS[september][normalYear] = 30; goMonthLengthS[october][normalYear] = 31; goMonthLengthS[november][normalYear] = 30; goMonthLengthS[december][normalYear] = 31;
goMonthLengthS[january][leapYear] = 31; goMonthLengthS[february][leapYear] = 29; goMonthLengthS[march][leapYear] = 31; goMonthLengthS[april][leapYear] = 30; goMonthLengthS[may][leapYear] = 31; goMonthLengthS[june][leapYear] = 30; goMonthLengthS[july][leapYear] = 31; goMonthLengthS[august][leapYear] = 31; goMonthLengthS[september][leapYear] = 30; goMonthLengthS[october][leapYear] = 31; goMonthLengthS[november][leapYear] = 30; goMonthLengthS[december][leapYear] = 31;
goMonthNameS[january] = "January"; goMonthNameS[february] = "February"; goMonthNameS[march] = "March"; goMonthNameS[april] = "April"; goMonthNameS[may] = "May"; goMonthNameS[june] = "June"; goMonthNameS[july] = "July"; goMonthNameS[august] = "August"; goMonthNameS[september] = "September"; goMonthNameS[october] = "October"; goMonthNameS[november] = "November"; goMonthNameS[december] = "December";
lcMonth=january; goNbDaySinceNewYearS[january][normalYear]=0; goNbDaySinceNewYearS[january][leapYear]=0;
while (lcMonth<december) { goNbDaySinceNewYearS[lcMonth+1][normalYear]=goNbDaySinceNewYearS[lcMonth][normalYear] + goMonthLengthS[lcMonth][normalYear];
goNbDaySinceNewYearS[lcMonth+1][leapYear]=goNbDaySinceNewYearS[lcMonth][leapYear] + goMonthLengthS[lcMonth][leapYear]; lcMonth++; }
goWeekDayNameS[sunday] = "Sunday"; goWeekDayNameS[monday] = "Monday"; goWeekDayNameS[tuesday] = "Tuesday"; goWeekDayNameS[wednesday] = "Wednesday"; goWeekDayNameS[thursday] = "Thursday"; goWeekDayNameS[friday] = "Friday"; goWeekDayNameS[saturday] = "Saturday";
bpp::low::string::copy(environment_private::goStartingDate,current().dateAndTime().data()); environment_private::goTerminationDate[0]=end_string; }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { try { environment::informTermination(goModuleName);
bpp::low::string::copy(environment_private::goTerminationDate,current().dateAndTime().data());
delete_array(goTimeZoneString); delete_object(goDataLocation); }
initializer_catch; } }
// End //------------------------------------------------------------------------------------------- } |
|