Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8274725
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T07:49:36+00:00 2026-06-08T07:49:36+00:00

The problem I am writing a class for holding dates in c++, and I

  • 0

The problem

I am writing a class for holding dates in c++, and I found the following problem:

I have a number of days N since a reference date (in my case that would be Jan 1, 0001 AD), including the leap days that passed since the reference day. How can I convert this number to a year Y, month M and day D efficiently?

I would like to do this as efficiently as possible, so the best implementation would obviously have O(1) complexity.

The next sections will explain some of the things I already learned.

Leap years

To determine if a year is leap or not, there are a few rules:

  1. Years which are divisible by 4 are leap
  2. Exception to rule 1: years that are divisible with 100 are not leap
  3. Exception to rule 2: years that are divisible with 400 are leap

This would translate in code like this:

bool IsLeapYear(int year)
{
    // Corrected after Henrick's suggestion
    if (year % 400 == 0) return true;
    if ((year % 4 == 0) && (year % 100 != 0)) return true;
    return false;
}

An efficient method to calculate how many years are leap before an year would be:

int LeapDaysBefore(int year)
{
    // Years divisible by 4, not divisible by 100, but divisible by 400
    return ((year-1)/4 - (year-1)/100 + (year-1)/400);
}

Calculating the month

Once I find the year, I can calculate how many days there are until the current year, and I can subtract this number from N. This will give me the day of the year.

Keeping a table with the day number on which every month starts, we can easily calculate the month. I also created a function which will add 1 if the year is leap, and the month is greater or equal to 2.

// What day each month starts on (counting from 0)
int MonthDaySt[] = { 0, 31, 59, 90, 120, 151, 181, 212, 
    243, 273, 304, 334, 365 };

int MonthDayStart(int month, bool leap)
{
   if (leap && month >= 2) return MonthDaySt[month]+1;
   return MonthDaySt[month];
}

My idea

My algorithm is pretty complicated, and it looks like this:

void GetDate(int N, int &Y, int &M, int &D)
{
    int year_days;

    // Approximate the year, this will give an year greater or equal
    // to what year we are looking for.
    Y = N / 365 + 1;

    // Find the actual year, counting leap days
    do {
        Y--;

        // Calculate the actual number of days until the
        // approximate year
        year_days = Y * 365 + LeapDaysBefore(year);

    } while (year_days > N);

    // Add 1, because we start from year 1 AD (not 0)
    Y++;

    // Calculate month
    uint64_t diff = N - year_days; // Will give us the day of the year
    bool leap = IsLeapYear(Y);  // Is current year leap?

    // Use table to find month
    M = 0;
    while (MonthDayStart(M, leap) <= diff && M <= 12)
        M++;

    // Calculate day
    D = diff - MonthDayStart(M - 1, leap) + 1;
}

The function may have a few bugs (for example, it didn’t work when N was 0).

Other notes

I hope that my algorithm is still correct, because I made some changes from the original for this question. If I missed something, or something was wrong, let me know to modify it. And sorry for the long question.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T07:49:40+00:00Added an answer on June 8, 2026 at 7:49 am

    Here are a few pointers. Note: For this exercise I will assume that when N=0 that Y % 400 == 0.

    1: There are a fixed number of days in each 400 year period (400 * 365) + 100 + 1 - 4.

    The +100 is for the leap years, the +1 is for the leap year every 400 years and the -4 is for not having a leap year every 100 years.

    So your first line of code will be:

    GetDate(int N, int &Y, int &M, int &D) {
      const int DAYS_IN_400_YEARS = (400*365)+97;
      int year = (N / DAYS_IN_400_YEARS) * 400;
      N = N % DAYS_IN_400_YEARS;
    

    2: You can make your life a great deal easier if you treat March 1st as the first day of the year

    3: Adding to the code in (1), we can work out the year. Bear in mind that every fourth century begins with a leap year. So you can complete the calculation of the year with the following:

      const int DAYS_IN_100_YEARS = (100*365) + 24;
      year += 100 * (N / DAYS_IN_100_YEARS) + (N < DAYS_IN_100_YEARS ? 1 : 0); // Add an extra day for the first leap year that occurs every 400 years.
      N = N - (N < DAYS_IN_100_YEARS ? 1 : 0);
      N = N % DAYS_IN_400_YEARS;
    

    4: Now you’ve sorted out the years, the rest is easy as pie (just remember (2), and the process is easy).

    Alternatively you could use boost::date.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am writing a class. I have encountered the problem in the title. Here
I have a problem with writing a catch clause for an exception that is
I have been writing several class templates that contain nested iterator classes, for which
I'm currently writing a class that implements the SeekableIterator interface and have run into
I have come across an annoying problem while writing some PHP4 code. I renamed
I have a problem with regards to writing the correct regex for the examination
I am writing some documentation and I have a little vocabulary problem: http://www.example.com/en/public/img/logo.gif is
I am writing a simple console application in Objective-C but I have heard that
I'm having a problem writing a regular expression for matching HTML tags. I found
I am writing class that extends adobe air PNGEncoder, I want to use the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.