Aymen Derradji
Aymen Derradji

Reputation: 318

Return number of days in a given month of a given year

I wrote a program that, given the month number and the year, returns the number of days in that month:

#include <iostream.h>
#include <conio.h>
void main() {
  clrscr();
  int month, year, i;
  cout << "give the year \n";
  cin >> year;
  cout << "give the month\n";
  cin >> month;
  for (i = 1; i <= 12; i++) {
    i = month;
    switch (month) {
      case 1:
        cout << "number of day in month is 31\n";
        break;
      case 2:
        if (year % 4 == 0) {
          cout << "the number of days is 29 \n";
        } else {
          cout << "the number of days is 28 \n";
        }
        break;
      case 3, 5, 7, 8, 10, 12:
        cout << "the number of days is 31 \n";
        break;
      default:
        cout << "the number of days is 30 \n";
        return;
    }
  }
  return;
}

When I give the month number 3, it returns the number of days is 31, so it works fine. But when I give 1 or 2, the output is

number of day in month is 31
number of day in month is 31
number of day in month is 31
.
.
.
.

How can I make it return only number of day in month is 31 or number of day in month is 28 if the case is 2?

Upvotes: 0

Views: 10384

Answers (6)

Howard Hinnant
Howard Hinnant

Reputation: 218750

C++20-level lazy:

#include <chrono>

int
GetDaysInMonth(int y, int m)
{
    return unsigned{(std::chrono::last/m/y).day()};
}

The expression last/m/y creates a chrono::year_month_day_last object using d/m/y ordering. The member function getter for the day of that year/month combination is called. And then that day is converted to unsigned which implicitly converts to int.

Demo.

Check out that assembly too. It's fast.

Upvotes: 0

AlexDev
AlexDev

Reputation: 4717

Even lazier:

#include <ctime>
static int GetDaysInMonthOfTheDate(std::tm curDate)
{
    std::tm date = curDate;
    date.tm_mday = 0;
    date.tm_mon++;
    mktime(&date);
    return date.tm_mday;
}

Upvotes: 0

tomy
tomy

Reputation: 454

Solution as C++ Class:

struct CwCalendar
{
    static bool leapYear(uint year)
    {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    static uint daysInMonth(uchar month, uint year)
    {
        switch (month) {
        case 2:
        {
            if (leapYear(year)) return 29;
            return 28;
        }
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        {
            return 31;
        }
        default:
            return 30;
        }
    }
};

Build on @Md. Monirul Islam answere which explains leap year calculation.

Unit test against Qt QDate class from year 1 to 3001:

void unittest_CwCalendar()
{
    for (int year = 1; year <= 3001; ++year) {
        for (int month = 1; month <= 12; ++month) {
            int day = CwCalendar::daysInMonth(month, year);
            if (0) day--; // insert error, set day before last day
            if (0) day++; // insert error, set not existing day in month

            QDate d(year,month, day);
            if (!d.isValid() || d.addDays(1).month() == d.month() )
            {
                std::cerr << "Error :: "
                          << "year: " << year
                          << " month: " << month
                          << " day: " << day << '\n';
                std::cerr << std::flush;
                exit(-1);
            }
        }
    }
}

Upvotes: 0

Danil
Danil

Reputation: 895

lazy way:

#include <ctime>
static int GetDaysInMonthOfTheDate(std::tm curDate)
{
    std::tm date = curDate;
    int i = 0;
    for (i = 29; i <= 31; i++)
    {
        date.tm_mday = i;
        mktime(&date);

        if (date1->tm_mon != curDate.tm_mon)
        {
            break;
        }
    }
    return i - 1;    
}

Upvotes: 0

Md. Monirul Islam
Md. Monirul Islam

Reputation: 731

Don't repeat the calculation/ don't use the loop. Use the switch case syntax properly.

And your leap year calculation is wrong. It should be like this:

if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){
    cout << "the number of days is 29 \n";
}
else {
    cout << "the number of days is 28 \n";
}

A year is leap year if it is divisible by 4 but not divisible by 100 or it is divisible by 400

Upvotes: 4

Alan Stokes
Alan Stokes

Reputation: 18964

You have a loop where i runs from 1 to 12.

Inside that loop you do

switch (month)

But you probably mean

switch (i)

Otherwise you're just repeating the same calculation 12 times.

Upvotes: 2

Related Questions