0

I'm working on a console based calendar as an educational task (school). It needs to display a calendar sheet for the specific month the user enters. I'm almost there, but I noticed that now all months start on a monday. I created the sheet with a stringbuilder, and I tried to fill the days before the first day of the month actually comes with zeroes, but it doesn't work yet. The for-loop is my attempt. Anyone got any ideas? I'm still learning. Here is the code that builds the sheet, whichs works fine aside from that issue:

DateTime date = DateTime.Now;
        List<DateTime> dateList = new List<DateTime>();

        DateTime dateCopyForModification = date;

        int inputMonth = date.Month;

        while (dateCopyForModification.Month == inputMonth)
        {
            dateList.Add(dateCopyForModification);
            dateCopyForModification = dateCopyForModification.AddDays(1);
        }

        Console.WriteLine("\t---------\n\t{0}, {1}\n\t---------", date.ToString("MMMM"), date.Year);

        int dayCounter = 0;
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.Append("\nMo\t|\tDi\t|\tMi\t|\tDo\t|\tFr\t|\tSa\t|\tSo\t|\n-----------------------------------------------------------------------------------------------------\n");


        foreach (DateTime dateTime in dateList)
        {

//the part that doesnt work
            int day = (int)dateTime.DayOfWeek;

            if (dateTime == new DateTime(dateTime.Year, dateTime.Month, 1))
            {
                for (day = 1; day == (int)dateTime.DayOfWeek; day++)
                {
                    stringBuilder.Append("0");
                    dayCounter++;
                }
            }
//until here
            else
            {
                stringBuilder.Append(dateTime.Day);
                dayCounter++;
            }

            if (dateTime.Day == 28)
            {
                stringBuilder.Append("  |");
            }
            else
            {
                stringBuilder.Append("\t|\t");
            }

            if (dayCounter == 7)
            {
                stringBuilder.Append("\n");
                dayCounter = 0;
            }

        }
        Console.Write(stringBuilder);
        Console.ReadKey();
tweedledum11
  • 121
  • 9
  • I'm afraid it's not really clear to me what you're trying to do, or what the current result is. Could you reduce this to a [mcve]? It looks like only the inner loop is relevant, but we can't tell for sure - a concrete example would make it much easier to help you. – Jon Skeet Apr 06 '16 at 10:37
  • The rest of the code, meaning everything except for the inner for-loop and the if-statement, just produces a calendar sheet. The columns have Mo-Fr as titles, and below then are the dates, just like the Windows calendar. The way I append the dates though, it always starts at monday, and I want to push that to the actual weekday that is the first of the month. I'll remove the rest. – tweedledum11 Apr 06 '16 at 10:52
  • In order to understand the problem, do we need the outer foreach loop? Can you convert this into a *complete* example, with a hard-coded date, and in a full console app that we can copy, paste, compile and run? The simpler you make it for us to reproduce the issue, the more easily we'll be able to help you. – Jon Skeet Apr 06 '16 at 10:55
  • Ok got it, sorry, I can't reduce it any further I think, but this code should work if you copy it. – tweedledum11 Apr 06 '16 at 11:16
  • Well I *really* think you should be able to reduce it - but you still haven't made it clear what you expect to happen and what actually does happen. Please read http://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ – Jon Skeet Apr 06 '16 at 12:43
  • Ok, I thought I did, I'm sorry. I'll educate myself and put more thought into my next question, for this one I'll ask a colleague, thanks for your input though! – tweedledum11 Apr 06 '16 at 13:11

1 Answers1

0

I created a small solution for your problem.However it doesn't use stringbuilder

//This class will store the given month information
class MonthInfo
{
    public DayOfWeek DayName { get; set; }
    public DateTime DayDate { get; set; }
}

//This class will store the cursor position, just to make it look like a calendar
class CursorPosition
{
    public string DayName { get; set; }
    public DayOfWeek DayWeek { get; set; }
    public int locationx { get; set; }


}

and here is the rest of the code

 static void Main(string[] args)
    {
        int monthdigit = 0;
        DateTime _date;


        Console.WriteLine("Enter Month");
        string monthName= Console.ReadLine(); //should be in format "Jan","Feb"


        if (DateTime.TryParseExact(monthName, "MMM", CultureInfo.InvariantCulture, DateTimeStyles.None, out _date))
        {
            monthdigit = (int)_date.Month;
        }
        else
        {
            Console.WriteLine("invalid..programm will exit");
            return;
        }




        List<MonthInfo> GetMyDate = GetDates(2016, monthdigit);


         //stores the cursor position to align the days accordingly
        List<CursorPosition> CurorList = new List<CursorPosition>();
        CurorList.Add(new CursorPosition() { DayName = "Sun", DayWeek=DayOfWeek.Sunday });
        CurorList.Add(new CursorPosition() { DayName = "Mon", DayWeek = DayOfWeek.Monday });
        CurorList.Add(new CursorPosition() { DayName = "Tue", DayWeek = DayOfWeek.Tuesday });
        CurorList.Add(new CursorPosition() { DayName = "Wed", DayWeek = DayOfWeek.Wednesday });
        CurorList.Add(new CursorPosition() { DayName = "Thu", DayWeek = DayOfWeek.Thursday });
        CurorList.Add(new CursorPosition() { DayName = "Fri", DayWeek = DayOfWeek.Friday });
        CurorList.Add(new CursorPosition() { DayName = "Sat", DayWeek = DayOfWeek.Saturday });


        //print all the days name
        foreach (CursorPosition _activeCursor in CurorList)
        {
              Console.Write("\t{0}",_activeCursor.DayName);
              _activeCursor.locationx = Console.CursorLeft;

        }



       //retreive the cursor position and display your day index by adjusting the rownumber accordingly.
        int _dayIndex = 1;
        int rownumber = 2;

        foreach (MonthInfo _month in GetMyDate)
        {
            Console.WriteLine();

                int positionx = (from p in CurorList
                                 where p.DayWeek == _month.DayName
                                 select p.locationx).Single();



            Console.SetCursorPosition(positionx, rownumber + 1);
            Console.Write(_dayIndex++.ToString());



                if ((int)_month.DayName== 6)
                {
                    rownumber++;
                    Console.WriteLine();
                }



        }

        Console.ReadKey();

    }

  public static List<MonthInfo> GetDates(int year, int month)
    {
        var query=from date in  Enumerable.Range(1, DateTime.DaysInMonth(year, month))  // Days: 1, 2 ... 31 etc.
                  select new MonthInfo() { DayName = new DateTime(year, month, date).DayOfWeek, DayDate = new DateTime(year, month, date) };

        return query.ToList();
    }
Rohit
  • 10,056
  • 7
  • 50
  • 82
  • Thanks very much. The thing is, my calendar works in another way, much simpler because some of the code you use seems rather advanced. I'm in the first of 3 years of school, and we need to explain what we use and how we code the whole thing, so this makes it rather difficult. Right now my calendar works by reading keys pressed by the user, meaning: RightArrow key = Go to next month, and so on. I know the stringbuilder might not be ideal, but isn't there a way to just start the Appending when the first day of the month is found? – tweedledum11 Apr 06 '16 at 12:03