Leaf187
Leaf187

Reputation: 1

Using Loops and Arrays to go through A Year

fairly new here (and to C#) and thought I would ask for some help as I've hit a brick wall. Currently, I am trying to write a program in C# which will allow me to display every day in the 2015 calendar in the format of

Thursday Jan 1
Friday Jan 2
....
Thursday Dec 31

With each date being printed on a different line and a command at the end of each month making the user press a key to move onto the next month.

I have my 3 arrays set up as

string[] MonthsOfTheYear = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

int[] DaysOfTheMonth = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

string[] DaysOfTheWeek = new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

I'm strictly doing this without using any form of DateTime. I'm sticking to only for and foreach loop.

The initial start will be on a Thursday(4) so I also need some help trying to get the daysOfTheWeek to go back to 0(Sunday) and continue like that until I reach my final date in the year.

Any help would be greatly appreciated

Upvotes: 0

Views: 1510

Answers (3)

Joel Coehoorn
Joel Coehoorn

Reputation: 416039

There are some things for which you really should use the DateTime type (or similar professional time API). This includes both getting the day of the week on a specific day and getting the number of days in the month. You wouldn't believe the number of real-world places where this gets fudged.

So, in for a penny, in for a pound/dollar, right? The entire program:

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var year = DateTime.Today.Year;
        foreach (var month in Enumerable.Range(1, 12))
        {
            foreach (var day in Enumerable.Range(1, DateTime.DaysInMonth(year, month))
                      .Select(day => new DateTime(year, month, day).ToString("dddd MMM d")))
            {
                Console.WriteLine(day);
            }  
            Console.WriteLine("Press a key to continue...");
            Console.ReadKey(true);
        }
    }
}

This is also better than the array-based method because it will correctly handle computers running with different culture/language settings.

I tend to like Enumerable.Range(), because it gets you thinking in terms of binding to a data source. But if you really have a hard time following this you could just use for loops instead of foreach:

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var year = DateTime.Today.Year;
        for(int month = 1; month <= 12; month++)
        {
            for(int day = 1; day <= DateTime.DaysInMonth(year, month); day++)
            {
                Console.WriteLine(new DateTime(year, month, day).ToString("dddd MMM d"));
            }  
            Console.WriteLine("Press a key to continue...");
            Console.ReadKey(true);
        }
    }
}

If you really want to do this the hard way, we can at least use array lookups to get the name and day of week. I still insist on using DateTime types to find the number of days in the month and the day of week for the first day of the year. If this is homework or something else giving you an unreasonable constraint there, this should be enough code for you find the rest of the way:

using System;
using System.Globalization;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var year = DateTime.Today.Year;
        //FIRST DAY OF THE WEEK IS CUSTOMIZABLE/SYSTEM DEPENDANT!
        var dayOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + (int)(new DateTime(year, 1, 1).DayOfWeek) ;
        var dayNames = new string[] {"", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
        var monthNames = new string[] { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

        var dayOfYear = 1;
        foreach (var month in Enumerable.Range(1, 12))
        {
            foreach (var dayOfMonth in Enumerable.Range(1, DateTime.DaysInMonth(year, month)))
            {
                Console.WriteLine("{0} {1} {2}", dayNames[(dayOfYear % 7) + dayOffset], monthNames[month], dayOfMonth);
                dayOfYear++;
            }  
            Console.WriteLine("Press a key to continue...");
            Console.ReadKey(true);
        }
    }
}

I'll put up one more answer where I fix the array definitions to use system locale-dependant month and weekday names:

using System;
using System.Globalization;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var year = DateTime.Today.Year;
        var Jan1 = new DateTime(year, 1, 1);
        var dayNames = Enumerable.Range(0, 7).Select(d => Jan1.AddDays(d).ToString("dddd")).ToArray();
        var monthNames = Enumerable.Range(1,12).Select(m => new DateTime(year, m, 1).ToString("MMM")).ToArray();

        var dayOfYear = 0;
        foreach (var month in Enumerable.Range(1, 12))
        {
            foreach (var dayOfMonth in Enumerable.Range(1, DateTime.DaysInMonth(year, month)))
            {
                Console.WriteLine("{0} {1} {2}", dayNames[dayOfYear % 7], monthNames[month-1], dayOfMonth);
                dayOfYear++;
            }  
            Console.WriteLine("Press a key to continue...");
            Console.ReadKey(true);
        }
    }
}

Upvotes: 1

Abhilash Augustine
Abhilash Augustine

Reputation: 4208

Enigmativity is correct.

I just need to add a functionality to display next month/stop the program based on the user input as Leaf187 asked.

string userChoice;
string[] MonthsOfTheYear = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

int[] DaysOfTheMonth = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

string[] DaysOfTheWeek = new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
var weekdayIndex = 4;
for (var index = 0; index < MonthsOfTheYear.Length; index++)
{
    for (var day = 1; day <= DaysOfTheMonth[index]; day++)
    {
        Console.WriteLine(String.Format("{0} {1} {2}", DaysOfTheWeek[weekdayIndex++ % 7], MonthsOfTheYear[index], day));
    }
    Console.Write("Enter any key to display next month. Enter 'e' to exit "); // Ask user to choose an option 
    userChoice = Console.ReadLine();
    if (userChoice == "e" || userChoice == "E")
    {
        // Break the execution
        break;
    }
}

Upvotes: 0

Enigmativity
Enigmativity

Reputation: 117124

Try this:

var weekdayIndex = 4;
for (var index = 0; index < MonthsOfTheYear.Length; index++)
{
    for (var day = 1; day <= DaysOfTheMonth[index]; day++)
    {
        Console.WriteLine(String.Format("{0} {1} {2}", DaysOfTheWeek[weekdayIndex++ % 7], MonthsOfTheYear[index], day));
    }
}

Upvotes: 0

Related Questions