Learning Windows Date Functions

I wanted to begin to learn how to use some basic Windows functions while doing Project Euler Problem 19. https://projecteuler.net/problem=19

Basically, I would like to use the following example which is written in C#, but I would like to adapt it to C++ and understand how the Windows functions are used. http://www.mathblog.dk/project-euler-19/

1
2
3
4
5
6
7
8
9
int sundays = 0;
 
for (int year = 1901; year <= 2000; year++) {
    for (int month = 1; month <= 12; month++) {
        if ((new DateTime(year, month, 1)).DayOfWeek == DayOfWeek.Sunday) {
            sundays++;
        }
    }
}


From what I seem to have gathered, I think the part of this code which I would assume is for Windows functions is either outdated or written for C# rather than C++. I have looked to find code at https://msdn.microsoft.com, and found the following at https://msdn.microsoft.com/en-us/library/1wzak8d0.aspx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <atltime.h>

// Print out the day of the week using localized day name
UINT DayOfWeek[] = {
   LOCALE_SDAYNAME7,   // Sunday
   LOCALE_SDAYNAME1,   
   LOCALE_SDAYNAME2,
   LOCALE_SDAYNAME3,
   LOCALE_SDAYNAME4, 
   LOCALE_SDAYNAME5, 
   LOCALE_SDAYNAME6   // Saturday
};
TCHAR strWeekday[256];
CTime time(CTime::GetCurrentTime());   // Initialize CTime with current time
::GetLocaleInfo(LOCALE_USER_DEFAULT,   // Get string for day of the week from system
   DayOfWeek[time.GetDayOfWeek()-1],   // Get day of week from CTime
   strWeekday, sizeof(strWeekday) / sizeof(strWeekday[0]));
ATLTRACE(_T("%s\n"), strWeekday);               // Print out day of the week    


However, if this is C/C++ code, there are errors:
GetLocalInfo has no storage class or type specifier.
ATLTRACE is not recognized.
Where strWeekday is written at the end, a type name is expected.
Last edited on
The code looks like MFC so you need to use it in an MFC app. The C# code is difficult to translate into C++ since C++ is much lower level. Even in 2017 with C++14 the current standard there is no simple to use DateTime class. You might be better of with C#.
Do you need to use date functions to solve Project Euler 19? Just accumulate the first days of the month from 1900 (note) and check whether it is a Sunday (i.e. day % 7 = 0 if the first day of 1900 was 1, a Monday) for years >= 1901.
Last edited on
Thanks, guys. I had been just skipping all the setting up of a program and getting right to the most simplified Win32 Console Application, but now I have begun to explore the project creation options a bit. I am just starting to look at MFC as well as other things. I wanted to do Project Euler 19 this way because I wanted to begin to learn some Windows programming stuff.

Just to get a solution, I did at first write a program that iterated through all of the days between January 1, 1901, and December 31, 2000, knowing from the C# example that it would do much more work than should be necessary. Another solution found here: http://www.mathblog.dk/project-euler-19/ describes how this can be done very easily without a computer. "Since there are 12 months and 100 years, we have 1200 months with a uniform distribution 1/7th of them is Mondays, totaling 171 Mondays. This solution works nicely for this period, but not for 1903 – 2002."

In any case, I did finally get my proposed code working this morning by making it a C++/CLR project. I still may not understand what I did very well, but using this example code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// This example demonstrates the DateTime.DayOfWeek property
using namespace System;
int main()
{

   // Assume the current culture is en-US.
   // Create a DateTime for the first of May, 2003.
   DateTime dt = DateTime(2003,5,1);
   Console::WriteLine(  "Is Thursday the day of the week for {0:d}?: {1}", dt, dt.DayOfWeek == DayOfWeek::Thursday );
   Console::WriteLine(  "The day of the week for {0:d} is {1}.", dt, dt.DayOfWeek );
}

/*
This example produces the following results:

Is Thursday the day of the week for 5/1/2003?: True
The day of the week for 5/1/2003 is Thursday.
*/

from here: https://msdn.microsoft.com/en-us/library/system.datetime.dayofweek(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1
I was able to write my code like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "stdafx.h"

int main()
{
	unsigned int sundays = 0;

	for (int year = 1901; year <= 2000; year++) {
		for (int month = 1; month <= 12; month++) {
			if (System::DateTime(year, month, 1).DayOfWeek == System::DayOfWeek::Sunday) {
				sundays++;
			}
		}
	}

	System::Console::WriteLine("Answer: {0}", sundays);
}
Last edited on
how this can be done very easily without a computer. "Since there are 12 months and 100 years, we have 1200 months with a uniform distribution 1/7th of them is Mondays, totaling 171 Mondays.


I'm not convinced -
Sun     171
Mon     172
Tue     171
Wed     173
Thu     169
Fri     173
Sat     171


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;

//======================================================================

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

//======================================================================

int main()
{
   const int MONTHLENGTH[ 1 + 12 ] = { 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                 // Includes Dec from previous year, so as to use [i-1] for previous month length
                 // Also allows Jan = month 1, Feb = month 2 etc.
   const char *names[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
   int tally[7] = { 0 };

   int day = 1;                                            // cumulative days from first of 1900 (a Monday)
   for ( int year = 1900; year <= 2000; year++ )
   {
      for ( int month = 1; month <= 12; month++ )
      {
         if ( !(year == 1900 && month == 1) ) day += MONTHLENGTH[month-1];     // cumulative days at 1st of month
         if ( month == 3 && isLeap( year ) ) day++;        // 1st of March in a leap year
         if ( year >= 1901 ) tally[day%7]++;               // count from 1901 onward
      }
   }

   for ( int i = 0; i < 7; i++ ) cout << names[i] << '\t' << tally[i] << '\n';
}

Topic archived. No new replies allowed.