返回深入学习ExtJS 2.2开发系列连载教程目录
ExtJS支持Date中代表特殊含义字母。我们可以根据该字符来自定义所需时间格式。如需要的格式如下:today is sunday,its dateTime is:2007-08-02。我们可以采用dateObject.format(“today is sunday,its dateTime is:2007-08-02”)吗?不行,因为today单词中的所有字母都代表特殊含义。但是不让它代表特殊含义怎么办?反转义。采用//t形式来反转义其特殊含义为其本身字母。
它的使用不难,但是我得考虑其是如何实现的。实现过程当然得从对表3.6中特殊字符进行解析开始。如果判断了其字符是Y,就通过getFullYear从日期中取到四位年的数值替换Y字符所在位置。其它字符处理相似。接下问题是反转义字符的解析,如果解析到/字符时(在字符串/字符是通过//来表示的)。那么就判断其下一个字符不需要解析直接放在原来位置上。
接下我们考虑其性能,在日常中要用的时间格式不就是那么几种,如Y-m-d等。如果每一次调用时都要解析格式会影响性能,能不能重用之前解析相同的格式转换呢。ExtJS对格式转换采用了编译方法,第一次需要编译,之后就可以重用,提高了性能。我们先从data.Format入口来分析其实现:
日期和时间是日常生活中不可缺少的部分,在软件中也不可避免地使用它们。JavaScript提供了Date对象来处理日期和时间。一个Date对象代表一个具体的时间,Date对象也提供了一些属性和方法来方便们对于时间操作。ExtJS对JS Date对象进行极大地扩展,使用日期和时间变得极为简单。下面我们就从原生Date和ExtJS进行的扩展两个方面来介绍。|
函数 |
说明 |
例子 |
|
toString() |
转换为字符串。 |
Sat Sep 6 10:10:31 UTC+0800 2008 |
|
toTimeString() |
时间部分转换为字符串。 |
10:10:31 UTC+0800 |
|
toDateString() |
日期部分转换为字符串。 |
Sat Sep 6 2008 |
|
toGMTString() |
转换为格林威治时字符串。 |
Sat, 6 Sep 2008 02:10:31 UTC |
|
toUTCString() |
转换为世界时字符串。 |
Sat, 6 Sep 2008 02:10:31 UTC |
|
toLocaleString() |
转换为本地时字符串。 |
2008年9月6日 10:10:31 |
|
toLocaleTimeString() |
时间部分转换本地时字符串 |
10:10:31 |
|
toLocaleDateString() |
日期部分转换本地时字符串 |
2008年9月6日 |
表3.4 Date的toString函数
在上表中可以看出tostring给出的信息最完全的,不但有日期,时间、星期,还有时差。而GTM的时间与UTC的时间是则是相同的。而在实际应用中,可能并不需要日期时间等综合体,而是需要某一部分,如今天是星期几等。时间单元可以分成如下8种:Year,month,date,day.hour,minutes,second,milliseconds。Date对象对这8种最小单元分别给出其操作函数。|
函数 |
说明 |
例子 |
|
getFullYear() |
返回四位数字年份 |
2008 |
|
getYear() |
返回两位或四位数字年份。 |
2008 (108 FF中) |
|
getUTCFullYear() |
返回四位数字年份 |
2008 |
|
getMonth() |
返回月份 (0 ~ 11) |
8 |
|
getUTCMonth() |
返回月份 (0 ~ 11) |
8 |
|
getDate() |
返回月中的某一天 (1 ~ 31) |
6 |
|
getUTCDate() |
返回月中的一天 (1 ~ 31) |
6 |
|
getHours() |
返回的小时 (0 ~ 23) |
10 |
|
getUTCHours() |
返回小时 (0 ~ 23) |
2 |
|
getMinutes() |
返回分钟 (0 ~ 59) |
41 |
|
getUTCMinutes() |
返回分钟 (0 ~ 59) |
41 |
|
getSeconds() |
返回秒数 (0 ~ 59)) |
3 |
|
getUTCSeconds() |
返回秒钟 (0 ~ 59) |
3 |
|
getMilliseconds() |
返回 毫秒(0 ~ 999) |
187 |
|
getUTCMilliseconds() |
返回毫秒(0 ~ 999) |
187 |
|
getDay() |
返回星期 (0 ~ 6) |
6 |
|
getUTCDay() |
返回星期(0 ~ 6) |
6 |
|
getTime() |
返回毫秒数 |
1220668863187 |
|
getTimezoneOffset() |
返回时差 (GMT) |
-480(以分为单位 东8区) |
表3.5 Date的时间函数
|
字母 |
说明 |
例子 |
|
年份字母表义 |
||
|
Y |
四位数的年 |
2008 |
|
y |
二位数的年 |
08 |
|
o |
四位数的年 |
2007 |
|
月份字母表义 |
||
|
m |
不足二位采用0填充的月份 |
01~12 |
|
n |
不采用0填充的月份 |
1~12 |
|
M |
短文本的月份 |
Jan 至Dec |
|
F |
长文本的月份 |
January至December |
|
t |
月份中的天数 |
28,29,30,31四种 |
|
日期字母表义 |
||
|
d |
不足二位采用0填充的日期 |
01~31 |
|
j |
不采用0填充的日期 |
1~31 |
|
日期字母表义 |
||
|
N |
星期几的数字 |
1~7(星期一~天) |
|
D |
星期几的短文本 |
Mon 至 Sun |
|
l |
星期几的长文本 |
Sunday ~aturday |
|
w |
星期几的数字 |
0~6(星期天~六) |
|
常用的判断 |
||
|
W |
当前星期是当前年中第几周(周一开始) |
0~53 |
|
Z |
当前日期是当前年中第几天(0开始) |
234 |
|
L |
当前年是否为闰年(1:是,0不是) |
0 |
|
S |
判断日期以0,1,2,3之一为最后一个数字 |
St(1), nd(2), rd(3),th(0) |
|
小时及上午下午 |
||
|
a |
上午还是下午 |
am或pm |
|
A |
上午还是下午 |
AM或PM |
|
g |
12小时制(不补0) |
1~12 |
|
G |
24小时制(不补0) |
0~23 |
|
h |
12小时制(补0) |
01~12 |
|
H |
24小时制(补0) |
00~23 |
|
分钞 |
||
|
i |
分钟 |
00~59 |
|
s |
钞 |
00~59 |
|
u |
毫秒 |
000~999 |
|
时区 |
||
|
P |
时区 |
-08:00 |
|
T |
时区(缩写) |
EST, |
|
Z |
时区以秒为单位 |
-43200 |
|
综合的时间 |
||
|
c |
Iso的日期格式 |
2007-04-17T15:19:21+08:00 |
|
U |
Times以毫秒为单位 |
1193432466 |
表3.6 Date的特殊字符含义
Date.prototype.dateFormat = function(format) { 
if(Date.formatFunctions[format]== null)...{ //如果未找到编译格式则创建
Date.createNewFormat(format);}
var func = Date.formatFunctions[format];
return this[func]();}; //找到了就直接调用编译过格式。
Date.prototype.format = Date.prototype.dateFormat;
Date.createNewFormat = function(format) {
var funcName = "format" +Date.formatFunctions.count++;//编译格式函数名
Date.formatFunctions[format] = funcName; 
var code = "Date.prototype." + funcName + " = function()...{return "
Date.getFormatCode = function(character) { 
switch (character) ...{
case "d": return "String.leftPad(this.getDate(), 2, '0') + ";
.. .. ..
case "l": return "Date.dayNames[this.getDay()] + "; ①
case "N": return "(this.getDay() ? this.getDay() : 7) + ";
.. .. ..
case "U": return "Math.round(this.getTime() / 1000) + ";
default: return "'" + String.escape(character) + "' + ";
}};
点击展开示例
Date.createParser = function(format) {
var funcName = "parse" + Date.parseFunctions.count++;
var regexNum = Date.parseRegexes.length; //regexp数组的原来的长度 ①
var currentGroup = 1;
Date.parseFunctions[format] = funcName;

var code = "Date." + funcName + " = function(input)...{\n" ②
+ "var y =-1,m = -1,d = -1,h = -1,i = -1,s =-1,ms = -1,o,z,u,v;\n"
+ "input = String(input);var d = new Date();\n"
+ "y = d.getFullYear();\n"+"m =d.getMonth();\n"+ "d = d.getDate();\n"
+"var results=input.match(Date.parseRegexes["+regexNum + "]);\n" ③

+ "if (results && results.length > 0) ...{";;
var regex = "", c, ch = '';

for (var i = 0; i < format.length; ++i) ...{ ④
ch = format.charAt(i);
if (!special && ch == "\\") ...{special = true; }
else if (special) ...{special = false; regex += String.escape(ch); }

else ...{ var obj = Date.formatCodeToRegex(ch, currentGroup); ⑤
currentGroup += obj.g;
regex += obj.s;
if (obj.g && obj.c) ...{ code += obj.c; } } }
code += "if (u)\n ...{v = new Date(u * 1000);}" ⑥
+ "else if (y>=0&&m>=0&&d>0&&h>= 0 && i >= 0 && s >= 0 && ms >= 0)\n"
+ "...{v = new Date(y, m, d, h, i, s, ms);}\n"
+ "else if (y>= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
+ "...{v = new Date(y, m, d, h, i, s);}\n"
+ "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
+ "...{v = new Date(y, m, d, h, i);}\n"
+ "else if (y>=0&&m>=0&&d>0&&h>=0)\n"+ "...{v = new Date(y, m, d, h);}\n"
+ "else if (y >= 0 && m >= 0 && d > 0)\n" + "...{v = new Date(y, m, d);}\n"
+ "else if (y >= 0 && m >= 0)\n" + "...{v = new Date(y, m);}\n"
+ "else if (y >= 0)\n" + "...{v = new Date(y);}\n"
+ "}
+ " (z ? v.add(Date.SECOND,(v.getTimezoneOffset()*60) + (z*1)) :\n" + " v.add(Date.HOUR, (v.getGMTOffset()/100)+ (o/-100))):v\n"+";};
Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i"); ⑦
eval(code);} return (v && (z || o))?\n""
d: { g:1, c:"d = parseInt(results[{0}], 10);\n", s:"(\\d{2})" }
var special = false, ch = ''; 
for (var i = 0; i < format.length; ++i) ...{
ch = format.charAt(i);
if (!special && ch == "\\") ...{special = true; } ① 
else if (special) ...{special = false;
code += "'" + String.escape(ch) + "' + "; } ②
else ...{code += Date.getFormatCode(ch); } } ③
eval(code.substring(0, code.length - 3) + ";}");};