bootstrap daterangepicker 添加阴历及节假日

所有的新增都用 'myAdd start'和'myAdd end'标注,所有的修改都用'myChange start'和'myChange end'标注。

 

借用了 1900-2100区间内的公历、农历互转  自己添加了节假日数组及一个方法:传入calendar(公历或农历)m月d日获得该日期的节假日,修改后的代码:

  1 /**
  2  * @1900-2100区间内的公历、农历互转
  3  * @charset UTF-8
  4  * @Author  Jea杨(JJonline@JJonline.Cn) 
  5  * @change by liyimin
  6  * @Time    2014-7-21
  7  * @Time    2016-8-13 Fixed 2033hex、Attribution Annals
  8  * @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
  9  * @Version 1.0.2
 10  * @公历转农历:myCalendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
 11  * @农历转公历:myCalendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
 12  */
 13 var myCalendar = {
 14     /**
 15      * 农历1900-2100的润大小信息表
 16      * @Array Of Property
 17      * @return Hex 
 18      */
 19     lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909
 20         0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919
 21         0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929
 22         0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939
 23         0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949
 24         0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
 25         0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969
 26         0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979
 27         0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989
 28         0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999
 29         0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
 30         0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019
 31         0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029
 32         0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039
 33         0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049
 34         /**Add By JJonline@JJonline.Cn**/
 35         0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
 36         0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
 37         0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
 38         0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
 39         0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
 40         0x0d520
 41     ], //2100
 42     /**
 43      * 公历每个月份的天数普通表
 44      * @Array Of Property
 45      * @return Number 
 46      */
 47     solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
 48     /**
 49      * 天干地支之天干速查表
 50      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
 51      * @return Cn string 
 52      */
 53     Gan: ["\u7532", "\u4e59", "\u4e19", "\u4e01", "\u620a", "\u5df1", "\u5e9a", "\u8f9b", "\u58ec", "\u7678"],
 54     /**
 55      * 天干地支之地支速查表
 56      * @Array Of Property 
 57      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
 58      * @return Cn string 
 59      */
 60     Zhi: ["\u5b50", "\u4e11", "\u5bc5", "\u536f", "\u8fb0", "\u5df3", "\u5348", "\u672a", "\u7533", "\u9149", "\u620c", "\u4ea5"],
 61     /**
 62      * 天干地支之地支速查表<=>生肖
 63      * @Array Of Property 
 64      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
 65      * @return Cn string 
 66      */
 67     Animals: ["\u9f20", "\u725b", "\u864e", "\u5154", "\u9f99", "\u86c7", "\u9a6c", "\u7f8a", "\u7334", "\u9e21", "\u72d7", "\u732a"],
 68     /**
 69      * 24节气速查表
 70      * @Array Of Property 
 71      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
 72      * @return Cn string 
 73      */
 74     solarTerm: ["\u5c0f\u5bd2", "\u5927\u5bd2", "\u7acb\u6625", "\u96e8\u6c34", "\u60ca\u86f0", "\u6625\u5206", "\u6e05\u660e", "\u8c37\u96e8", "\u7acb\u590f", "\u5c0f\u6ee1", "\u8292\u79cd", "\u590f\u81f3", "\u5c0f\u6691", "\u5927\u6691", "\u7acb\u79cb", "\u5904\u6691", "\u767d\u9732", "\u79cb\u5206", "\u5bd2\u9732", "\u971c\u964d", "\u7acb\u51ac", "\u5c0f\u96ea", "\u5927\u96ea", "\u51ac\u81f3"],
 75     /**
 76      * 1900-2100各年的24节气日期速查表
 77      * @Array Of Property 
 78      * @return 0x string For splice
 79      */
 80     sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
 81     /**
 82      * 数字转中文速查表
 83      * @Array Of Property 
 84      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
 85      * @return Cn string 
 86      */
 87     nStr1: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341"],
 88     /**
 89      * 日期转农历称呼速查表
 90      * @Array Of Property 
 91      * @trans ['初','十','廿','卅']
 92      * @return Cn string 
 93      */
 94     nStr2: ["\u521d", "\u5341", "\u5eff", "\u5345"],
 95     /**
 96      * 月份转农历称呼速查表
 97      * @Array Of Property 
 98      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
 99      * @return Cn string 
100      */
101     nStr3: ["\u6b63", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u51ac", "\u814a"],
102    
103     /**myAdd start
104      * 节假日
105      * @Array Of Property 
106      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
107      * @return Cn string 
108      */
109     //公历节日
110     sFtv: ["0101 元旦", "0214 情人节",
111         // "0308 妇女",
112         // "0312 植树",
113         // "0315 消费者权益日",
114         // "0401 愚人",
115         "0501 劳动节",
116         // "0504 青年",
117         // "0512 护士",
118         // "0601 儿童",
119         // "0701 建党",
120         // "0801 建军",
121         // "0910 教师节",
122         // "0928 孔子诞辰",
123         "1001 国庆节",
124         // "1006 老人",
125         // "1024 联合国日",
126         "1224 平安夜", "1225 圣诞"
127     ],
128     //农历节日
129     lFtv: ["0101 春节", "0115 元宵", "0505 端午", "0707 七夕", "0715 中元", "0815 中秋", "0909 重阳", "1208 腊八", "1224 小年"],
130     /**myAdd end*/
131 
132     /**
133      * 返回农历y年一整年的总天数
134      * @param lunar Year
135      * @return Number
136      * @eg:var count = myCalendar.lYearDays(1987) ;//count=387
137      */
138     lYearDays: function(y) {
139         var i, sum = 348;
140         for (i = 0x8000; i > 0x8; i >>= 1) {
141             sum += (myCalendar.lunarInfo[y - 1900] & i) ? 1 : 0;
142         }
143         return (sum + myCalendar.leapDays(y));
144     },
145     /**
146      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
147      * @param lunar Year
148      * @return Number (0-12)
149      * @eg:var leapMonth = myCalendar.leapMonth(1987) ;//leapMonth=6
150      */
151     leapMonth: function(y) { //闰字编码 \u95f0
152         return (myCalendar.lunarInfo[y - 1900] & 0xf);
153     },
154     /**
155      * 返回农历y年闰月的天数 若该年没有闰月则返回0
156      * @param lunar Year
157      * @return Number (0、29、30)
158      * @eg:var leapMonthDay = myCalendar.leapDays(1987) ;//leapMonthDay=29
159      */
160     leapDays: function(y) {
161         if (myCalendar.leapMonth(y)) {
162             return ((myCalendar.lunarInfo[y - 1900] & 0x10000) ? 30 : 29);
163         }
164         return (0);
165     },
166     /**
167      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
168      * @param lunar Year
169      * @return Number (-1、29、30)
170      * @eg:var MonthDay = myCalendar.monthDays(1987,9) ;//MonthDay=29
171      */
172     monthDays: function(y, m) {
173         if (m > 12 || m < 1) {
174             return -1
175         } //月份参数从1至12,参数错误返回-1
176         return ((myCalendar.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
177     },
178     /**
179      * 返回公历(!)y年m月的天数
180      * @param solar Year
181      * @return Number (-1、28、29、30、31)
182      * @eg:var solarMonthDay = myCalendar.leapDays(1987) ;//solarMonthDay=30
183      */
184     solarDays: function(y, m) {
185         if (m > 12 || m < 1) {
186             return -1
187         } //若参数错误 返回-1
188         var ms = m - 1;
189         if (ms == 1) { //2月份的闰平规律测算后确认返回28或29
190             return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28);
191         } else {
192             return (myCalendar.solarMonth[ms]);
193         }
194     },
195     /**
196      * 农历年份转换为干支纪年
197      * @param  lYear 农历年的年份数
198      * @return Cn string
199      */
200     toGanZhiYear: function(lYear) {
201         var ganKey = (lYear - 3) % 10;
202         var zhiKey = (lYear - 3) % 12;
203         if (ganKey == 0) ganKey = 10; //如果余数为0则为最后一个天干
204         if (zhiKey == 0) zhiKey = 12; //如果余数为0则为最后一个地支
205         return myCalendar.Gan[ganKey - 1] + myCalendar.Zhi[zhiKey - 1];
206     },
207     /**
208      * 公历月、日判断所属星座
209      * @param  cMonth [description]
210      * @param  cDay [description]
211      * @return Cn string
212      */
213     toAstro: function(cMonth, cDay) {
214         var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";
215         var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
216         return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + "\u5ea7"; //
217     },
218     /**
219      * 传入offset偏移量返回干支
220      * @param offset 相对甲子的偏移量
221      * @return Cn string
222      */
223     toGanZhi: function(offset) {
224         return myCalendar.Gan[offset % 10] + myCalendar.Zhi[offset % 12];
225     },
226     /**myAdd start
227      * 传入calendar(公历或农历)m月d日获得该日期的节假日
228      * @param 
229      * @return 
230      * @eg:var 
231      */
232     getFestivals: function(m, d, calendar) {
233         var festivals;
234         if (calendar == 'lunar') {
235             festivalsArr = myCalendar.lFtv;
236         } else if (calendar == 'solar') {
237             festivalsArr = myCalendar.sFtv;
238         }
239         for (var i = 0, len = festivalsArr.length; i < len; i++) {
240             if (m == parseInt(festivalsArr[i].substr(0, 2)) && d == parseInt(festivalsArr[i].substr(2, 4))) {
241                 return festivalsArr[i].substr(5);
242             }
243         }
244     },
245     /**myAdd end*/
246     
247     /**
248      * 传入公历(!)y年获得该年第n个节气的公历日期
249      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 
250      * @return day Number
251      * @eg:var _24 = myCalendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
252      */
253     getTerm: function(y, n) {
254         if (y < 1900 || y > 2100) {
255             return -1;
256         }
257         if (n < 1 || n > 24) {
258             return -1;
259         }
260         var _table = myCalendar.sTermInfo[y - 1900];
261         var _info = [
262             parseInt('0x' + _table.substr(0, 5)).toString(),
263             parseInt('0x' + _table.substr(5, 5)).toString(),
264             parseInt('0x' + _table.substr(10, 5)).toString(),
265             parseInt('0x' + _table.substr(15, 5)).toString(),
266             parseInt('0x' + _table.substr(20, 5)).toString(),
267             parseInt('0x' + _table.substr(25, 5)).toString()
268         ];
269         var _calday = [
270             _info[0].substr(0, 1),
271             _info[0].substr(1, 2),
272             _info[0].substr(3, 1),
273             _info[0].substr(4, 2),
274             _info[1].substr(0, 1),
275             _info[1].substr(1, 2),
276             _info[1].substr(3, 1),
277             _info[1].substr(4, 2),
278             _info[2].substr(0, 1),
279             _info[2].substr(1, 2),
280             _info[2].substr(3, 1),
281             _info[2].substr(4, 2),
282             _info[3].substr(0, 1),
283             _info[3].substr(1, 2),
284             _info[3].substr(3, 1),
285             _info[3].substr(4, 2),
286             _info[4].substr(0, 1),
287             _info[4].substr(1, 2),
288             _info[4].substr(3, 1),
289             _info[4].substr(4, 2),
290             _info[5].substr(0, 1),
291             _info[5].substr(1, 2),
292             _info[5].substr(3, 1),
293             _info[5].substr(4, 2),
294         ];
295         return parseInt(_calday[n - 1]);
296     },
297     /**
298      * 传入农历数字月份返回汉语通俗表示法
299      * @param lunar month
300      * @return Cn string
301      * @eg:var cnMonth = myCalendar.toChinaMonth(12) ;//cnMonth='腊月'
302      */
303     toChinaMonth: function(m) { // 月 => \u6708
304         if (m > 12 || m < 1) {
305             return -1
306         } //若参数错误 返回-1
307         var s = myCalendar.nStr3[m - 1];
308         s += "\u6708"; //加上月字
309         return s;
310     },
311     /**
312      * 传入农历日期数字返回汉字表示法
313      * @param lunar day
314      * @return Cn string
315      * @eg:var cnDay = myCalendar.toChinaDay(21) ;//cnMonth='廿一'
316      */
317     toChinaDay: function(d) { //日 => \u65e5
318         var s;
319         switch (d) {
320             case 10:
321                 s = '\u521d\u5341';
322                 break;
323             case 20:
324                 s = '\u4e8c\u5341';
325                 break;
326                 break;
327             case 30:
328                 s = '\u4e09\u5341';
329                 break;
330                 break;
331             default:
332                 s = myCalendar.nStr2[Math.floor(d / 10)];
333                 s += myCalendar.nStr1[d % 10];
334         }
335         return (s);
336     },
337     /**
338      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
339      * @param y year
340      * @return Cn string
341      * @eg:var animal = myCalendar.getAnimal(1987) ;//animal='兔'
342      */
343     getAnimal: function(y) {
344         return myCalendar.Animals[(y - 4) % 12]
345     },
346     /**
347      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
348      * @param y  solar year
349      * @param m  solar month
350      * @param d  solar day
351      * @return JSON object
352      * @eg:console.log(myCalendar.solar2lunar(1987,11,01));
353      */
354     solar2lunar: function(y, m, d) { //参数区间1900.1.31~2100.12.31
355         if (y < 1900 || y > 2100) {
356             return -1;
357         } //年份限定、上限
358         if (y == 1900 && m == 1 && d < 31) {
359             return -1;
360         } //下限
361         if (!y) { //未传参  获得当天
362             var objDate = new Date();
363         } else {
364             var objDate = new Date(y, parseInt(m) - 1, d)
365         }
366         var i, leap = 0,
367             temp = 0;
368         //修正ymd参数
369         var y = objDate.getFullYear(),
370             m = objDate.getMonth() + 1,
371             d = objDate.getDate();
372         var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000;
373         for (i = 1900; i < 2101 && offset > 0; i++) {
374             temp = myCalendar.lYearDays(i);
375             offset -= temp;
376         }
377         if (offset < 0) {
378             offset += temp;
379             i--;
380         }
381         //是否今天
382         var isTodayObj = new Date(),
383             isToday = false;
384         if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
385             isToday = true;
386         }
387         //星期几
388         var nWeek = objDate.getDay(),
389             cWeek = myCalendar.nStr1[nWeek];
390         if (nWeek == 0) {
391             nWeek = 7;
392         } //数字表示周几顺应天朝周一开始的惯例
393         //农历年
394         var year = i;
395         var leap = myCalendar.leapMonth(i); //闰哪个月
396         var isLeap = false;
397         //效验闰月
398         for (i = 1; i < 13 && offset > 0; i++) {
399             //闰月
400             if (leap > 0 && i == (leap + 1) && isLeap == false) {
401                 --i;
402                 isLeap = true;
403                 temp = myCalendar.leapDays(year); //计算农历闰月天数
404             } else {
405                 temp = myCalendar.monthDays(year, i); //计算农历普通月天数
406             }
407             //解除闰月
408             if (isLeap == true && i == (leap + 1)) {
409                 isLeap = false;
410             }
411             offset -= temp;
412         }
413         if (offset == 0 && leap > 0 && i == leap + 1)
414             if (isLeap) {
415                 isLeap = false;
416             } else {
417                 isLeap = true;
418                 --i;
419             }
420         if (offset < 0) {
421             offset += temp;
422             --i;
423         }
424         //农历月
425         var month = i;
426         //农历日
427         var day = offset + 1;
428         //天干地支处理
429         var sm = m - 1;
430         var gzY = myCalendar.toGanZhiYear(year);
431         //月柱 1900年1月小寒以前为 丙子月(60进制12)
432         var firstNode = myCalendar.getTerm(year, (m * 2 - 1)); //返回当月「节」为几日开始
433         var secondNode = myCalendar.getTerm(year, (m * 2)); //返回当月「节」为几日开始
434         //依据12节气修正干支月
435         var gzM = myCalendar.toGanZhi((y - 1900) * 12 + m + 11);
436         if (d >= firstNode) {
437             gzM = myCalendar.toGanZhi((y - 1900) * 12 + m + 12);
438         }
439         //传入的日期的节气与否
440         var isTerm = false;
441         var Term = null;
442         if (firstNode == d) {
443             isTerm = true;
444             Term = myCalendar.solarTerm[m * 2 - 2];
445         }
446         if (secondNode == d) {
447             isTerm = true;
448             Term = myCalendar.solarTerm[m * 2 - 1];
449         }
450         //日柱 当月一日与 1900/1/1 相差天数
451         var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10;
452         var gzD = myCalendar.toGanZhi(dayCyclical + d - 1);
453         //该日期所属的星座
454         var astro = myCalendar.toAstro(m, d);
455         return {
456             'lYear': year,
457             'lMonth': month,
458             'lDay': day,
459             'Animal': myCalendar.getAnimal(year),
460             'IMonthCn': (isLeap ? "\u95f0" : '') + myCalendar.toChinaMonth(month),
461             'IDayCn': myCalendar.toChinaDay(day),
462             'cYear': y,
463             'cMonth': m,
464             'cDay': d,
465             'lunarFestivals': myCalendar.getFestivals(month, day, 'lunar'), //myAdd
466             'calendarFestivals': myCalendar.getFestivals(m, d, 'solar'), //myAdd
467             'gzYear': gzY,
468             'gzMonth': gzM,
469             'gzDay': gzD,
470             'isToday': isToday,
471             'isLeap': isLeap,
472             'nWeek': nWeek,
473             'ncWeek': "\u661f\u671f" + cWeek,
474             'isTerm': isTerm,
475             'Term': Term,
476             'astro': astro
477         };
478     },
479     /**
480      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
481      * @param y  lunar year
482      * @param m  lunar month
483      * @param d  lunar day
484      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
485      * @return JSON object
486      * @eg:console.log(myCalendar.lunar2solar(1987,9,10));
487      */
488     lunar2solar: function(y, m, d, isLeapMonth) { //参数区间1900.1.31~2100.12.1
489         var isLeapMonth = !!isLeapMonth;
490         var leapOffset = 0;
491         var leapMonth = myCalendar.leapMonth(y);
492         var leapDay = myCalendar.leapDays(y);
493         if (isLeapMonth && (leapMonth != m)) {
494             return -1;
495         } //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
496         if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) {
497             return -1;
498         } //超出了最大极限值 
499         var day = myCalendar.monthDays(y, m);
500         var _day = day;
501         //bugFix 2016-9-25 
502         //if month is leap, _day use leapDays method 
503         if (isLeapMonth) {
504             _day = myCalendar.leapDays(y, m);
505         }
506         if (y < 1900 || y > 2100 || d > _day) {
507             return -1;
508         } //参数合法性效验
509         //计算农历的时间差
510         var offset = 0;
511         for (var i = 1900; i < y; i++) {
512             offset += myCalendar.lYearDays(i);
513         }
514         var leap = 0,
515             isAdd = false;
516         for (var i = 1; i < m; i++) {
517             leap = myCalendar.leapMonth(y);
518             if (!isAdd) { //处理闰月
519                 if (leap <= i && leap > 0) {
520                     offset += myCalendar.leapDays(y);
521                     isAdd = true;
522                 }
523             }
524             offset += myCalendar.monthDays(y, i);
525         }
526         //转换闰月农历 需补充该年闰月的前一个月的时差
527         if (isLeapMonth) {
528             offset += day;
529         }
530         //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
531         var stmap = Date.UTC(1900, 1, 30, 0, 0, 0);
532         var calObj = new Date((offset + d - 31) * 86400000 + stmap);
533         var cY = calObj.getUTCFullYear();
534         var cM = calObj.getUTCMonth() + 1;
535         var cD = calObj.getUTCDate();
536         return myCalendar.solar2lunar(cY, cM, cD);
537     }
538 };
View Code

对daterangepicker修改后的代码:

   1 /**
   2  * @version: 2.1.22
   3  * @author: Dan Grossman http://www.dangrossman.info/
   4  * change by liyimin
   5  * @copyright: Copyright (c) 2012-2016 Dan Grossman. All rights reserved.
   6  * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
   7  * @website: https://www.improvely.com/
   8  */
   9 // Follow the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
  10 (function(root, factory) {
  11     if (typeof define === 'function' && define.amd) {
  12         // AMD. Make globaly available as well
  13         define(['moment', 'jquery'], function(moment, jquery) {
  14             return (root.daterangepicker = factory(moment, jquery));
  15         });
  16     } else if (typeof module === 'object' && module.exports) {
  17         // Node / Browserify
  18         //isomorphic issue
  19         var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined;
  20         if (!jQuery) {
  21             jQuery = require('jquery');
  22             if (!jQuery.fn) jQuery.fn = {};
  23         }
  24         module.exports = factory(require('moment'), jQuery);
  25     } else {
  26         // Browser globals
  27         root.daterangepicker = factory(root.moment, root.jQuery);
  28     }
  29 }(this, function(moment, $) {
  30     var DateRangePicker = function(element, options, cb) {
  31         //default settings for options
  32         this.parentEl = 'body';
  33         this.element = $(element);
  34         this.startDate = moment().startOf('day');
  35         this.endDate = moment().endOf('day');
  36         this.minDate = false;
  37         this.maxDate = false;
  38         this.dateLimit = false;
  39         this.autoApply = false;
  40         this.singleDatePicker = false;
  41         this.showDropdowns = false;
  42         this.showWeekNumbers = false;
  43         this.showISOWeekNumbers = false;
  44         this.timePicker = false;
  45         this.timePicker24Hour = false;
  46         this.timePickerIncrement = 1;
  47         this.timePickerSeconds = false;
  48         this.linkedCalendars = true;
  49         this.autoUpdateInput = true;
  50         this.alwaysShowCalendars = false;
  51         this.ranges = {};
  52         this.opens = 'right';
  53         if (this.element.hasClass('pull-right')) this.opens = 'left';
  54         this.drops = 'down';
  55         if (this.element.hasClass('dropup')) this.drops = 'up';
  56         this.buttonClasses = 'btn btn-sm';
  57         this.applyClass = 'btn-success';
  58         this.cancelClass = 'btn-default';
  59         this.locale = {
  60             direction: 'ltr',
  61             format: 'MM/DD/YYYY',
  62             separator: ' - ',
  63             applyLabel: 'Apply',
  64             cancelLabel: 'Cancel',
  65             weekLabel: 'W',
  66             customRangeLabel: 'Custom Range',
  67             daysOfWeek: moment.weekdaysMin(),
  68             monthNames: moment.monthsShort(),
  69             firstDay: moment.localeData().firstDayOfWeek()
  70         };
  71         this.callback = function() {};
  72         //some state information
  73         this.isShowing = false;
  74         this.leftCalendar = {};
  75         this.rightCalendar = {};
  76         //custom options from user
  77         if (typeof options !== 'object' || options === null) options = {};
  78         //allow setting options with data attributes
  79         //data-api options will be overwritten with custom javascript options
  80         options = $.extend(this.element.data(), options);
  81         //html template for the picker UI
  82         if (typeof options.template !== 'string' && !(options.template instanceof $)) options.template = '<div class="daterangepicker dropdown-menu">' + '<div class="calendar left">' + '<div class="daterangepicker_input">' + '<input class="input-mini form-control" type="text" name="daterangepicker_start" value="" />' + '<i class="fa fa-calendar glyphicon glyphicon-calendar"></i>' + '<div class="calendar-time">' + '<div></div>' + '<i class="fa fa-clock-o glyphicon glyphicon-time"></i>' + '</div>' + '</div>' + '<div class="calendar-table"></div>' + '</div>' + '<div class="calendar right">' + '<div class="daterangepicker_input">' + '<input class="input-mini form-control" type="text" name="daterangepicker_end" value="" />' + '<i class="fa fa-calendar glyphicon glyphicon-calendar"></i>' + '<div class="calendar-time">' + '<div></div>' + '<i class="fa fa-clock-o glyphicon glyphicon-time"></i>' + '</div>' + '</div>' + '<div class="calendar-table"></div>' + '</div>' + '<div class="ranges">' + '<div class="range_inputs">' + '<button class="applyBtn" disabled="disabled" type="button"></button> ' + '<button class="cancelBtn" type="button"></button>' + '</div>' + '</div>' + '</div>';
  83         this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
  84         this.container = $(options.template).appendTo(this.parentEl);
  85         //
  86         // handle all the possible options overriding defaults
  87         //
  88         if (typeof options.locale === 'object') {
  89             if (typeof options.locale.direction === 'string') this.locale.direction = options.locale.direction;
  90             if (typeof options.locale.format === 'string') this.locale.format = options.locale.format;
  91             if (typeof options.locale.separator === 'string') this.locale.separator = options.locale.separator;
  92             if (typeof options.locale.daysOfWeek === 'object') this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
  93             if (typeof options.locale.monthNames === 'object') this.locale.monthNames = options.locale.monthNames.slice();
  94             if (typeof options.locale.firstDay === 'number') this.locale.firstDay = options.locale.firstDay;
  95             if (typeof options.locale.applyLabel === 'string') this.locale.applyLabel = options.locale.applyLabel;
  96             if (typeof options.locale.cancelLabel === 'string') this.locale.cancelLabel = options.locale.cancelLabel;
  97             if (typeof options.locale.weekLabel === 'string') this.locale.weekLabel = options.locale.weekLabel;
  98             if (typeof options.locale.customRangeLabel === 'string') this.locale.customRangeLabel = options.locale.customRangeLabel;
  99         }
 100         this.container.addClass(this.locale.direction);
 101         if (typeof options.startDate === 'string') this.startDate = moment(options.startDate, this.locale.format);
 102         if (typeof options.endDate === 'string') this.endDate = moment(options.endDate, this.locale.format);
 103         if (typeof options.minDate === 'string') this.minDate = moment(options.minDate, this.locale.format);
 104         if (typeof options.maxDate === 'string') this.maxDate = moment(options.maxDate, this.locale.format);
 105         if (typeof options.startDate === 'object') this.startDate = moment(options.startDate);
 106         if (typeof options.endDate === 'object') this.endDate = moment(options.endDate);
 107         if (typeof options.minDate === 'object') this.minDate = moment(options.minDate);
 108         if (typeof options.maxDate === 'object') this.maxDate = moment(options.maxDate);
 109         // sanity check for bad options
 110         if (this.minDate && this.startDate.isBefore(this.minDate)) this.startDate = this.minDate.clone();
 111         // sanity check for bad options
 112         if (this.maxDate && this.endDate.isAfter(this.maxDate)) this.endDate = this.maxDate.clone();
 113         if (typeof options.applyClass === 'string') this.applyClass = options.applyClass;
 114         if (typeof options.cancelClass === 'string') this.cancelClass = options.cancelClass;
 115         if (typeof options.dateLimit === 'object') this.dateLimit = options.dateLimit;
 116         if (typeof options.opens === 'string') this.opens = options.opens;
 117         if (typeof options.drops === 'string') this.drops = options.drops;
 118         if (typeof options.showWeekNumbers === 'boolean') this.showWeekNumbers = options.showWeekNumbers;
 119         if (typeof options.showISOWeekNumbers === 'boolean') this.showISOWeekNumbers = options.showISOWeekNumbers;
 120         if (typeof options.buttonClasses === 'string') this.buttonClasses = options.buttonClasses;
 121         if (typeof options.buttonClasses === 'object') this.buttonClasses = options.buttonClasses.join(' ');
 122         if (typeof options.showDropdowns === 'boolean') this.showDropdowns = options.showDropdowns;
 123         if (typeof options.singleDatePicker === 'boolean') {
 124             this.singleDatePicker = options.singleDatePicker;
 125             if (this.singleDatePicker) this.endDate = this.startDate.clone();
 126         }
 127         if (typeof options.timePicker === 'boolean') this.timePicker = options.timePicker;
 128         if (typeof options.timePickerSeconds === 'boolean') this.timePickerSeconds = options.timePickerSeconds;
 129         if (typeof options.timePickerIncrement === 'number') this.timePickerIncrement = options.timePickerIncrement;
 130         if (typeof options.timePicker24Hour === 'boolean') this.timePicker24Hour = options.timePicker24Hour;
 131         if (typeof options.autoApply === 'boolean') this.autoApply = options.autoApply;
 132         if (typeof options.autoUpdateInput === 'boolean') this.autoUpdateInput = options.autoUpdateInput;
 133         if (typeof options.linkedCalendars === 'boolean') this.linkedCalendars = options.linkedCalendars;
 134         if (typeof options.isInvalidDate === 'function') this.isInvalidDate = options.isInvalidDate;
 135         if (typeof options.isCustomDate === 'function') this.isCustomDate = options.isCustomDate;
 136         if (typeof options.alwaysShowCalendars === 'boolean') this.alwaysShowCalendars = options.alwaysShowCalendars;
 137         // update day names order to firstDay
 138         if (this.locale.firstDay != 0) {
 139             var iterator = this.locale.firstDay;
 140             while (iterator > 0) {
 141                 this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
 142                 iterator--;
 143             }
 144         }
 145         var start, end, range;
 146         //if no start/end dates set, check if an input element contains initial values
 147         if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
 148             if ($(this.element).is('input[type=text]')) {
 149                 var val = $(this.element).val(),
 150                     split = val.split(this.locale.separator);
 151                 start = end = null;
 152                 if (split.length == 2) {
 153                     start = moment(split[0], this.locale.format);
 154                     end = moment(split[1], this.locale.format);
 155                 } else if (this.singleDatePicker && val !== "") {
 156                     start = moment(val, this.locale.format);
 157                     end = moment(val, this.locale.format);
 158                 }
 159                 if (start !== null && end !== null) {
 160                     this.setStartDate(start);
 161                     this.setEndDate(end);
 162                 }
 163             }
 164         }
 165         if (typeof options.ranges === 'object') {
 166             for (range in options.ranges) {
 167                 if (typeof options.ranges[range][0] === 'string') start = moment(options.ranges[range][0], this.locale.format);
 168                 else start = moment(options.ranges[range][0]);
 169                 if (typeof options.ranges[range][1] === 'string') end = moment(options.ranges[range][1], this.locale.format);
 170                 else end = moment(options.ranges[range][1]);
 171                 // If the start or end date exceed those allowed by the minDate or dateLimit
 172                 // options, shorten the range to the allowable period.
 173                 if (this.minDate && start.isBefore(this.minDate)) start = this.minDate.clone();
 174                 var maxDate = this.maxDate;
 175                 if (this.dateLimit && maxDate && start.clone().add(this.dateLimit).isAfter(maxDate)) maxDate = start.clone().add(this.dateLimit);
 176                 if (maxDate && end.isAfter(maxDate)) end = maxDate.clone();
 177                 // If the end of the range is before the minimum or the start of the range is
 178                 // after the maximum, don't display this range option at all.
 179                 if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day')) || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day'))) continue;
 180                 //Support unicode chars in the range names.
 181                 var elem = document.createElement('textarea');
 182                 elem.innerHTML = range;
 183                 var rangeHtml = elem.value;
 184                 this.ranges[rangeHtml] = [start, end];
 185             }
 186             var list = '<ul>';
 187             for (range in this.ranges) {
 188                 list += '<li>' + range + '</li>';
 189             }
 190             list += '<li>' + this.locale.customRangeLabel + '</li>';
 191             list += '</ul>';
 192             this.container.find('.ranges').prepend(list);
 193         }
 194         if (typeof cb === 'function') {
 195             this.callback = cb;
 196         }
 197         if (!this.timePicker) {
 198             this.startDate = this.startDate.startOf('day');
 199             this.endDate = this.endDate.endOf('day');
 200             this.container.find('.calendar-time').hide();
 201         }
 202         //can't be used together for now
 203         if (this.timePicker && this.autoApply) this.autoApply = false;
 204         if (this.autoApply && typeof options.ranges !== 'object') {
 205             this.container.find('.ranges').hide();
 206         } else if (this.autoApply) {
 207             this.container.find('.applyBtn, .cancelBtn').addClass('hide');
 208         }
 209         if (this.singleDatePicker) {
 210             this.container.addClass('single');
 211             this.container.find('.calendar.left').addClass('single');
 212             this.container.find('.calendar.left').show();
 213             this.container.find('.calendar.right').hide();
 214             this.container.find('.daterangepicker_input input, .daterangepicker_input > i').hide();
 215             if (!this.timePicker) {
 216                 this.container.find('.ranges').hide();
 217             }
 218         }
 219         if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) {
 220             this.container.addClass('show-calendar');
 221         }
 222         this.container.addClass('opens' + this.opens);
 223         //swap the position of the predefined ranges if opens right
 224         if (typeof options.ranges !== 'undefined' && this.opens == 'right') {
 225             this.container.find('.ranges').prependTo(this.container.find('.calendar.left').parent());
 226         }
 227         //apply CSS classes and labels to buttons
 228         this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
 229         if (this.applyClass.length) this.container.find('.applyBtn').addClass(this.applyClass);
 230         if (this.cancelClass.length) this.container.find('.cancelBtn').addClass(this.cancelClass);
 231         this.container.find('.applyBtn').html(this.locale.applyLabel);
 232         this.container.find('.cancelBtn').html(this.locale.cancelLabel);
 233         //
 234         // event listeners
 235         //
 236         this.container.find('.calendar').on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this)).on('click.daterangepicker', '.next', $.proxy(this.clickNext, this)).on('click.daterangepicker', 'td.available', $.proxy(this.clickDate, this)).on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)).on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this)).on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this)).on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this)).on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)).on('click.daterangepicker', '.daterangepicker_input input', $.proxy(this.showCalendars, this))
 237             //.on('keyup.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this))
 238             .on('change.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this));
 239         this.container.find('.ranges').on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)).on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)).on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)).on('mouseenter.daterangepicker', 'li', $.proxy(this.hoverRange, this)).on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this));
 240         if (this.element.is('input') || this.element.is('button')) {
 241             this.element.on({
 242                 'click.daterangepicker': $.proxy(this.show, this),
 243                 'focus.daterangepicker': $.proxy(this.show, this),
 244                 'keyup.daterangepicker': $.proxy(this.elementChanged, this),
 245                 'keydown.daterangepicker': $.proxy(this.keydown, this)
 246             });
 247         } else {
 248             this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
 249         }
 250         //
 251         // if attached to a text input, set the initial value
 252         //
 253         if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) {
 254             this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
 255             this.element.trigger('change');
 256         } else if (this.element.is('input') && this.autoUpdateInput) {
 257             this.element.val(this.startDate.format(this.locale.format));
 258             this.element.trigger('change');
 259         }
 260     };
 261     DateRangePicker.prototype = {
 262         constructor: DateRangePicker,
 263         setStartDate: function(startDate) {
 264             if (typeof startDate === 'string') this.startDate = moment(startDate, this.locale.format);
 265             if (typeof startDate === 'object') this.startDate = moment(startDate);
 266             if (!this.timePicker) this.startDate = this.startDate.startOf('day');
 267             if (this.timePicker && this.timePickerIncrement) this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
 268             if (this.minDate && this.startDate.isBefore(this.minDate)) {
 269                 this.startDate = this.minDate;
 270                 if (this.timePicker && this.timePickerIncrement) this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
 271             }
 272             if (this.maxDate && this.startDate.isAfter(this.maxDate)) {
 273                 this.startDate = this.maxDate;
 274                 if (this.timePicker && this.timePickerIncrement) this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
 275             }
 276             if (!this.isShowing) this.updateElement();
 277             this.updateMonthsInView();
 278         },
 279         setEndDate: function(endDate) {
 280             if (typeof endDate === 'string') this.endDate = moment(endDate, this.locale.format);
 281             if (typeof endDate === 'object') this.endDate = moment(endDate);
 282             if (!this.timePicker) this.endDate = this.endDate.endOf('day');
 283             if (this.timePicker && this.timePickerIncrement) this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
 284             if (this.endDate.isBefore(this.startDate)) this.endDate = this.startDate.clone();
 285             if (this.maxDate && this.endDate.isAfter(this.maxDate)) this.endDate = this.maxDate;
 286             if (this.dateLimit && this.startDate.clone().add(this.dateLimit).isBefore(this.endDate)) this.endDate = this.startDate.clone().add(this.dateLimit);
 287             this.previousRightTime = this.endDate.clone();
 288             if (!this.isShowing) this.updateElement();
 289             this.updateMonthsInView();
 290         },
 291         isInvalidDate: function() {
 292             return false;
 293         },
 294         isCustomDate: function() {
 295             return false;
 296         },
 297         updateView: function() {
 298             if (this.timePicker) {
 299                 this.renderTimePicker('left');
 300                 this.renderTimePicker('right');
 301                 if (!this.endDate) {
 302                     this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled');
 303                 } else {
 304                     this.container.find('.right .calendar-time select').removeAttr('disabled').removeClass('disabled');
 305                 }
 306             }
 307             if (this.endDate) {
 308                 this.container.find('input[name="daterangepicker_end"]').removeClass('active');
 309                 this.container.find('input[name="daterangepicker_start"]').addClass('active');
 310             } else {
 311                 this.container.find('input[name="daterangepicker_end"]').addClass('active');
 312                 this.container.find('input[name="daterangepicker_start"]').removeClass('active');
 313             }
 314             this.updateMonthsInView();
 315             this.updateCalendars();
 316             this.updateFormInputs();
 317         },
 318         updateMonthsInView: function() {
 319             if (this.endDate) {
 320                 //if both dates are visible already, do nothing
 321                 if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month && (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) && (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))) {
 322                     return;
 323                 }
 324                 this.leftCalendar.month = this.startDate.clone().date(2);
 325                 if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
 326                     this.rightCalendar.month = this.endDate.clone().date(2);
 327                 } else {
 328                     this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
 329                 }
 330             } else {
 331                 if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
 332                     this.leftCalendar.month = this.startDate.clone().date(2);
 333                     this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
 334                 }
 335             }
 336             if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) {
 337                 this.rightCalendar.month = this.maxDate.clone().date(2);
 338                 this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month');
 339             }
 340         },
 341         updateCalendars: function() {
 342             if (this.timePicker) {
 343                 var hour, minute, second;
 344                 if (this.endDate) {
 345                     hour = parseInt(this.container.find('.left .hourselect').val(), 10);
 346                     minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
 347                     second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
 348                     if (!this.timePicker24Hour) {
 349                         var ampm = this.container.find('.left .ampmselect').val();
 350                         if (ampm === 'PM' && hour < 12) hour += 12;
 351                         if (ampm === 'AM' && hour === 12) hour = 0;
 352                     }
 353                 } else {
 354                     hour = parseInt(this.container.find('.right .hourselect').val(), 10);
 355                     minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
 356                     second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
 357                     if (!this.timePicker24Hour) {
 358                         var ampm = this.container.find('.right .ampmselect').val();
 359                         if (ampm === 'PM' && hour < 12) hour += 12;
 360                         if (ampm === 'AM' && hour === 12) hour = 0;
 361                     }
 362                 }
 363                 this.leftCalendar.month.hour(hour).minute(minute).second(second);
 364                 this.rightCalendar.month.hour(hour).minute(minute).second(second);
 365             }
 366             this.renderCalendar('left');
 367             this.renderCalendar('right');
 368             //highlight any predefined range matching the current start and end dates
 369             this.container.find('.ranges li').removeClass('active');
 370             if (this.endDate == null) return;
 371             this.calculateChosenLabel();
 372         },
 373         renderCalendar: function(side) {
 374             //
 375             // Build the matrix of dates that will populate the calendar
 376             //
 377             var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar;
 378             var month = calendar.month.month();
 379             var year = calendar.month.year();
 380             var hour = calendar.month.hour();
 381             var minute = calendar.month.minute();
 382             var second = calendar.month.second();
 383             var daysInMonth = moment([year, month]).daysInMonth();
 384             var firstDay = moment([year, month, 1]);
 385             var lastDay = moment([year, month, daysInMonth]);
 386             var lastMonth = moment(firstDay).subtract(1, 'month').month();
 387             var lastYear = moment(firstDay).subtract(1, 'month').year();
 388             var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
 389             var dayOfWeek = firstDay.day();
 390             //initialize a 6 rows x 7 columns array for the calendar
 391             var calendar = [];
 392             calendar.firstDay = firstDay;
 393             calendar.lastDay = lastDay;
 394             for (var i = 0; i < 6; i++) {
 395                 calendar[i] = [];
 396             }
 397             //populate the calendar with date objects
 398             var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
 399             if (startDay > daysInLastMonth) startDay -= 7;
 400             if (dayOfWeek == this.locale.firstDay) startDay = daysInLastMonth - 6;
 401             var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]);
 402             var col, row;
 403             for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
 404                 if (i > 0 && col % 7 === 0) {
 405                     col = 0;
 406                     row++;
 407                 }
 408                 calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second);
 409                 curDate.hour(12);
 410                 if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') {
 411                     calendar[row][col] = this.minDate.clone();
 412                 }
 413                 if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') {
 414                     calendar[row][col] = this.maxDate.clone();
 415                 }
 416             }
 417             //make the calendar object available to hoverDate/clickDate
 418             if (side == 'left') {
 419                 this.leftCalendar.calendar = calendar;
 420             } else {
 421                 this.rightCalendar.calendar = calendar;
 422             }
 423             //
 424             // Display the calendar
 425             //
 426             var minDate = side == 'left' ? this.minDate : this.startDate;
 427             var maxDate = this.maxDate;
 428             var selected = side == 'left' ? this.startDate : this.endDate;
 429             var arrow = this.locale.direction == 'ltr' ? {
 430                 left: 'chevron-left',
 431                 right: 'chevron-right'
 432             } : {
 433                 left: 'chevron-right',
 434                 right: 'chevron-left'
 435             };
 436             var html = '<table class="table-condensed">';
 437             html += '<thead>';
 438             html += '<tr>';
 439             // add empty cell for week number
 440             if (this.showWeekNumbers || this.showISOWeekNumbers) html += '<th></th>';
 441             if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) {
 442                 html += '<th class="prev available"><i class="fa fa-' + arrow.left + ' glyphicon glyphicon-' + arrow.left + '"></i></th>';
 443             } else {
 444                 html += '<th></th>';
 445             }
 446             var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
 447             if (this.showDropdowns) {
 448                 var currentMonth = calendar[1][1].month();
 449                 var currentYear = calendar[1][1].year();
 450                 var maxYear = (maxDate && maxDate.year()) || (currentYear + 5);
 451                 var minYear = (minDate && minDate.year()) || (currentYear - 50);
 452                 var inMinYear = currentYear == minYear;
 453                 var inMaxYear = currentYear == maxYear;
 454                 var monthHtml = '<select class="monthselect">';
 455                 for (var m = 0; m < 12; m++) {
 456                     if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {
 457                         monthHtml += "<option value='" + m + "'" + (m === currentMonth ? " selected='selected'" : "") + ">" + this.locale.monthNames[m] + "</option>";
 458                     } else {
 459                         monthHtml += "<option value='" + m + "'" + (m === currentMonth ? " selected='selected'" : "") + " disabled='disabled'>" + this.locale.monthNames[m] + "</option>";
 460                     }
 461                 }
 462                 monthHtml += "</select>";
 463                 var yearHtml = '<select class="yearselect">';
 464                 for (var y = minYear; y <= maxYear; y++) {
 465                     yearHtml += '<option value="' + y + '"' + (y === currentYear ? ' selected="selected"' : '') + '>' + y + '</option>';
 466                 }
 467                 yearHtml += '</select>';
 468                 dateHtml = monthHtml + yearHtml;
 469             }
 470             /*myAdd start*/
 471             var yearMonthArr = dateHtml.split('月');
 472             var myVar = {
 473                 lunar: null,
 474                 // classStr:cname.replace(/^\s+|\s+$/g, ''),
 475                 year: parseInt(yearMonthArr[1]),
 476                 month: parseInt(yearMonthArr[0]),
 477                 day: 1,
 478                 lunarDay: null,
 479                 startDate: this.startDate.format('YYYY-MM-DD').split('-'),
 480                 //endDate:('endDate' in this)?this.endDate.format('YYYY-MM-DD').split('-'):null,
 481                 lunarMonth: ''
 482             }
 483             if (this.endDate == null && myVar.startDate[1] == myVar.month && myVar.startDate[0] == myVar.year) {
 484                 // console.log('no endDate')
 485                 myVar.lunar = myCalendar.solar2lunar(myVar.startDate[0], myVar.startDate[1], myVar.startDate[2]);
 486                 myVar.lunarMonth = '(农历 ' + myVar.lunar.IMonthCn + ')';
 487             } else if (this.endDate !== null) {
 488                 //console.log('has endDate')
 489                 myVar.endDate = this.endDate.format('YYYY-MM-DD').split('-');
 490                 if (side == 'left' && myVar.startDate[1] == myVar.month && myVar.startDate[0] == myVar.year) {
 491                     //console.log('left')
 492                     myVar.lunar = myCalendar.solar2lunar(myVar.startDate[0], myVar.startDate[1], myVar.startDate[2]);
 493                     myVar.lunarMonth = '(农历 ' + myVar.lunar.IMonthCn + ')';
 494                 } else if (side == 'right' && myVar.endDate[1] == myVar.month && myVar.endDate[0] == myVar.year) {
 495                     //console.log('right')
 496                     myVar.lunar = myCalendar.solar2lunar(myVar.endDate[0], myVar.endDate[1], myVar.endDate[2]);
 497                     myVar.lunarMonth = '(农历 ' + myVar.lunar.IMonthCn + ')';
 498                 }
 499             }
 500             // console.log(myVar.lunar);
 501             /*myAdd end*/
 502             /*myChange start*/
 503             html += '<th colspan="5" class="month">' + dateHtml + myVar.lunarMonth + '</th>'; //(农历 '+ myVar.lunar.IMonthCn +')
 504             /*myChange end*/
 505             if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) {
 506                 html += '<th class="next available"><i class="fa fa-' + arrow.right + ' glyphicon glyphicon-' + arrow.right + '"></i></th>';
 507             } else {
 508                 html += '<th></th>';
 509             }
 510             html += '</tr>';
 511             html += '<tr>';
 512             // add week number label
 513             if (this.showWeekNumbers || this.showISOWeekNumbers) html += '<th class="week">' + this.locale.weekLabel + '</th>';
 514             $.each(this.locale.daysOfWeek, function(index, dayOfWeek) {
 515                 html += '<th>' + dayOfWeek + '</th>';
 516             });
 517             html += '</tr>';
 518             html += '</thead>';
 519             html += '<tbody>';
 520             //adjust maxDate to reflect the dateLimit setting in order to
 521             //grey out end dates beyond the dateLimit
 522             if (this.endDate == null && this.dateLimit) {
 523                 var maxLimit = this.startDate.clone().add(this.dateLimit).endOf('day');
 524                 if (!maxDate || maxLimit.isBefore(maxDate)) {
 525                     maxDate = maxLimit;
 526                 }
 527             }
 528             for (var row = 0; row < 6; row++) {
 529                 html += '<tr>';
 530                 // add week number
 531                 if (this.showWeekNumbers) html += '<td class="week" weekDateData=' + calendar[row][0].year() + '-' + (calendar[row][0].month() + 1) + '-' + calendar[row][0].date() + '>' + calendar[row][0].week() + '</td>';
 532                 else if (this.showISOWeekNumbers) html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>';
 533                 for (var col = 0; col < 7; col++) {
 534                     var classes = [];
 535                     //highlight today's date
 536                     if (calendar[row][col].isSame(new Date(), "day")) classes.push('today');
 537                     //highlight weekends
 538                     if (calendar[row][col].isoWeekday() > 5) classes.push('weekend');
 539                     //grey out the dates in other months displayed at beginning and end of this calendar
 540                     if (calendar[row][col].month() != calendar[1][1].month()) classes.push('off');
 541                     //don't allow selection of dates before the minimum date
 542                     if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day')) classes.push('off', 'disabled');
 543                     //don't allow selection of dates after the maximum date
 544                     if (maxDate && calendar[row][col].isAfter(maxDate, 'day')) classes.push('off', 'disabled');
 545                     //don't allow selection of date if a custom function decides it's invalid
 546                     if (this.isInvalidDate(calendar[row][col])) classes.push('off', 'disabled');
 547                     //highlight the currently selected start date
 548                     if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) classes.push('active', 'start-date');
 549                     //highlight the currently selected end date
 550                     if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) classes.push('active', 'end-date');
 551                     //highlight dates in-between the selected dates
 552                     if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate) classes.push('in-range');
 553                     //apply custom classes for this date
 554                     var isCustom = this.isCustomDate(calendar[row][col]);
 555                     if (isCustom !== false) {
 556                         if (typeof isCustom === 'string') classes.push(isCustom);
 557                         else Array.prototype.push.apply(classes, isCustom);
 558                     }
 559                     var cname = '',
 560                         disabled = false;
 561                     for (var i = 0; i < classes.length; i++) {
 562                         cname += classes[i] + ' ';
 563                         if (classes[i] == 'disabled') disabled = true;
 564                     }
 565                     if (!disabled) cname += 'available';
 566                     /*myAdd start*/
 567                     myVar.year = parseInt(calendar[row][col].format("YYYY"));
 568                     myVar.month = parseInt(calendar[row][col].month()) + 1;
 569                     myVar.day = calendar[row][col].date();
 570                     myVar.lunar = myCalendar.solar2lunar(myVar.year, myVar.month, myVar.day);
 571                     myVar.lunarDay = myVar.lunar.IDayCn;
 572                     myVar.lunarDayClass = 'lunarDay';
 573                     // console.log(myVar.lunar)
 574                     if (myVar.lunar.Term || myVar.lunar.lunarFestivals || myVar.lunar.calendarFestivals) {
 575                         myVar.lunarDay = myVar.lunar.lunarFestivals || myVar.lunar.calendarFestivals || myVar.lunar.Term;
 576                         myVar.lunarDayClass += ' lunarTerm';
 577                     }
 578                     /*myAdd end*/
 579                     html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '<br /><span class="' + myVar.lunarDayClass + '">' + myVar.lunarDay + '</span></td>';
 580                 }
 581                 html += '</tr>';
 582             }
 583             html += '</tbody>';
 584             html += '</table>';
 585             this.container.find('.calendar.' + side + ' .calendar-table').html(html);
 586         },
 587         renderTimePicker: function(side) {
 588             var html, selected, minDate, maxDate = this.maxDate;
 589             if (this.dateLimit && (!this.maxDate || this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate))) maxDate = this.startDate.clone().add(this.dateLimit);
 590             if (side == 'left') {
 591                 selected = this.startDate.clone();
 592                 minDate = this.minDate;
 593             } else if (side == 'right') {
 594                 selected = this.endDate ? this.endDate.clone() : this.previousRightTime.clone();
 595                 minDate = this.startDate;
 596                 if (selected.isBefore(this.startDate)) selected = this.startDate.clone();
 597                 if (maxDate && selected.isAfter(maxDate)) selected = maxDate.clone();
 598                 //Preserve the time already selected
 599                 var timeSelector = this.container.find('.calendar.right .calendar-time div');
 600                 if (!this.endDate && timeSelector.html() != '') {
 601                     selected.hour(timeSelector.find('.hourselect option:selected').val() || selected.hour());
 602                     selected.minute(timeSelector.find('.minuteselect option:selected').val() || selected.minute());
 603                     selected.second(timeSelector.find('.secondselect option:selected').val() || selected.second());
 604                     if (!this.timePicker24Hour) {
 605                         var ampm = timeSelector.find('.ampmselect option:selected').val();
 606                         if (ampm === 'PM' && selected.hour() < 12) selected.hour(selected.hour() + 12);
 607                         if (ampm === 'AM' && selected.hour() === 12) selected.hour(0);
 608                     }
 609                 }
 610             }
 611             //
 612             // hours
 613             //
 614             html = '<select class="hourselect">';
 615             var start = this.timePicker24Hour ? 0 : 1;
 616             var end = this.timePicker24Hour ? 23 : 12;
 617             for (var i = start; i <= end; i++) {
 618                 var i_in_24 = i;
 619                 if (!this.timePicker24Hour) i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i);
 620                 var time = selected.clone().hour(i_in_24);
 621                 var disabled = false;
 622                 if (minDate && time.minute(59).isBefore(minDate)) disabled = true;
 623                 if (maxDate && time.minute(0).isAfter(maxDate)) disabled = true;
 624                 if (i_in_24 == selected.hour() && !disabled) {
 625                     html += '<option value="' + i + '" selected="selected">' + i + '</option>';
 626                 } else if (disabled) {
 627                     html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>';
 628                 } else {
 629                     html += '<option value="' + i + '">' + i + '</option>';
 630                 }
 631             }
 632             html += '</select> ';
 633             //
 634             // minutes
 635             //
 636             html += ': <select class="minuteselect">';
 637             for (var i = 0; i < 60; i += this.timePickerIncrement) {
 638                 var padded = i < 10 ? '0' + i : i;
 639                 var time = selected.clone().minute(i);
 640                 var disabled = false;
 641                 if (minDate && time.second(59).isBefore(minDate)) disabled = true;
 642                 if (maxDate && time.second(0).isAfter(maxDate)) disabled = true;
 643                 if (selected.minute() == i && !disabled) {
 644                     html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
 645                 } else if (disabled) {
 646                     html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
 647                 } else {
 648                     html += '<option value="' + i + '">' + padded + '</option>';
 649                 }
 650             }
 651             html += '</select> ';
 652             //
 653             // seconds
 654             //
 655             if (this.timePickerSeconds) {
 656                 html += ': <select class="secondselect">';
 657                 for (var i = 0; i < 60; i++) {
 658                     var padded = i < 10 ? '0' + i : i;
 659                     var time = selected.clone().second(i);
 660                     var disabled = false;
 661                     if (minDate && time.isBefore(minDate)) disabled = true;
 662                     if (maxDate && time.isAfter(maxDate)) disabled = true;
 663                     if (selected.second() == i && !disabled) {
 664                         html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
 665                     } else if (disabled) {
 666                         html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
 667                     } else {
 668                         html += '<option value="' + i + '">' + padded + '</option>';
 669                     }
 670                 }
 671                 html += '</select> ';
 672             }
 673             //
 674             // AM/PM
 675             //
 676             if (!this.timePicker24Hour) {
 677                 html += '<select class="ampmselect">';
 678                 var am_html = '';
 679                 var pm_html = '';
 680                 if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate)) am_html = ' disabled="disabled" class="disabled"';
 681                 if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate)) pm_html = ' disabled="disabled" class="disabled"';
 682                 if (selected.hour() >= 12) {
 683                     html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>';
 684                 } else {
 685                     html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>';
 686                 }
 687                 html += '</select>';
 688             }
 689             this.container.find('.calendar.' + side + ' .calendar-time div').html(html);
 690         },
 691         updateFormInputs: function() {
 692             //ignore mouse movements while an above-calendar text input has focus
 693             if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) return;
 694             this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.locale.format));
 695             if (this.endDate) this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.locale.format));
 696             if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) {
 697                 this.container.find('button.applyBtn').removeAttr('disabled');
 698             } else {
 699                 this.container.find('button.applyBtn').attr('disabled', 'disabled');
 700             }
 701         },
 702         move: function() {
 703             var parentOffset = {
 704                     top: 0,
 705                     left: 0
 706                 },
 707                 containerTop;
 708             var parentRightEdge = $(window).width();
 709             if (!this.parentEl.is('body')) {
 710                 parentOffset = {
 711                     top: this.parentEl.offset().top - this.parentEl.scrollTop(),
 712                     left: this.parentEl.offset().left - this.parentEl.scrollLeft()
 713                 };
 714                 parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
 715             }
 716             if (this.drops == 'up') containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
 717             else containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
 718             this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('dropup');
 719             if (this.opens == 'left') {
 720                 this.container.css({
 721                     top: containerTop,
 722                     right: parentRightEdge - this.element.offset().left - this.element.outerWidth(),
 723                     left: 'auto'
 724                 });
 725                 if (this.container.offset().left < 0) {
 726                     this.container.css({
 727                         right: 'auto',
 728                         left: 9
 729                     });
 730                 }
 731             } else if (this.opens == 'center') {
 732                 this.container.css({
 733                     top: containerTop,
 734                     left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 - this.container.outerWidth() / 2,
 735                     right: 'auto'
 736                 });
 737                 if (this.container.offset().left < 0) {
 738                     this.container.css({
 739                         right: 'auto',
 740                         left: 9
 741                     });
 742                 }
 743             } else {
 744                 this.container.css({
 745                     top: containerTop,
 746                     left: this.element.offset().left - parentOffset.left,
 747                     right: 'auto'
 748                 });
 749                 if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {
 750                     this.container.css({
 751                         left: 'auto',
 752                         right: 0
 753                     });
 754                 }
 755             }
 756         },
 757         show: function(e) {
 758             if (this.isShowing) return;
 759             // Create a click proxy that is private to this instance of datepicker, for unbinding
 760             this._outsideClickProxy = $.proxy(function(e) {
 761                 this.outsideClick(e);
 762             }, this);
 763             // Bind global datepicker mousedown for hiding and
 764             $(document).on('mousedown.daterangepicker', this._outsideClickProxy)
 765                 // also support mobile devices
 766                 .on('touchend.daterangepicker', this._outsideClickProxy)
 767                 // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
 768                 .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
 769                 // and also close when focus changes to outside the picker (eg. tabbing between controls)
 770                 .on('focusin.daterangepicker', this._outsideClickProxy);
 771             // Reposition the picker if the window is resized while it's open
 772             $(window).on('resize.daterangepicker', $.proxy(function(e) {
 773                 this.move(e);
 774             }, this));
 775             this.oldStartDate = this.startDate.clone();
 776             this.oldEndDate = this.endDate.clone();
 777             this.previousRightTime = this.endDate.clone();
 778             this.updateView();
 779             this.container.show();
 780             this.move();
 781             this.element.trigger('show.daterangepicker', this);
 782             this.isShowing = true;
 783         },
 784         hide: function(e) {
 785             if (!this.isShowing) return;
 786             //incomplete date selection, revert to last values
 787             if (!this.endDate) {
 788                 this.startDate = this.oldStartDate.clone();
 789                 this.endDate = this.oldEndDate.clone();
 790             }
 791             //if a new date range was selected, invoke the user callback function
 792             if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) this.callback(this.startDate, this.endDate, this.chosenLabel);
 793             //if picker is attached to a text input, update it
 794             this.updateElement();
 795             $(document).off('.daterangepicker');
 796             $(window).off('.daterangepicker');
 797             this.container.hide();
 798             this.element.trigger('hide.daterangepicker', this);
 799             this.isShowing = false;
 800         },
 801         toggle: function(e) {
 802             if (this.isShowing) {
 803                 this.hide();
 804             } else {
 805                 this.show();
 806             }
 807         },
 808         outsideClick: function(e) {
 809             var target = $(e.target);
 810             // if the page is clicked anywhere except within the daterangerpicker/button
 811             // itself then call this.hide()
 812             if (
 813                 // ie modal dialog fix
 814                 e.type == "focusin" || target.closest(this.element).length || target.closest(this.container).length || target.closest('.calendar-table').length) return;
 815             this.hide();
 816         },
 817         showCalendars: function() {
 818             this.container.addClass('show-calendar');
 819             this.move();
 820             this.element.trigger('showCalendar.daterangepicker', this);
 821         },
 822         hideCalendars: function() {
 823             this.container.removeClass('show-calendar');
 824             this.element.trigger('hideCalendar.daterangepicker', this);
 825         },
 826         hoverRange: function(e) {
 827             //ignore mouse movements while an above-calendar text input has focus
 828             if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) return;
 829             var label = e.target.innerHTML;
 830             if (label == this.locale.customRangeLabel) {
 831                 this.updateView();
 832             } else {
 833                 var dates = this.ranges[label];
 834                 this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.locale.format));
 835                 this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.locale.format));
 836             }
 837         },
 838         clickRange: function(e) {
 839             var label = e.target.innerHTML;
 840             this.chosenLabel = label;
 841             if (label == this.locale.customRangeLabel) {
 842                 this.showCalendars();
 843             } else {
 844                 var dates = this.ranges[label];
 845                 this.startDate = dates[0];
 846                 this.endDate = dates[1];
 847                 if (!this.timePicker) {
 848                     this.startDate.startOf('day');
 849                     this.endDate.endOf('day');
 850                 }
 851                 if (!this.alwaysShowCalendars) this.hideCalendars();
 852                 this.clickApply();
 853             }
 854         },
 855         clickPrev: function(e) {
 856             var cal = $(e.target).parents('.calendar');
 857             if (cal.hasClass('left')) {
 858                 this.leftCalendar.month.subtract(1, 'month');
 859                 if (this.linkedCalendars) this.rightCalendar.month.subtract(1, 'month');
 860             } else {
 861                 this.rightCalendar.month.subtract(1, 'month');
 862             }
 863             this.updateCalendars();
 864         },
 865         clickNext: function(e) {
 866             var cal = $(e.target).parents('.calendar');
 867             if (cal.hasClass('left')) {
 868                 this.leftCalendar.month.add(1, 'month');
 869             } else {
 870                 this.rightCalendar.month.add(1, 'month');
 871                 if (this.linkedCalendars) this.leftCalendar.month.add(1, 'month');
 872             }
 873             this.updateCalendars();
 874         },
 875         hoverDate: function(e) {
 876             //ignore mouse movements while an above-calendar text input has focus
 877             if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) return;
 878             //ignore dates that can't be selected
 879             if (!$(e.target).hasClass('available')) return;
 880             //have the text inputs above calendars reflect the date being hovered over
 881             var title = $(e.target).attr('data-title');
 882             var row = title.substr(1, 1);
 883             var col = title.substr(3, 1);
 884             var cal = $(e.target).parents('.calendar');
 885             var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
 886             if (this.endDate) {
 887                 this.container.find('input[name=daterangepicker_start]').val(date.format(this.locale.format));
 888             } else {
 889                 this.container.find('input[name=daterangepicker_end]').val(date.format(this.locale.format));
 890             }
 891             //highlight the dates between the start date and the date being hovered as a potential end date
 892             var leftCalendar = this.leftCalendar;
 893             var rightCalendar = this.rightCalendar;
 894             var startDate = this.startDate;
 895             if (!this.endDate) {
 896                 this.container.find('.calendar td').each(function(index, el) {
 897                     //skip week numbers, only look at dates
 898                     if ($(el).hasClass('week')) return;
 899                     var title = $(el).attr('data-title');
 900                     var row = title.substr(1, 1);
 901                     var col = title.substr(3, 1);
 902                     var cal = $(el).parents('.calendar');
 903                     var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
 904                     if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) {
 905                         $(el).addClass('in-range');
 906                     } else {
 907                         $(el).removeClass('in-range');
 908                     }
 909                 });
 910             }
 911         },
 912         clickDate: function(e) {
 913             if (!$(e.target).hasClass('available')) return;
 914             var title = $(e.target).attr('data-title');
 915             var row = title.substr(1, 1);
 916             var col = title.substr(3, 1);
 917             var cal = $(e.target).parents('.calendar');
 918             var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
 919             //
 920             // this function needs to do a few things:
 921             // * alternate between selecting a start and end date for the range,
 922             // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date
 923             // * if autoapply is enabled, and an end date was chosen, apply the selection
 924             // * if single date picker mode, and time picker isn't enabled, apply the selection immediately
 925             //
 926             if (this.endDate || date.isBefore(this.startDate, 'day')) {
 927                 if (this.timePicker) {
 928                     var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
 929                     if (!this.timePicker24Hour) {
 930                         var ampm = this.container.find('.left .ampmselect').val();
 931                         if (ampm === 'PM' && hour < 12) hour += 12;
 932                         if (ampm === 'AM' && hour === 12) hour = 0;
 933                     }
 934                     var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
 935                     var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
 936                     date = date.clone().hour(hour).minute(minute).second(second);
 937                 }
 938                 this.endDate = null;
 939                 this.setStartDate(date.clone());
 940             } else if (!this.endDate && date.isBefore(this.startDate)) {
 941                 //special case: clicking the same date for start/end,
 942                 //but the time of the end date is before the start date
 943                 this.setEndDate(this.startDate.clone());
 944             } else {
 945                 if (this.timePicker) {
 946                     var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
 947                     if (!this.timePicker24Hour) {
 948                         var ampm = this.container.find('.right .ampmselect').val();
 949                         if (ampm === 'PM' && hour < 12) hour += 12;
 950                         if (ampm === 'AM' && hour === 12) hour = 0;
 951                     }
 952                     var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
 953                     var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
 954                     date = date.clone().hour(hour).minute(minute).second(second);
 955                 }
 956                 this.setEndDate(date.clone());
 957                 if (this.autoApply) {
 958                     this.calculateChosenLabel();
 959                     this.clickApply();
 960                 }
 961             }
 962             if (this.singleDatePicker) {
 963                 this.setEndDate(this.startDate);
 964                 if (!this.timePicker) this.clickApply();
 965             }
 966             this.updateView();
 967         },
 968         calculateChosenLabel: function() {
 969             var customRange = true;
 970             var i = 0;
 971             for (var range in this.ranges) {
 972                 if (this.timePicker) {
 973                     if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) {
 974                         customRange = false;
 975                         this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html();
 976                         break;
 977                     }
 978                 } else {
 979                     //ignore times when comparing dates if time picker is not enabled
 980                     if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {
 981                         customRange = false;
 982                         this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html();
 983                         break;
 984                     }
 985                 }
 986                 i++;
 987             }
 988             if (customRange) {
 989                 this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html();
 990                 this.showCalendars();
 991             }
 992         },
 993         clickApply: function(e) {
 994             this.hide();
 995             this.element.trigger('apply.daterangepicker', this);
 996         },
 997         clickCancel: function(e) {
 998             this.startDate = this.oldStartDate;
 999             this.endDate = this.oldEndDate;
1000             this.hide();
1001             this.element.trigger('cancel.daterangepicker', this);
1002         },
1003         monthOrYearChanged: function(e) {
1004             var isLeft = $(e.target).closest('.calendar').hasClass('left'),
1005                 leftOrRight = isLeft ? 'left' : 'right',
1006                 cal = this.container.find('.calendar.' + leftOrRight);
1007             // Month must be Number for new moment versions
1008             var month = parseInt(cal.find('.monthselect').val(), 10);
1009             var year = cal.find('.yearselect').val();
1010             if (!isLeft) {
1011                 if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {
1012                     month = this.startDate.month();
1013                     year = this.startDate.year();
1014                 }
1015             }
1016             if (this.minDate) {
1017                 if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) {
1018                     month = this.minDate.month();
1019                     year = this.minDate.year();
1020                 }
1021             }
1022             if (this.maxDate) {
1023                 if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) {
1024                     month = this.maxDate.month();
1025                     year = this.maxDate.year();
1026                 }
1027             }
1028             if (isLeft) {
1029                 this.leftCalendar.month.month(month).year(year);
1030                 if (this.linkedCalendars) this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month');
1031             } else {
1032                 this.rightCalendar.month.month(month).year(year);
1033                 if (this.linkedCalendars) this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month');
1034             }
1035             this.updateCalendars();
1036         },
1037         timeChanged: function(e) {
1038             var cal = $(e.target).closest('.calendar'),
1039                 isLeft = cal.hasClass('left');
1040             var hour = parseInt(cal.find('.hourselect').val(), 10);
1041             var minute = parseInt(cal.find('.minuteselect').val(), 10);
1042             var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0;
1043             if (!this.timePicker24Hour) {
1044                 var ampm = cal.find('.ampmselect').val();
1045                 if (ampm === 'PM' && hour < 12) hour += 12;
1046                 if (ampm === 'AM' && hour === 12) hour = 0;
1047             }
1048             if (isLeft) {
1049                 var start = this.startDate.clone();
1050                 start.hour(hour);
1051                 start.minute(minute);
1052                 start.second(second);
1053                 this.setStartDate(start);
1054                 if (this.singleDatePicker) {
1055                     this.endDate = this.startDate.clone();
1056                 } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) {
1057                     this.setEndDate(start.clone());
1058                 }
1059             } else if (this.endDate) {
1060                 var end = this.endDate.clone();
1061                 end.hour(hour);
1062                 end.minute(minute);
1063                 end.second(second);
1064                 this.setEndDate(end);
1065             }
1066             //update the calendars so all clickable dates reflect the new time component
1067             this.updateCalendars();
1068             //update the form inputs above the calendars with the new time
1069             this.updateFormInputs();
1070             //re-render the time pickers because changing one selection can affect what's enabled in another
1071             this.renderTimePicker('left');
1072             this.renderTimePicker('right');
1073         },
1074         formInputsChanged: function(e) {
1075             var isRight = $(e.target).closest('.calendar').hasClass('right');
1076             var start = moment(this.container.find('input[name="daterangepicker_start"]').val(), this.locale.format);
1077             var end = moment(this.container.find('input[name="daterangepicker_end"]').val(), this.locale.format);
1078             if (start.isValid() && end.isValid()) {
1079                 if (isRight && end.isBefore(start)) start = end.clone();
1080                 this.setStartDate(start);
1081                 this.setEndDate(end);
1082                 if (isRight) {
1083                     this.container.find('input[name="daterangepicker_start"]').val(this.startDate.format(this.locale.format));
1084                 } else {
1085                     this.container.find('input[name="daterangepicker_end"]').val(this.endDate.format(this.locale.format));
1086                 }
1087             }
1088             this.updateCalendars();
1089             if (this.timePicker) {
1090                 this.renderTimePicker('left');
1091                 this.renderTimePicker('right');
1092             }
1093         },
1094         elementChanged: function() {
1095             if (!this.element.is('input')) return;
1096             if (!this.element.val().length) return;
1097             if (this.element.val().length < this.locale.format.length) return;
1098             var dateString = this.element.val().split(this.locale.separator),
1099                 start = null,
1100                 end = null;
1101             if (dateString.length === 2) {
1102                 start = moment(dateString[0], this.locale.format);
1103                 end = moment(dateString[1], this.locale.format);
1104             }
1105             if (this.singleDatePicker || start === null || end === null) {
1106                 start = moment(this.element.val(), this.locale.format);
1107                 end = start;
1108             }
1109             if (!start.isValid() || !end.isValid()) return;
1110             this.setStartDate(start);
1111             this.setEndDate(end);
1112             this.updateView();
1113         },
1114         keydown: function(e) {
1115             //hide on tab or enter
1116             if ((e.keyCode === 9) || (e.keyCode === 13)) {
1117                 this.hide();
1118             }
1119         },
1120         updateElement: function() {
1121             if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) {
1122                 this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
1123                 this.element.trigger('change');
1124             } else if (this.element.is('input') && this.autoUpdateInput) {
1125                 this.element.val(this.startDate.format(this.locale.format));
1126                 this.element.trigger('change');
1127             }
1128         },
1129         remove: function() {
1130             this.container.remove();
1131             this.element.off('.daterangepicker');
1132             this.element.removeData();
1133         }
1134     };
1135     $.fn.daterangepicker = function(options, callback) {
1136         this.each(function() {
1137             var el = $(this);
1138             if (el.data('daterangepicker')) el.data('daterangepicker').remove();
1139             el.data('daterangepicker', new DateRangePicker(el, options, callback));
1140         });
1141         return this;
1142     };
1143     return DateRangePicker;
1144 }));
View Code

 

调用方式没有任何改变,效果图:

不过存在一个问题,就是选择日期的时候点击农历日期无效,要点击公历日期(即数字)才能选中。

 

posted @ 2016-11-25 11:45  zhengtulym  阅读(1542)  评论(0编辑  收藏  举报