Reputation: 318
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
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
.
Check out that assembly too. It's fast.
Upvotes: 0
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
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
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
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
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