Hi all, I have been working on this code all day and can't seem to really get a grasp on it. Essentially I need to calculate the number of days in the year when the user inputs a month (by name), day, and year

My output would look something like this:

<< Enter the (Month Date, Year) i.e. March 23, 1999:
>> january 1, 2009
<< the Julian date is 1

<< Enter the (Month Date, Year) i.e. March 23, 1999
>> december 31, 2000
<< the Julian date is 366

It has to take into account leap years.

This is the code that I have so far. Any direction would be very much appreciated. I'm having trouble trying to visualize it.

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{
  int daysInMonth[12] = {0, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  int leapYear[13] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  char month[10];
  int day;
  int year;
  int i, x, mm, sum;

  cout << "Enter the (Month Date, Year) i.e. March 23, 1999: ";
  cin >> month >> day >> year;
  strlwr(month);

       if( (year % 4 == 0 && year % 100 != 0) ||  year % 400 == 0) // leap year
		   daysInMonth[1] = 29;
	   else
		   daysInMonth[1] = 28;

  x = strcmp(month, "january");
    if(x == 0)
      mm = 1;
    else if(strcmp(month, "february") == 0)
      mm = 2;
    else if(strcmp(month, "march") == 0)
      mm = 3;
    else if(strcmp(month, "april") == 0)
      mm = 4;
    else if(strcmp(month, "may") == 0)
      mm = 5;
    else if(strcmp(month, "june") == 0)
      mm = 6;
    else if(strcmp(month, "july") == 0)
      mm = 7;
    else if(strcmp(month, "august") == 0)
      mm = 8;
    else if(strcmp(month, "september") == 0)
      mm = 9;
    else if(strcmp(month, "october") == 0)
      mm = 10;
    else if(strcmp(month, "november") == 0)
      mm = 11;
    else if(strcmp(month, "december") == 0)
      mm = 12;

	sum = 0;

	// counter to add days in the month for the date
    for(i=0; i < mm; i++)
      sum = day + daysInMonth[i];


    cout << endl << sum << endl;
  return 0;
}

I keep getting hung up on the leap year and the counter to add to the input day the number of days prior to what I input.


I'd really appreciate any help at all.

Dani AI

Generated

You can meet the 1D-array requirement without resorting to time APIs. Keep a normal days-in-month table, flip February to 29 on leap years, then sum the months before the one entered and add the day. Also, avoid nonstandard functions: strlwr/stricmp are not portable. Use std::string and lowercase with <algorithm>. If you like ’s idea of accepting abbreviations, compare only the first 3 letters case-insensitively. ’s tm_yday example is great for verification, but here is a pure-array approach.

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

bool is_leap(int y) {
    return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}

int month_from_name(std::string m) {
    // normalize and keep first 3 letters only
    std::string key;
    for (char c : m) {
        if (std::isalpha(static_cast<unsigned char>(c))) {
            key.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(c))));
            if (key.size() == 3) break;
        }
    }
    static const char* keys[] = {
        "jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"
    };
    for (int i = 0; i < 12; ++i) if (key == keys[i]) return i + 1;
    return 0; // invalid
}

int day_of_year(const std::string& monthName, int day, int year) {
    int mdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; // 1-based
    if (is_leap(year)) mdays[2] = 29;
    int m = month_from_name(monthName);
    if (m == 0 || day < 1 || day > mdays[m]) return -1; // simple validation
    int sum = day;
    for (int i = 1; i < m; ++i) sum += mdays[i];
    return sum;
}

Common pitfalls from your code: (1) your loop resets sum each time; it should accumulate with +=. (2) reading input like "December 31, 2000" leaves a comma in the stream; read and discard it: char comma; std::cin >> month >> day; if (std::cin.peek()==',') std::cin >> comma; std::cin >> year;. This keeps the parse robust and your Julian day math simple.

Recommended Answers

All 3 Replies

Can you use the standard library?

#include <iostream>
#include <ctime>

int main(void)
{
    using namespace std; // I'm being lazy
    struct tm calendar = {0};
    calendar.tm_year = 2009 - 1900;
    calendar.tm_mon  = 6 - 1;
    calendar.tm_mday = 30;
    time_t date = mktime ( &calendar );
    if ( date != (time_t)(-1) )
    {
        cout << ctime(&date) << "tm_yday = " << calendar.tm_yday + 1 << '\n';
    }
    return 0;
}

/* my output
Tue Jun 30 01:00:00 2009
tm_yday = 181
*/

Or something along that line?

Use stricmp()
Same as strcmp except it's caseless!

Though I'd recommend strlwr or strupr to convert to lower and upper case but do a strncmp
so that you're only comparing the first 3 letters. That way abbreviation can be used and a match will still work!

To save a running count how about using a base count
for each month and subtract next month from prevous month to get day count for the month. Then Look up November directly instead of adding Jan through Nov.

uint MonthBase[12+1] = {
            0, 31, 59, 90, 120, 151,
             181, 212, 243, 273, 304, 334,       365};
};

days elapsed = MonthBase[ Month {0...11} ] + leapday() if >= March

days in month = MonthBase[ Month{0...11} + 1] - MonthBase[ Month ] + leapday() if February;

Congratulations on knowning about the, "Every four years, except every 100 years, except every 400 years."
Most people don't know those last two!

You should also pick a base year. Something not too long ago but will allow you to handle recent old dates!

Hi Dave,

Thanks for the quick response. The criteria is to use a 1D array for it.

int daysInMonth[12] = {0, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Is basically supposed to be the amount of days for each month the user inputs. If the user inputs january 1, 2000 it'll output 1 (which is why the array subscript [0] is holding a '0'.

Then I have to determine whether or not it's a leap year. If it IS a leap year, then the accumulated days after February start to change (+1).

I'm just confused trying to visualize this. I have been writing it out on paper for the last hour and nothing.

So far I have:

1) Set up a 1D array holding the number of days in each month
2) ask for the date from the user
3) see if it's a leap year or not according to the year the user entered
4) if it IS a leap year, count 29 days, otherwise keep it at 28
5) sum the elements of the array
6) have a loop to scroll through the months and days to see if we have chosen the correct day. if so add the days of the month to the sum.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.