Ty Doris
Ty Doris

Reputation: 1

Finding specific days in a specific years and leap years

so, I have this much of the program done I still have to determine what day of the week january 1st is in the current year as well as leap years: A leap year is one whose number is exactly divisible by four. Century years, however, are only leap years if they are exactly divisible by 400. Hence 1900 was not a leap year but 2000 was. Im a bit stuck on where to go from here, I understand it in my head but am having trouble putting my thoughts into code. If anyone can push me in the right direction or if you have a solution id really appreciate the help.

#include <ctime>
#include <iostream>
using namespace std;

int main()
{   
    tm dateTime;        
    time_t systemTime = time(0);        
    localtime_s( &dateTime, &systemTime ); 
    int day = dateTime.tm_mday;//theTime.tm_mday;
    int month = dateTime.tm_mon+1;//theTime.tm_mon;
    int year = dateTime.tm_year + 1900;//theTime.tm_year + 1900;
    int weekDay  = dateTime.tm_wday;
    cout << "Today is ";
    switch (weekDay){
        case 0: cout << "Sunday, ";
            break;
        case 1: cout << "Monday, ";
            break;
        case 2: cout << "Tuesday, ";
            break;
        case 3: cout << "Wednesday, ";
            break;
        case 4: cout << "Thursday, ";
            break;
        case 5: cout << "Friday, ";
            break;
        case 6: cout << "Saturday, ";
            break;
    }
    cout << month << "/" << day << "/" << year << endl;
}

Upvotes: 0

Views: 216

Answers (3)

selbie
selbie

Reputation: 104514

Using the epoch as a reference date (we could really pick any date), we just count up to the current date to get the day of the week.

One optimization is that we can increment the years first and just let the dayOfTheWeek variable increment by 1 or 2 depending if we're currently counting on a leap year or not.

bool isLeapYear(int year)
{
    if ((year % 400) == 0)
        return true;
    if ((year % 100) == 0)
        return false;
    return ((year % 4) == 0);
}

// return the day of the week for a given month/day/year value
// Sunday is 0.  Monday is 1.... Saturday is 6;
int GetDayOfWeek(int month, int day, int year)
{
   int dayOfWeek = 5; // January 1, 1970 was a Thursday
   int daysOfMonth = [0,31,28,31,30,31,30,31,31,30,31,30,31];
   int d = 1;
   int m = 1;
   int y = 1970;

   if (year < 1970)
     return -1;

   // go "year by year" incrementing dayOfWeek by 1 or 2 based on leap year
   while (y < year)
   {
       dayOfWeek = (isLeapYear(y) ? 2 : 1) % 7;
       y++;
   }

   while (d != day && m != month)
   {
      // increment the day
      d++;
      dayOfWeek = (dayOfWeek + 1) % 7;
      if (d > daysOfMonth[m]) // new month
      {
          d = 1;
          m++;
      }
   }

   return dayOfWeek;
}

Upvotes: 0

user1180790
user1180790

Reputation:

  1. Use modulo arithmetic operator (%) to determine if the year is dividable by 4.
    • If it's not, then it's not leap.

Note that a result of operator% equals 0 if and only if lhs is dividable by rhs.

  1. Then, apply the same operator with logic that stands behind alghoritm that determines if year is leap, as you described in your question. Details are in comments of my answer's code.
[[nodiscard]]
constexpr bool IsLeap(const int & Year) noexcept
{
    // If $Year is not dividable by 4, it's not leap, eg 2003.
    // Otherwise, apply more logic below (for years like 2004, 2000 or 1900).

    if (Year % 4 != 0) [[likely]]
        return false;

    // If $Year is dividable by 100, eg 2000, check if it's also dividable by 400.
    // If it's also dividable by 400, it's leap, eg 2000.
    // Otherwise, it's not leap, eg 1900.

    if (Year % 100 == 0) [[unlikely]]
    {
        if (Year % 400 == 0) [[unlikely]]
            return true;

        return false;
    }

    // $Year is dividable by 4 and not by 100, so it's leap.

    return true;
}

Example:

#include <iostream>
int main()
{
    std::cout << std::boolalpha << IsLeap(2003) << std::endl; // false (not dividable by 4)
    std::cout << std::boolalpha << IsLeap(2004) << std::endl; // true  (dividable by 4 and not dividable by 100)
    std::cout << std::boolalpha << IsLeap(2000) << std::endl; // true  (dividable by 4, 100 and 400)
    std::cout << std::boolalpha << IsLeap(1900) << std::endl; // false (dividable by 4 and 100, but not by 400)
}

Upvotes: 1

Artyer
Artyer

Reputation: 40791

To check if a given number is divisible by another number, you use the modulus (%) operator. If a % b == 0, that means that a is divisible by b.

bool is_leap_year(int year) {
    if (year % 4 != 0) return false;
    // Year is divisible by 4; It is a leap year
    if (year % 100 == 0) {
        // Unless it is also divisible by 100, in which case it is not a leap year
        // Except when it is divisible by 400
        if (year % 400 == 0) return true;
        return false;
    }
    return true;
}

// Equivalent to
bool is_leap_year(int year) {
    return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

And then when finding out what weekday it was on January 1st from the current day, you will have to use the modulus operator again. This time, you will use a % 7, which will give the remainder when something is divided by 7 (So 15 days ago is 15 % 7 == 1 day ago in a different week).

Upvotes: 0

Related Questions