Partial Date/Time Utility: Expand Partial Date/Time to Calendar Year at Date_Time
Phil Weinstein, CADSWES, RiverWare 6.1, edit 7-18-2011

Added PartialDateTime function:

void PartialDateTimeEncoder::expandToCalendarYearAtDateTime (
                                                Date_Time& resultFullDT,
                                                const Date_Time& refDT) const

Implementation (in Utils/PartialDateTimeEncoder.cpp):

// Expand this encoded partial date/time to a Date_Time in the calendar
// year of the given reference Date_Time.  This is done by constructing
// a full Date_Time from the defined partial date/time "parts" plus the
// other parts from the reference date/time (with adjustments made for
// different-sized months).
//
// FOR EXAMPLE:
//  This partial dt: March 12
//  Ref date/time:   July  23, 2009, 6:30 am
//  Result:          March 12, 2009, 6:30 am
//
//  This partial dt: 31st day of the month
//  Ref date/time:   February 14, 2008, 9:20 pm  (a leap year)
//  Result:          Feburary 29, 2008, 9:20 pm  (day clipped to end of Feb)
//
//--
 
void PartialDateTimeEncoder::expandToCalendarYearAtDateTime (
                                                Date_Time& resultFullDT,
                                                const Date_Time& refDT) const
{
   // First check if this partial date/time is "absolute". If so, just
   // return its Date_Time. (The given Reference Date_Time is not used).
   //
   if (_negPartBits == PartialDateTime::NegPartBits_Absolute)
   {
      resultFullDT = _dtime;
      return; //---------->>
   }
 
   // Compute the result date/time parts from the defined partial date/time
   // "parts" and (for the other parts) the Reference Date_Time parts.
   //
   int resYear = showYear()  ?_dtime.get_year()  :refDT.get_year();
   int resMon1 = showMonth() ?_dtime.get_month() :refDT.get_month(); // [1..12]
   int resMDay = showDay()   ?_dtime.get_mday()  :refDT.get_mday();  // [1..31]
   int resHour = showHour()  ?_dtime.get_hour()  :refDT.get_hour();
   int resMin  = showMins()  ?_dtime.get_min()   :refDT.get_min();
   int resSec  = showSecs()  ?_dtime.get_sec()   :refDT.get_sec();
 
   // Fixup month day, considering the length of the result month.
   const int monthDays = Date_Time::daysInMonth (resYear, resMon1); // [1..12]
   resMDay = std::min (resMDay, monthDays);
 
   resultFullDT.setTime (resYear, resMon1, resMDay, resHour, resMin, resSec);
}

Test:

static void testPartialDateTimeExpand()
{
   static const char* mname ("WorkspaceTest.cpp testPartialDateTimeExpand");
 
   // Test for PartialDateTimeEncoder::expandToCalendarYearAtDateTime
   // For RiverWare 6.1 / July 2011 / Phil Weinstein
 
   //====================================
   // Expected Results:
   //
   //   TEST 1:
   //     Partial DT: March 12
   //     Ref DT    : 07-23-2009 06:30:00
   //     Result DT : 03-12-2009 06:30:00
   //
   //   TEST 2:
   //     Partial DT: 31st
   //     Ref DT    : 02-14-2008 21:20:00    // (a leap year)
   //     Result DT : 02-29-2008 21:20:00    // (day clipped to end of Feb)
   //====================================
 
   // *********************************************
   // ***  (1) Create Partial Date/Time Values  ***
   // *********************************************
 
   PartialDateTimeEncoder pdt1;    // *** March 12 ***
   pdt1.setDateParts (false,  0,   // bool setYear,   int inpYear,
                      true,   3,   // bool setMonth,  int inpMonth1,
                      true,  12,   // bool setDay,    int inpDay,
                      false,  0,   // bool setHour,   int inpHour,
                      false,  0,   // bool setMinute, int inpMinute,
                      false,  0,   // bool setSecond, int inpSecond,
                      true);       // bool setScopeFromGivenParts
 
   PartialDateTimeEncoder pdt2;    // *** 31st Day of the Month ***
   pdt2.setDateParts (false,  0,   // bool setYear,   int inpYear,
                      false,  0,   // bool setMonth,  int inpMonth1,
                      true,  31,   // bool setDay,    int inpDay,
                      false,  0,   // bool setHour,   int inpHour,
                      false,  0,   // bool setMinute, int inpMinute,
                      false,  0,   // bool setSecond, int inpSecond,
                      true);       // bool setScopeFromGivenParts
 
   const double partialDtVal1 = pdt1.encode();
   const double partialDtVal2 = pdt2.encode();
 
   // *************************************************
   // ***  (2) Test expandToCalendarYearAtDateTime  ***
   // *************************************************
 
   PartialDateTimeEncoder pdt1b (partialDtVal1);
   PartialDateTimeEncoder pdt2b (partialDtVal2);
 
   Date_Time refDT1;
   Date_Time refDT2;
   refDT1 .setTime (2009, 7, 23,  6, 30, 0);  // July 23, 2009, 6:30 am
   refDT2 .setTime (2008, 2, 14, 21, 20, 0);  // Feb  14, 2008, 9:20 pm
 
   Date_Time resultDT1;
   Date_Time resultDT2;
   pdt1b .expandToCalendarYearAtDateTime (resultDT1, refDT1);  // *** TEST
   pdt2b .expandToCalendarYearAtDateTime (resultDT2, refDT2);  // *** TEST
 
   // ****************************
   // ***  (3) Report Results  ***
   // ****************************
 
   QString pdt1bStr; (void) pdt1b.getStr (pdt1bStr);
   QString pdt2bStr; (void) pdt2b.getStr (pdt2bStr);
 
   const QString refDT1Str    = refDT1.userFormat();
   const QString refDT2Str    = refDT2.userFormat();
   const QString resultDT1Str = resultDT1.userFormat();
   const QString resultDT2Str = resultDT2.userFormat();
 
   std::cout << mname << " TEST 1"
             << "\n  Partial DT: " << qPrintable (pdt1bStr)
             << "\n  Ref DT    : " << qPrintable (refDT1Str)
             << "\n  Result DT : " << qPrintable (resultDT1Str)
             << "\n" << std::endl;
 
   std::cout << mname << " TEST 2"
             << "\n  Partial DT: " << qPrintable (pdt2bStr)
             << "\n  Ref DT    : " << qPrintable (refDT2Str)
             << "\n  Result DT : " << qPrintable (resultDT2Str)
             << "\n" << std::endl;

--- (end) ---