记录 Ext 日历月份选择控件bug解决过程结果

Posted hijushen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录 Ext 日历月份选择控件bug解决过程结果相关的知识,希望对你有一定的参考价值。

目录

背景

项目使用 Ext.NET 2.2.0.40838 , 对应 Ext JS4.2 版本。 结果 2017/3/31 号的时候偶然间点日历选择控件选择2月,10月等月份突然就跳到3月份,9月份之类。 就是无法选择, 选择谷歌以后发现有同样的问题, 然后各种尝试, 重写了默认属性,如下代码后解决。 收获就是调用平台有时候要知道原因才能找到未知原因并修复. 宝贵的额是Ext框架问题解决思路吧.

现记录。 改动的部分就是 dt.setDate(1); 这一句, 设置为当前月份第一天。

技术图片

代码

  • 原则上放到公共js里面, 然后就行了, 确保生效。 当然也可以放在页面里面调试, 先看看是不是可行。 本项目验证通过。
//修复日期月份模式下在本地日期为31号时跳到下个月的问题 2017年3月31日

(function () { 

if(!window.Ext){return;}
if(!window.Ext.Date){return;}

Ext.Date.createParser = function (format) {
    var utilDate = Ext.Date;



    var xf = function (format) {
        var args = Array.prototype.slice.call(arguments, 1);


        var numberTokenRe = /{(d+)}/g;

        return format.replace(numberTokenRe, function (m, i) {
            return args[i];
        });
    }


    var code = [
    // date calculations (note: the code below creates a dependency on Ext.Number.from())
        "var me = this, dt, y, m, d, h, i, s, ms, o, O, z, zz, u, v, W, year, jan4, week1monday,",
            "def = me.defaults,",
            "from = Ext.Number.from,",
            "results = String(input).match(me.parseRegexes[{0}]);", // either null, or an array of matched strings

        "if(results){",
            "{1}",

            "if(u != null){", // i.e. unix time is defined
                "v = new Date(u * 1000);", // give top priority to UNIX time
            "}else{",
    // create Date object representing midnight of the current day;
    // this will provide us with our date defaults
    // (note: clearTime() handles Daylight Saving Time automatically)
                "dt = me.clearTime(new Date);dt.setDate(1);",

                "y = from(y, from(def.y, dt.getFullYear()));",
                "m = from(m, from(def.m - 1, dt.getMonth()));",
                "d = from(d, from(def.d, dt.getDate()));",

                "h  = from(h, from(def.h, dt.getHours()));",
                "i  = from(i, from(def.i, dt.getMinutes()));",
                "s  = from(s, from(def.s, dt.getSeconds()));",
                "ms = from(ms, from(def.ms, dt.getMilliseconds()));",

                "if(z >= 0 && y >= 0){",
    // both the year and zero-based day of year are defined and >= 0.
    // these 2 values alone provide sufficient info to create a full date object

    // create Date object representing January 1st for the given year
    // handle years < 100 appropriately
                    "v = me.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",

    // then add day of year, checking for Date "rollover" if necessary
                    "v = !strict? v : (strict === true && (z <= 364 || (me.isLeapYear(v) && z <= 365))? me.add(v, me.DAY, z) : null);",
                "}else if(strict === true && !me.isValid(y, m + 1, d, h, i, s, ms)){", // check for Date "rollover"
                    "v = null;", // invalid date, so return null
                "}else{",
                    "if (W) {", // support ISO-8601
    // http://en.wikipedia.org/wiki/ISO_week_date
    //
    // Mutually equivalent definitions for week 01 are:
    // a. the week starting with the Monday which is nearest in time to 1 January
    // b. the week with 4 January in it
    // ... there are many others ...
    //
    // We'll use letter b above to determine the first week of the year.
    //
    // So, first get a Date object for January 4th of whatever calendar year is desired.
    //
    // Then, the first Monday of the year can easily be determined by (operating on this Date):
    // 1. Getting the day of the week.
    // 2. Subtracting that by one.
    // 3. Multiplying that by 86400000 (one day in ms).
    // 4. Subtracting this number of days (in ms) from the January 4 date (represented in ms).
    // 
    // Example #1 ...
    //
    //       January 2012
    //   Su Mo Tu We Th Fr Sa
    //    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
    //
    // 1. January 4th is a Wednesday.
    // 2. Its day number is 3.
    // 3. Simply substract 2 days from Wednesday.
    // 4. The first week of the year begins on Monday, January 2. Simple!
    //
    // Example #2 ...
    //       January 1992
    //   Su Mo Tu We Th Fr Sa
    //             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
    // 
    // 1. January 4th is a Saturday.
    // 2. Its day number is 6.
    // 3. Simply subtract 5 days from Saturday.
    // 4. The first week of the year begins on Monday, December 30. Simple!
    //
    // v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000)));
    // (This is essentially doing the same thing as above but for the week rather than the day)
                        "year = y || (new Date()).getFullYear(),",
                        "jan4 = new Date(year, 0, 4, 0, 0, 0),",
                        "week1monday = new Date(jan4.getTime() - ((jan4.getDay() - 1) * 86400000));",
                        "v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000)));",
                    "} else {",
    // plain old Date object
    // handle years < 100 properly
                        "v = me.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",
                    "}",
                "}",
            "}",
        "}",

        "if(v){",
    // favor UTC offset over GMT offset
            "if(zz != null){",
    // reset to UTC, then add offset
                "v = me.add(v, me.SECOND, -v.getTimezoneOffset() * 60 - zz);",
            "}else if(o){",
    // reset to GMT, then add offset
                "v = me.add(v, me.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
            "}",
        "}",

        "return v;"
      ].join('
');



    var regexNum = utilDate.parseRegexes.length,
            currentGroup = 1,
            calc = [],
            regex = [],
            special = false,
            ch = "",
            i = 0,
            len = format.length,
            atEnd = [],
            obj;

    for (; i < len; ++i) {
        ch = format.charAt(i);
        if (!special && ch == "\") {
            special = true;
        } else if (special) {
            special = false;
            regex.push(Ext.String.escape(ch));
        } else {
            obj = utilDate.formatCodeToRegex(ch, currentGroup);
            currentGroup += obj.g;
            regex.push(obj.s);
            if (obj.g && obj.c) {
                if (obj.calcAtEnd) {
                    atEnd.push(obj.c);
                } else {
                    calc.push(obj.c);
                }
            }
        }
    }

    calc = calc.concat(atEnd);

    utilDate.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
    utilDate.parseFunctions[format] = Ext.functionFactory("input", "strict", xf(code, regexNum, calc.join('')));

}
})();

以上是关于记录 Ext 日历月份选择控件bug解决过程结果的主要内容,如果未能解决你的问题,请参考以下文章

Qt入门系列开发教程基础控件篇QCalendarWidget日历控件

WPF学习第二十五章 日期控件

Android(Kotlin)日期区间选择器/时间区间选择器——日历区间选择器

Android(Kotlin)日期区间选择器/时间区间选择器——日历区间选择器

一个奇怪的bug

extjs 如何禁用日期时间控件