日期处理是前端框架中的核心需求,Ext JS 自然也不例外。Ext.Date 作为一套完善的日期操作工具集,对 JavaScript 原生 Date 对象的功能进行了系统化扩展,在日常开发中几乎每天都会用到。下面我们将最常用的功能逐一拆解,并附上代码示例,方便开发者直接使用。

首先介绍基础函数,它们构成了日期操作的核心骨架:
- Ext.Date.add() —— 为日期增加或减少指定的时间单位,不会修改原对象,返回新的日期实例。
- Ext.Date.between() —— 判断一个日期是否介于另外两个日期之间。
- Ext.Date.clearTime() —— 将日期的时间部分清零(设置为 00:00:00.000)。
- Ext.Date.clone() —— 复制一个日期对象。
- Ext.Date.format() —— 按指定格式输出日期字符串。
- Ext.Date.getDayOfYear() —— 获取该日期在当年中是第几天。
- Ext.Date.getDaysInMonth() —— 获取该日期所在月份的总天数。
- Ext.Date.getFirstDateOfMonth() —— 返回当月第一天的日期。
- Ext.Date.getFirstDayOfMonth() —— 返回当月第一天的星期索引。
- Ext.Date.getLastDateOfMonth() —— 返回当月最后一天的日期。
- Ext.Date.getLastDayOfMonth() —— 返回当月最后一天的星期索引。
- Ext.Date.getWeekOfYear() —— 获取该日期在当年中是第几周(遵循 ISO-8601 标准)。
- Ext.Date.isLeapYear() —— 判断该日期所在的年份是否为闰年。
- Ext.Date.now() —— 返回当前时间的时间戳(毫秒),Chrome、IE9+ 等浏览器已原生支持
Date.now()。 - Ext.Date.parse() —— 根据指定格式从字符串解析日期。
仅罗列函数名称还不够,下面展示一组实际调用的代码,一目了然:
// Ext.Date.add(date, interval, value)
var date = Ext.Date.add(new Date('10/29/2006'), Ext.Date.DAY, 5); // 增加5天
console.log(date); // Fri Nov 03 2006 00:00:00 GMT+0800 (中国标准时间)
var date = Ext.Date.add(new Date('10/29/2006'), Ext.Date.DAY, -5); // 减少5天
console.log(date); // Tue Oct 24 2006 00:00:00 GMT+0800 (中国标准时间)
var date = Ext.Date.add(new Date('10/29/2006'), Ext.Date.YEAR, 2); // 增加2年
console.log(date); // Wed Oct 29 2008 00:00:00 GMT+0800 (中国标准时间)
// Ext.Date.between(date, start, end)
var date = new Date('10/29/2006');
var start = new Date('10/5/2006');
var end = new Date('11/15/2006');
Ext.Date.between(date, start, end); // true
// Ext.Date.clearTime(date, clone)
var date = new Date('10/30/2012 14:30:00');
Ext.Date.clearTime(date); // Tue Oct 30 2012 00:00:00 GMT+0800 (中国标准时间)
// Ext.Date.clone(date)
var orig = new Date('10/30/2012');
var copy = Ext.Date.clone(orig);
// Ext.Date.format(date, format)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.format(date, 'Y-m-d H:i:s'); // "2012-10-20 14:30:00"
Ext.Date.format(date, 'Y年m月d日 H:i:s'); // "2012年10月20日 14:30:00"
// Ext.Date.getDayOfYear(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getDayOfYear(date); // 293
// Ext.Date.getDaysInMonth(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getDayOfYear(date); // 31
// Ext.Date.getFirstDateOfMonth(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getFirstDateOfMonth(date); // Mon Oct 01 2012 00:00:00 GMT+0800 (中国标准时间)
// Ext.Date.getFirstDayOfMonth(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getFirstDayOfMonth(date); // 1 (星期一)
// Ext.Date.getLastDateOfMonth(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getLastDateOfMonth(date); // Wed Oct 31 2012 00:00:00 GMT+0800 (中国标准时间)
// Ext.Date.getLastDayOfMonth(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getLastDayOfMonth(date); // 3 (星期三)
// Ext.Date.getWeekOfYear(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.getWeekOfYear(date); // 42
// Ext.Date.isLeapYear(date)
var date = new Date('10/20/2012 14:30:00');
Ext.Date.isLeapYear(date); // true
// Ext.Date.now()
var timestamp = Ext.Date.now(); // 1351666679575
var date = new Date(timestamp); // Wed Oct 31 2012 14:57:59 GMT+0800 (中国标准时间)
// Ext.Date.parse(input, format, strict)
var input = '2012年10月31日 14:30:00';
var format = 'Y年m月d日 H:i:s';
var date = Ext.Date.parse(input, format, true); // Wed Oct 31 2012 14:30:00 GMT+0800 (中国标准时间)
实战:实现带周数显示的日期选择控件
1. 问题
许多人认为使用 Ext JS 可以完美解决星期显示问题,但实际上并非如此。本系列前文曾提到,Ext 自带的 datepicker 控件并未直接显示周数,需要自行扩展。在扩展过程中,会遇到一个棘手的矛盾:
JavaScript 原生的 Date 对象认为一周从星期日开始(getDay() 返回 0 表示星期日)。而 Ext.Date.getWeekOfYear 遵循 ISO-8601 标准,一周从星期一开始。这就造成了混用标准时的混乱。
具体表现为:
- Ext 的日期选择控件界面默认从星期日开始排列(S M T W T F S),但使用
getWeekOfYear获取选中日期的周数时,结果却按星期一开始计算。每个星期日会被误算为前一周的结尾(例如 2013/08/18 是星期日,本应是第 34 周,却返回 33 周)。 - 控件默认显示 42 天(6 周),跨年时会出现歧义:某一天究竟是所属年份的第 53 周,还是下一年的第 1 周?
2. 解决方案
既然官方 API 存在标准冲突,那就自己编写一个兼容方案:结合 JavaScript 原生的 Date 对象和 Ext JS 的 Ext.Date,实现一个可靠的周数字符串生成函数。
核心规则如下:
- 每周以星期日为第一天。
- 每年的周数范围 1~52,如果计算出的周数超过 52,则归入下一年的第 1 周。例如 2013/12/29 原本是第 53 周,处理后被算作 2014 年第 1 周。
- 输出格式为 “W1334” 这样的字符串(W + 两位年份 + 两位周数)。
/*
* 返回格式如 W1334(代表 2013年第34周)
* 规则:
* 1. 星期日 -> 周数 +1(因为 Ext.getWeekOfYear 以周一为起点)
* 2. 如果周数 > 52 -> 年份+1,周数-52
* 3. 如果月份=11(12月)且周数<2 -> 年份+1
*/
function getWeekStrOfDate(date)
{
var weekStr = null;
if(date!=null)
{
weekStr = "W";
var dateYear = date.getFullYear();
var dateWeek = Ext.Date.getWeekOfYear(date);
var firstDayOfMonth = Ext.Date.getFirstDayOfMonth(date);
var day = date.getDate();
var month = date.getMonth();
// weekday 0-6
var weekday = date.getDay();
if(weekday===0)
{
dateWeek++;
}
// week > 52 -> year +1
if(month==11)
{
if(dateWeek>52)
{
dateYear += 1;
dateWeek -= 52;
}else if(dateWeek<2){
dateYear += 1;
}
}
var yearStr = dateYear.toString();
yearStr = yearStr.substring(2,4);
var dateWeekStr = dateWeek.toString();
if(dateWeekStr.length<2)
{
dateWeekStr = "0" + dateWeekStr;
}
weekStr += yearStr;
weekStr += dateWeekStr;
}
return weekStr;
}
这段代码已在实际项目中运行过,基本能够覆盖常见的跨年边界情况和星期日特殊处理。如果在实现日期选择控件时需要显示周数,直接使用这个函数即可,省去反复调试的麻烦。
