Calendar start weeks at Monday

2019-06-14 09:02发布

问题:

What do you have to change so that week start from Monday not Sunday?

I can not post the code here, always get an error message and I do not understand because my English is not so good.

`function calendar() {
// show info on init
showInfo();

// vars
var day_of_week = new Array(
'So','Mo', 'Di',
'Mi', 'Do', 'Fr', 'Sa'),
  month_of_year = new Array(
    'Januar', 'Februar', 'März',
    'April', 'May', 'Juni', 'July',
    'August', 'September', 'Oktober',
    'November', 'Dezember'),

  Calendar = new Date(),
  year = Calendar.getYear(),
  month = Calendar.getMonth(),
  today = Calendar.getDate(),
  weekday = Calendar.getDay(),
  html = '';

// start in 1 and this month
Calendar.setDate(1);
Calendar.setMonth(month);

// template calendar
html = '<table>';
// head
html += '<thead>';
html += '<tr class="head_cal"><th colspan="7">' + month_of_year[month] + 
'</th></tr>';
html += '<tr class="subhead_cal"><th colspan="7">' + Calendar.getFullYear() 
+ 
'</th></tr>';
html += '<tr class="week_cal">';
for (index = 0; index < 7; index++) {
  if (weekday == index ) {
    html += '<th class="week_event">' + day_of_week[index] + '</th>';
} else {
  html += '<th>' + day_of_week[index] + '</th>';
}
  }
  html += '</tr>';
  html += '</thead>';

  // body
  html += '<tbody class="days_cal">';
  html += '</tr>';

  // white zone
  for (index = 0; index < Calendar.getDay(); index++) {
    html += '<td class="white_cal"> </td>';
  }  

  for (index = 0; index < 31; index++) {
    if (Calendar.getDate() > index) {

  week_day = Calendar.getDay();

  if (week_day === 0) {
    html += '</tr>';
  }
  if (week_day !== 7) {
    // this day
    var day = Calendar.getDate();
    var info = (Calendar.getMonth() + 1) + '/' + day + '/' + 
    Calendar.getFullYear();

       if (today === Calendar.getDate()) {
          html += '<td><a class="today_cal" href="#" data-id="' + 
          info + '" onclick="return showInfo(\'' + 
          info + '\')">' +
          day + '</a></td>';

          showInfo(info);

        } else {
          html += '<td><a href="#" data-id="' + 
          info + '" onclick="return showInfo(\'' + 
          info + '\')">' +
          day + '</a></td>';
        }

      }

      if (week_day == 7) {
        html += '</tr>';
      }

    }

    Calendar.setDate(Calendar.getDate() + 1);

  } // end for loop
  return html;
}`

Codepen

回答1:

In your day_of_week array change the order of days so that Sunday comes last.

Instead of this:

var day_of_week = new Array('So', 'Mo', 'Di','Mi', 'Do', 'Fr', 'Sa')

Do this:

var day_of_week = new Array('Mo', 'Di','Mi', 'Do', 'Fr', 'Sa', 'So')

Also, you should have a quick read of the help to see how to create links to external sites like Codepen etc (use the question mark '?' in the question editor if you need it). That will help you with things like posting code, links, formatting etc.

Also, when you are linking to an external code site (like Codepen or JSFiddle) you have to include some code in your question or answer as well as the link to the full code.

Update

OK - I see what you mean. Your day of week date does not correctly correspond to the day (as in Jun 3 2017 is a Saturday but showing as a Sunday) after my suggestion.

Because the order of the days changed (ie Monday became the first day of the week), you need to offset your weekday by -1 day.

In your white zone you need to change the first Calendar.getDay() loop from:

for (index = 0; index < Calendar.getDay(); index++)

to:

for (index = 0; index < Calendar.getDay() -1; index++)

That takes care of the first week in the month where there is white-space before the month. Then you need to fix all the other calendar dates. So change the next loop's Calendar.getDay() to offset that too. From this:

week_day = Calendar.getDay();

to this:

week_day = Calendar.getDay() -1;

You should go through the rest of your code and check other months to make sure you are not going to get an invalid date (NaN) because you are decreasing the date by one day.

Update 2

Try this piece of code. This provides a Monday - Sunday calendar and will create the table accordingly. You can easily modify the relevant table cells to include your hook into events and the actual date with styling etc.

If you wanted to you could create the table header with a loop for the days and with a little modification could make the first day of any given week whatever you wanted. I have tested it with each month of this year from Jan through June and the dates work fine.

_('#calendar').innerHTML = calendar();

// short querySelector
function _(s) {
  return document.querySelector(s);
}

function calendar() {

  var html = '<table><thead><tr>';

  html += '<td>Mon</td>';
  html += '<td>Tue</td>';
  html += '<td>Wed</td>';
  html += '<td>Thu</td>';
  html += '<td>Fri</td>';
  html += '<td>Sat</td>';
  html += '<td>Sun</td>';

  html += '</tr></thead>';

  return html + '<tbody>' + calendarRows(new Date("2017/07/02")) + '</tbody></table>';
}

function calendarRows(dt) {

  var html = '';

  // Get the number of days in the month
  var d = new Date(dt.getFullYear(), dt.getMonth()+1, 0);
  var totalDays = d.getDate();

  // Get the first day of the month
  var f = new Date(dt);
  f.setDate(1);
  // The first day of the month for the date passed
  var firstDayOfMonth = f.getDay();
  // The actual date of the month in the calendar
  var calendarDate = 1;
  // The actual day in any given week. 1 === first day, 7 === last
  var dayOfWeek = 1; 

  while (dayOfWeek < 9 && calendarDate <= totalDays) {

    if (dayOfWeek === 8) {
      dayOfWeek = 1;
    }

    // If we are at the start of a new week, create a new row
    if (dayOfWeek === 1) {
      html += '<tr>';
    }

    // Process the calendar day
    html += '<td>';

    // Is this the first day of the month?
    if (calendarDate === 1 && firstDayOfMonth === dayOfWeek) {
      html += calendarDate;
      calendarDate ++;
    }
    else {
      if (calendarDate === 1 || calendarDate > totalDays) {
        html += '&nbsp;';  
      }
      else {
        html += calendarDate;
        calendarDate ++;
      }
    }

    html +='</td>';

    // Are we at the end of a week?
    if (dayOfWeek === 7) {
      html += '</tr>';
    }

    dayOfWeek ++;
  }

  return html;
}

Hopefully that will work for you. You could always tighten up the code, but I leave that up to you. I've tried to make it easy to modify, but admit I put it together rather quickly to try and help you out.

And if you end up modifying the while loop variables just make sure you don't get yourself into an infinite loop.

Update 3

OK - I have created a Codepen for you that has it working with your formatting. You will still need to make the popup events work and add the relevant code to show events in the calendar. You can also tighten the code up if you need. I left it verbose so you can see what is going on.

_('#calendar').innerHTML = calendar();

// short querySelector
function _(s) {
  return document.querySelector(s);
}

// show info
function showInfo(event) {  
    // Your code in here
}

// toggle event show or hide
function hideEvent(){
    _('#calendar_data').classList.toggle('show_data');
}

function calendar() {

  //showInfo();

  var calDate = new Date("2017/06/02");

  var weekdays = new Array( 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
  var months = new Array(
        'Januar', 'Februar', 'März',
        'April', 'May', 'Juni', 'July',
        'August', 'September', 'Oktober',
        'November', 'Dezember');

  // Working vars
  var d = calDate.getDate(),
      m = calDate.getMonth(),
      y = calDate.getFullYear(),
      day = calDate.getDay(),
      today = calDate.getDate();

  var html = '<table><thead>';

  // Month
  html += '<tr class="head_cal"><th colspan="7">' + months[m] + '</th></tr>';

  // Year
  html += '<tr class="subhead_cal"><th colspan="7">' + y + '</th></tr>';

  // Days of week
  html += '<tr class="week_cal">';

  for (i = 0; i < 7; i++) {
    if (today == i) {
      html += '<th class="week_event">' + weekdays[i] + '</th>';
    } else {
      html += '<th>' + weekdays[i] + '</th>';
    }
  }

  html += '</tr>';
  html += '</thead>';

  // Individual calendar days
  html += '<tbody class="days_cal">' + calendarRows(calDate, d, m, y, day, today) + '</tbody></table>';

  return html;
}

function calendarRows(calDate, d, m, y, day, today) {

  var html = '';

  // Get the number of days in the month
  var tempDt = new Date(calDate.getFullYear(), calDate.getMonth()+1, 0);
  var totalDays = tempDt.getDate();

  // Get the first day of the month
  tempDt.setDate(1);
  var firstDayOfMonth = tempDt.getDay();

  // Reset the day to 1 (first day of any month)
  d = 1;

  // Counter for tracking day of week. 1 === first day, 7 === last
  var dayOfWeek = 1;

  while (dayOfWeek < 9 && d <= totalDays) {

    if (dayOfWeek === 8) {
      dayOfWeek = 1;
    } 

    // If we are at the start of a new week, create a new row
    if (dayOfWeek === 1) {
      html += '<tr>';
    }

   // Is this the first day of the month?
    if (d === 1 && firstDayOfMonth === dayOfWeek) {
      html += makeCell(d, m, y, today);
      d ++;
    }
    else {
      if (d === 1 || d > totalDays) {
        html += '<td>&nbsp;</td>';  
      }
      else {
        html += makeCell(d, m, y, today);
        d ++;
      }
    }

    // Are we at the end of a week?
    if (dayOfWeek === 7) {
      html += '</tr>';
    }

    dayOfWeek ++;
  }

  return html;
}

function makeCell(d, m, y, today) {

  var info = (m + 1) + "/" + d + "/" + y;

  var cell = "<td><a href='#' ";

  cell += d === today ? "class='today_cal' " : "";
  cell += "data-id='" + info + "' onclick=\"return showInfo('" + info + "')\">";
  cell += d + "</a></td>";

  return cell;
}

If you modularize your code into smaller chunks (like the makeCell()), you will find it is easier to figure out what is going on and it is easier to get your brain around the more complex code problems.

Hope this helps.

Update 4

Updated the same Codepen - I think this fixed your issue, plus you can set the first day of the week to whatever day you want and the calendar should adjust accordingly. Code change was in the CalendarRows function:

function calendarRows(calDate, d, m, y, day, today) {

  var html = '';

  // Get the number of days in the month
  var tempDt = new Date(calDate.getFullYear(), calDate.getMonth()+1, 0);
  var totalDays = tempDt.getDate();

  // Get the first day of the month
  tempDt.setDate(1);
  var firstDayOfMonth = tempDt.getDay();

  // Reset the day to 1 (first day of any month)
  d = 1;

  // Weekdays are 0 === Sunday, 6 === Saturday
  var firstDayOfWeek = 1, // <-- this means weeks start on Monday
      lastDayOfWeek = 0, // <-- this measn Sunday
      dayOfWeek = firstDayOfWeek,
      safety = 0,
      endLoop = false;

  while (endLoop === false) {

    safety ++;

    if ((dayOfWeek === firstDayOfWeek && d > totalDays) || safety === 50) {

      if (safety === 50) console.error("Infinite loop safety break");

      break;
    }

    // If we are at the start of a new week, create a new row
    if (dayOfWeek === firstDayOfWeek) {
      html += '<tr>';
    }

   // Is this the first day of the month?
    if (d === 1 && firstDayOfMonth === dayOfWeek) {
      html += makeCell(d, m, y, today);
      d ++;
    }
    else {
      if (d === 1 || d > totalDays) {
        html += '<td>&nbsp;</td>';  
      }
      else {
        html += makeCell(d, m, y, today);
        d ++;
      }
    }

    // Are we at the end of a week?
    if (dayOfWeek === lastDayOfWeek) {
      html += '</tr>';
    }

    // Add a day to the current day counter
    dayOfWeek ++;

    // If we get to Saturday, reset the next day to Sunday
    if (dayOfWeek === 7)
      dayOfWeek = 0;

  }

  return html;
}


标签: calendar