[MFC] Cate zile are luna?

Despre MFC, ATL si alte biblioteci C++ de la Microsoft (forum moderat)
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi

[MFC] Cate zile are luna?

Post by Ovidiu Cucu » 26 Aug 2007, 23:25

Problema
Avand un obiect tip CTime sau COleDateTime, cum aflu numarul de zile din luna incapsulata in acel obiect?


Rezolvare (1)
Se stie foarte bine ca lunile 1, 3, 5, 7, 8, 10 si 12 au cate 31 zile iar lunile 4, 6, 9 si 11 au cate 30.
Ramane luna 2 (februarie) care are 29 zile daca anul este bisect, respectiv 28 zile daca anul nu este bisect.
Regulile care decid daca un an este bisect sunt urmatoarele:
  1. Daca anul se divide la 4 atunci este bisect (exemplu: anul 2008 este bisect);
  2. Exceptie de la regula 1: daca anul se divide la 100 atunci nu este bisect (exemplu: 1900 nu este bisect);
  3. Exceptie de la regula 2: daca anul se divide prin 400 atunci este bisect (exemplu: 2000 este an bisect).
Aplicand in program regulile enuntate mai sus, un exemplu de implementare ar fi urmatorul

Code: Select all

int CFoo::GetDaysOfMonth(const COleDateTime& odt)
{
   int nDaysOfMonth = 0;
   const int nYear  = odt.GetYear();
   const int nMonth = odt.GetMonth();
   bool bIsLeapYear = ((nYear % 4) == 0)      // rule #1
                    && (((nYear % 100) != 0)  // rule #2
                    || ((nYear % 400) == 0)); // rule #3
   switch(nMonth)
   {
   case 1: case 3: case 5: case 7: case 8: case 10: case 12: 
      nDaysOfMonth = 31;
      break;
   case 4: case 6: case 9: case 11:
      nDaysOfMonth = 30;
      break;
   case 2:
      nDaysOfMonth = bIsLeapYear ? 29 : 28;
      break;
   default:
      ASSERT(FALSE); // invalid month
   }
   return nDaysOfMonth;
}
Rezolvare (2)
Mai simplu, odata ce folosim MFC-ul, este sa punem la treaba MFC-ul.
Concret, folosind CTimeSpan, respectiv COleDateTimeSpan, adaugam 31 zile la data de 1 a lunii. Ziua (din luna urmatoare) rezultata va fi 1, 2, 3, sau 4, daca luna curenta are 31, 30, 29 sau respectiv 28 de zile.
Nu mai ramane decat sa scadem valoarea respectiva din 32 si obtinem rezultatul dorit.

Code: Select all

int CFoo::GetDaysOfMonth(const COleDateTime& odt) 
{ 
   COleDateTime odtNext(odt.GetYear(), odt.GetMonth(), 1, 0, 0, 0); 
   odtNext += COleDateTimeSpan(31, 0, 0, 0); 
   return 32 - odtNext.GetDay();
}
Note
  • In implementarea similara cu CTime/CTimeSpan, pentru ca rezultatul sa fie corect in toate cazurile, trebuie adaugate 31 zile si 1 ora.

    Code: Select all

       // ...
       tNext += CTimeSpan(31, 1, 0, 0); 
       // ...
    
Vezi si

<< Back to MFC index
Last edited by Ovidiu Cucu on 08 Aug 2011, 18:59, edited 5 times in total.
Reason: am adaugat nota



Post Reply