How to write a calendar component in my blog


As we all know, while there are many javascript apis for time, we can use methods to retrieve year, month, day, hour, minute, second, millisecond… It seems like a lot. Recently I wrote a calendar (I used to write it, but it was badly written, and it was recently optimized), so the following is a brief record of how to write a calendar, listing some methods that I encapsulated in the process of writing a calendar

rendering

Come a piece of effect map first, because do not have UI design, so oneself simple design a style (somehow I also design professional, although already do not do a design for many years), although slightly ugly, but important is a function!!

Train of thought

How exactly is a calendar generated in code? In fact, observe the existing calendar display form, you can quickly form ideas, that is: according to the calculation of the date number corresponding to the correct day of the week, and in accordance with the order of output. Here’s my thinking:

  • Gets the number of days in the month

  • Get the day of the week of the first day of the month

  • The loop returns an array object for the number and day of the week

    • Return each child of an array object containing at least: number, day of the week, and then add as appropriate: highlighted, current month, holiday… Attributes such as

Methods encapsulate

Note that to keep javascript methods easy to call, and to keep the output realistic, all methods have the following conventions:

  • During the calculation

    • All the months are numbers from 0 to 11

    • All numbers about the week are 0 to 6

  • In the output result

    • All output for months defaults to numbers 1-12

    • All output for the week defaults to numbers 1-7

So when passing arguments to the calling method, the month and day of the week need to be subtracted by one from the actual month

Days of month

There is no direct method to get the day of the month in javascript, but it does provide a getDate method to get the day of the day. Then we only need to get the last day of the month (the 0 day of the next month) to know the number of days of the month:

// Year is the year to get, Function getMonthDays(year, month){return new Date(year, month + 1, 0).getDate(); function getMonthDays(year, month + 1, 0). } getMonthDays(2016 2) //29 getMonthDays(2017 2) //28Copy the code

Get the day of the week

Function getWeekday(year, month, day){return new Date(year, month, day); function getWeekday(year, month, day){return new Date(year, month, day); day).getDate() + 1; } getWeekday(2016,10,9) // output 4, indicating that November 9, 2016 is The 4th of the week getWeekday(2017,10,9) // output 5, indicating that November 9, 2017 is the 5thCopy the code

The fetch month has several weeks

To calculate how many weeks a month contains, you need two pieces of data: the day of the month and the day of the week on which the month begins, to get the desired result

Function getweeksInMonth(year, month){var days = getMonthDays(year, monthdays){var days = getMonthDays(year, monthdays) month); var FirstDayWeekday = getWeekday(year, month, 1); return Math.ceil(days + FirstDayWeekday); }Copy the code

Loop to generate month objects

With that in mind, you can generate a simple month object through a loop. Note that there are two kinds of calendar ordering:

  • Each line begins with Sunday

  • Each line begins with a week

// year is the year to be retrieved // month is the month to be retrieved // day is the day to be retrieved // type is the day of the week, 0 is the day of Monday, 1 is the day of Sunday, // Returns the number of weeks in the current month const WEEKTABLE = [{cn: [' Sunday ', 'Monday ',' Tuesday ', 'Wednesday ',' Thursday ', 'Friday ',' Saturday '], CNS: [' day ', 'a', '2', '3', '4', '5', '6'], en: [' Sun ', 'Mon, Tue, Wed, Thu,' Fri ', 'Sat]}, {cn: [' Monday ', 'on Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday' '], CNS: [' a ', '2', '3', '4', '5', '6', 'days'], en: [' Mon, Tue, Wed, Thu, Fri, Sat, 'Sun']}] getMonthDaysArray (year, month, day,  type) { if (typeof day === 'undefined' && year === YEAR && month === MONTH) day = DAY; var dayArrays = []; var days = this.getMonthDays(year, month), preDays = this.getMonthDays(year, month - 1); var thisMonthFirstDayInWeek = this.getWeekday(year, month, 1), thisMonthLastDayInWeek = this.getWeekday(year, month, days); type = ! type || type ! = = 1? 0:1; For (var I = 0; i < thisMonthFirstDayInWeek; i++) { dayArrays.push({ dayNum: (preDays - thisMonthFirstDayInWeek + i + 1), weekDay: WEEKTABLE[type].cn[I]})} for (var I = 1; i <= days; i++) { var weekDayFlag = (thisMonthFirstDayInWeek + i - 1) % 7 dayArrays.push({ dayNum: i, weekDay: WEEKTABLE[type].cn[weekDayFlag], selected: i === +day, isThisMonth: true }) }; For (var I = 1; i <= (6 - thisMonthLastDayInWeek); i++) { var weekDayFlag = (thisMonthFirstDayInWeek + days + i - 1) % 7 dayArrays.push({ dayNum: i, weekDay: WEEKTABLE[type].cn[weekDayFlag] }) }; return dayArrays; }Copy the code

Formatting time

When it comes to time, it is often necessary to convert the time format. In order to cope with multiple requirements, I have encapsulated one myself

// The FMT argument must // the date argument must not, allowing string and time objects, // Year (YYYY/ YYYY) fixed four placeholders // Month (M), day (d), hour (h), minute (M), second (s) can use 1 or 2 placeholders, strictly case sensitive. // milliseconds (ms/ MSS) up to three placeholders, each corresponding to type 56,056 // example:  // (Format("yyyy-MM-dd hh:mm:ss:ms") ==> 2006-07-02 08:09:04:23 // (Format("yyyy-MM-dd hh:mm:ss:mss") ==> 2006-07-02 // (Format(" YYYY-m-d h: M :s:ms") ==> date){ date = new Date(date).toString() === 'Invalid Date' ? new Date() : new Date(date); var _rules = [{ rule: '[yY]{4}', value: _date.getFullYear() }, { rule: 'M+', value: _date.getMonth() + 1 }, { rule: '[dD]+', value: _date.getDate() }, { rule: 'h+', value: _date.getHours() }, { rule: 'm+', value: _date.getminutes ()}, {rule: 's+', value: _date.getseconds ()}, {rule: 'ms{1,2}', value: _date.getmilliseconds ()}]; _rules.forEach(function (_r){ const rule = _r.rule, val = _r.value; fmt = fmt.replace(new RegExp(rule), function ($1) { const rLen = val.toString().length, fLen = $1.length; return (fLen ! == 2 || rLen >= fLen) ? val : ['00', val].join().substr(rLen); }); }); return fmt; Var time1 = formate("YYYY/MM/DD hh: MM :ss", new Date()); //2017/11/2 11:09:20 var time2 = formate("YYYY-MM-DD", time1); //2017-11-2 var time3 = formate("MM-DD-YYYY", time2); / / 11-2-2017Copy the code

The last

Attached is the source code for these methods datepicker vUE based implementation of a calendar:

  • demovue-datepicker

  • Source datePickerPanel. Vue

Of course, this is only the simplest calendar output, the idea is also super simple (feel a little Low), if there is a god willing to share its experience, welcome to email ~