Javascript 如何正确组织此功能?
我正在扩展插件中的日期过滤器,以允许用户配置日期格式,即Javascript 如何正确组织此功能?,javascript,jquery,validation,date,Javascript,Jquery,Validation,Date,我正在扩展插件中的日期过滤器,以允许用户配置日期格式,即dd/mm/yyyy,mm-dd-yyyy。。。到目前为止,我得到的是: date: { regex: function (input, value) { var // Just grabbing some info from the plugin... data = input.userOptions.data ? input.userOptions.data.date
dd/mm/yyyy
,mm-dd-yyyy
。。。到目前为止,我得到的是:
date: {
regex: function (input, value) {
var
// Just grabbing some info from the plugin...
data = input.userOptions.data
? input.userOptions.data.date
: { format: 'mm/dd/yyyy' }, // default format
separator = '\\' + /[^mdy]/.exec(data.format)[0], // extract separator
userFormat = data.format.replace(/[^mdy]/g, ''), // convert to proper format
isDate = function (m, d, y) {
return m > 0 &&
m < 13 &&
y > 0 &&
y < 32768 &&
d > 0 &&
d <= (new Date(y, m, 0)).getDate()
},
n2 = '(\\d{1,2})', // day and month
n4 = '(\\d{4})', // year
format = {
'mmddyyyy': function () {
var re = new RegExp(n2 + separator + n2 + separator + n4),
m = re.exec(value)
return m && isDate(m[1], m[2], m[3])
},
'ddmmyyyy': function () {
var re = new RegExp(n2 + separator + n2 + separator + n4),
m = re.exec(value)
return m && isDate(m[2], m[1], m[3])
},
'yyyymmdd': function () {
var re = new RegExp(n4 + separator + n2 + separator + n2),
m = re.exec(value)
return m && isDate(m[2], m[3], m[1])
},
'yyyyddmm': function () {
var re = new RegExp(n4 + separator + n2 + separator + n2),
m = re.exec(value)
return m && isDate(m[3], m[2], m[1])
}
}
return format[userFormat]() || format['mmddyyyy']()
},
日期:{
正则表达式:函数(输入,值){
变量
//只是从插件中获取一些信息。。。
data=input.userOptions.data
?input.userOptions.data.date
:{格式:'mm/dd/yyyy'},//默认格式
分隔符='\'+/[^mdy]/.exec(data.format)[0],//提取分隔符
userFormat=data.format.replace(//[^mdy]/g','),//转换为正确的格式
isDate=函数(m,d,y){
返回m>0&&
m<13&&
y>0&&
y<32768&&
d>0&&
编辑
我也想谈谈您关于返回isDate
的评论。函数的行为与预期一致,问题在别处。我没有对您的代码进行足够的分析,以说明错误在哪里,但isDate
是正确的:
原始答案
我很幸运地看到了这段代码的变体:
基本上,它在日期对象中实现了一个fromString
方法。我不喜欢这种方法,所以我将实现修改为独立函数,并消除了一些不必要的位。也就是说,它工作得很好
基本思想是首先对输入进行规范化。因为您永远不知道用户是否给您提供了类似于1.11.2011
或3~12~2012
的格式,所以首先要做的就是去除噪音:
data = data.replace(/[^:a-z0-9]/g, '-');
我们正在丢弃所有非字母数字字符,并加入一个-
,您似乎更喜欢/
——不管怎样,只要输入一致即可。我们保留字母,这样我们也可以处理2012年3月18日的
然后,代码段解析输入,提取时间(如果给定,则使用:标识),然后确定一年。正如评论中所指出的,日和月以最合理的格式彼此相邻,因此你要确定什么不是年,并从那里开始。然后是一个排除过程,以确定月,然后是日
不是我的代码,所以我不想因为这个想法而受到赞扬,但再次强调,这个东西是按照广告宣传的那样交付的。您可以按原样使用它(BSD许可证),或者通读源代码并剖析这个概念
以下是代码,供子孙后代使用:
/**
* @author Joey Mazzarelli
* @website http://bitbucket.org/mazzarelli/js-date/
* @website http://joey.mazzarelli.com/2008/11/25/easy-date-parsing-with-javascript/
* @copyright Joey Mazzarelli
* @license BSD license
*/
Date.fromString = (function () {
var defaults = {
order : 'MDY',
strict : false
};
var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC"];
var abs = ["AM", "PM", "AFTERNOON", "MORNING"];
var mark = function (str, val) {
var lval = val.toLowerCase();
var regex = new RegExp('^' + lval + '|(.*[^:alpha:])' + lval, 'g');
return str.replace(regex, '$1' + val);
};
var normalize = function (str) {
str = str.toLowerCase();
str = str.replace(/[^:a-z0-9]/g, '-');
for (var i=0; i<months.length; i++) str = mark(str, months[i]);
for (var i=0; i<abs.length; i++) str = mark(str, abs[i]);
str = str.replace(/[a-z]/g, '');
str = str.replace(/([0-9])([A-Z])/g, '$1-$2');
str = ('-' + str + '-').replace(/-+/g, '-');
return str;
};
var find_time = function (norm) {
var obj = {date:norm, time:''};
obj.time = norm.replace(
/^.*-(\d\d?(:\d\d){1,2}(:\d\d\d)?(-(AM|PM))?)-.*$/, '$1');
if (obj.time == obj.date)
obj.time = norm.replace(/^.*-(\d\d?-(AM|PM))-.*$/, '$1');
if (obj.time == obj.date) obj.time = '';
obj.date = norm.replace(obj.time, '');
obj.time = ('-' + obj.time + '-').replace(/-+/g, '-');
obj.date = ('-' + obj.date + '-').replace(/-+/g, '-');
return obj;
};
var find_year = function (norm) {
var year = null;
// Check for a 4-digit year
year = norm.replace(/^.*-(\d\d\d\d)-.*$/, '$1');
if (year != norm) return year; else year = null;
// Check for a 2-digit year, over 32.
year = norm.replace(/^.*-((3[2-9])|([4-9][0-9]))-.*$/, '$1');
if (year != norm) return year; else year = null;
// Day is always by month, so check for explicit months in
// first or third spot
year = norm.replace(/^.*-[A-Z]{3}-\d\d?-(\d\d?)-.*$/, '$1');
if (year != norm) return year; else year = null;
year = norm.replace(/^.*-(\d\d?)-\d\d?-[A-Z]{3}-.*$/, '$1');
if (year != norm) return year; else year = null;
// If all else fails, use the setting for the position of the year.
var pos = '$3';
if (defaults.opts.order.charAt(0) == 'Y') pos = '$1';
else if (defaults.opts.order.charAt(1) == 'Y') pos = '$2';
year = norm.replace(/^.*-(\d\d?)-([A-Z]{3}|\d{1,2})-(\d\d?)-.*$/, pos);
if (year != norm) return year; else year = null;
return year;
};
var find_month = function (norm, year) {
// Check for an explicity month
var matches = norm.match(/[A-Z]{3}/);
if (matches && matches.length) return matches[0];
// Remove the year, and unless obviously wrong, use order
// to chose which one to use for month.
var parts = norm.replace(year + '-', '').split('-');
if (parts.length != 4) return null;
var order = defaults.opts.order;
var md = order.indexOf('M') < order.indexOf('D')? 1: 2;
return (parseInt(parts[md], 10) <= 12)? parts[md]: parts[md==1? 2: 1];
};
var find_day = function (norm, year, month) {
return norm.replace(year, '').replace(month, '').replace(/-/g, '');
};
var create_absolute = function (obj) {
var time = obj.time.replace(/[-APM]/g, '');
var parts = time.split(':');
parts[1] = parts[1] || 0;
parts[2] = parts[2] || 0;
parts[3] = parts[3] || 0;
var ihr = parseInt(parts[0], 10);
if (obj.time.match(/-AM-/) && ihr == 12) parts[0] = 0;
else if (obj.time.match(/-PM-/) && ihr < 12) parts[0] = ihr + 12;
parts[0] = ("0" + parts[0]).substring(("0" + parts[0]).length - 2);
parts[1] = ("0" + parts[1]).substring(("0" + parts[1]).length - 2);
parts[2] = ("0" + parts[2]).substring(("0" + parts[2]).length - 2);
time = parts[0] + ":" + parts[1] + ":" + parts[2];
var millisecs = parts[3];
var strict = defaults.opts.strict;
if (!obj.year && !strict) obj.year = (new Date()).getFullYear();
var year = parseInt(obj.year, 10);
if (year < 100) {
year += (year<70? 2000: 1900);
}
if (!obj.month && !strict) obj.month = (new Date()).getMonth() + 1;
var month = String(obj.month);
if (month.match(/[A-Z]{3}/)) {
month = "JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-"
.indexOf(month) / 4 + 1;
}
month = ("0" + month).substring(("0" + month).length - 2);
if (!obj.day && !strict) obj.day = (new Date()).getDate();
var day = ("0" + obj.day).substring(("0" + obj.day).length - 2);
var date = new Date();
date.setTime(Date.parse(year + '/' + month + '/' + day + ' ' + time));
date.setMilliseconds(millisecs);
return date;
};
var parse = function (norm) {
return absolute(norm);
};
var absolute = function (norm) {
var obj = find_time(norm);
obj.norm = norm;
obj.year = find_year(obj.date);
obj.month = find_month(obj.date, obj.year);
obj.day = find_day(obj.date, obj.year, obj.month);
return create_absolute(obj);
};
return function (fuzz, opts) {
defaults.opts = { order: defaults.order, strict: defaults.strict };
if (opts && opts.order) defaults.opts.order = opts.order;
if (opts && opts.strict != undefined) defaults.opts.strict = opts.strict;
var date = parse(normalize(fuzz));
return date;
};
})();
/**
*@作者Joey Mazzarelli
*@网站http://bitbucket.org/mazzarelli/js-date/
*@网站http://joey.mazzarelli.com/2008/11/25/easy-date-parsing-with-javascript/
*@版权所有Joey Mazzarelli
*@license-BSD-license
*/
Date.fromString=(函数(){
var默认值={
订单:“MDY”,
严格:假
};
风险值月份=[“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”、“八月”,
“九月”、“十月”、“十一月”、“十二月”];
var abs=[“上午”、“下午”、“下午”、“上午”];
变量标记=函数(str,val){
var lval=val.toLowerCase();
var regex=new RegExp('^'+lval+'|(.*[^:alpha:])'+lval,'g');
返回str.replace(正则表达式,$1'+val);
};
var normalize=函数(str){
str=str.toLowerCase();
str=str.replace(/[^:a-z0-9]/g,'-');
对于(var i=0;i编辑
我也想谈谈您关于返回isDate
的评论。函数的行为与预期一致,问题在别处。我没有对您的代码进行足够的分析,以说明错误在哪里,但isDate
是正确的:
原始答案
我很幸运地看到了这段代码的变体:
基本上,它在日期对象中实现了一个fromString
方法。我不喜欢这种方法,所以我将实现修改为独立函数,并消除了一些不必要的位。也就是说,它工作得很好
基本思想是首先对输入进行规范化。因为您永远不知道用户是否给您提供了类似于1.11.2011
或3~12~2012
的格式,所以首先要做的就是去除噪音:
data = data.replace(/[^:a-z0-9]/g, '-');
我们正在丢弃所有非字母数字字符,并加入一个-
,您似乎更喜欢/
——不管怎样,只要输入一致即可。我们保留字母,这样我们也可以处理2012年3月18日的
然后,代码段解析输入,提取时间(如果给定,则使用:标识),然后确定一年。正如评论中所指出的,日和月以最合理的格式彼此相邻,因此你要确定什么不是年,并从那里开始。然后是一个排除过程,以确定月,然后是日
不是我的代码,所以我不想因为这个想法而受到赞扬,但再次强调,这个东西是按照广告宣传的那样交付的。您可以按原样使用它(BSD许可证),或者通读源代码并剖析这个概念
以下是代码,供子孙后代使用:
/**
* @author Joey Mazzarelli
* @website http://bitbucket.org/mazzarelli/js-date/
* @website http://joey.mazzarelli.com/2008/11/25/easy-date-parsing-with-javascript/
* @copyright Joey Mazzarelli
* @license BSD license
*/
Date.fromString = (function () {
var defaults = {
order : 'MDY',
strict : false
};
var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC"];
var abs = ["AM", "PM", "AFTERNOON", "MORNING"];
var mark = function (str, val) {
var lval = val.toLowerCase();
var regex = new RegExp('^' + lval + '|(.*[^:alpha:])' + lval, 'g');
return str.replace(regex, '$1' + val);
};
var normalize = function (str) {
str = str.toLowerCase();
str = str.replace(/[^:a-z0-9]/g, '-');
for (var i=0; i<months.length; i++) str = mark(str, months[i]);
for (var i=0; i<abs.length; i++) str = mark(str, abs[i]);
str = str.replace(/[a-z]/g, '');
str = str.replace(/([0-9])([A-Z])/g, '$1-$2');
str = ('-' + str + '-').replace(/-+/g, '-');
return str;
};
var find_time = function (norm) {
var obj = {date:norm, time:''};
obj.time = norm.replace(
/^.*-(\d\d?(:\d\d){1,2}(:\d\d\d)?(-(AM|PM))?)-.*$/, '$1');
if (obj.time == obj.date)
obj.time = norm.replace(/^.*-(\d\d?-(AM|PM))-.*$/, '$1');
if (obj.time == obj.date) obj.time = '';
obj.date = norm.replace(obj.time, '');
obj.time = ('-' + obj.time + '-').replace(/-+/g, '-');
obj.date = ('-' + obj.date + '-').replace(/-+/g, '-');
return obj;
};
var find_year = function (norm) {
var year = null;
// Check for a 4-digit year
year = norm.replace(/^.*-(\d\d\d\d)-.*$/, '$1');
if (year != norm) return year; else year = null;
// Check for a 2-digit year, over 32.
year = norm.replace(/^.*-((3[2-9])|([4-9][0-9]))-.*$/, '$1');
if (year != norm) return year; else year = null;
// Day is always by month, so check for explicit months in
// first or third spot
year = norm.replace(/^.*-[A-Z]{3}-\d\d?-(\d\d?)-.*$/, '$1');
if (year != norm) return year; else year = null;
year = norm.replace(/^.*-(\d\d?)-\d\d?-[A-Z]{3}-.*$/, '$1');
if (year != norm) return year; else year = null;
// If all else fails, use the setting for the position of the year.
var pos = '$3';
if (defaults.opts.order.charAt(0) == 'Y') pos = '$1';
else if (defaults.opts.order.charAt(1) == 'Y') pos = '$2';
year = norm.replace(/^.*-(\d\d?)-([A-Z]{3}|\d{1,2})-(\d\d?)-.*$/, pos);
if (year != norm) return year; else year = null;
return year;
};
var find_month = function (norm, year) {
// Check for an explicity month
var matches = norm.match(/[A-Z]{3}/);
if (matches && matches.length) return matches[0];
// Remove the year, and unless obviously wrong, use order
// to chose which one to use for month.
var parts = norm.replace(year + '-', '').split('-');
if (parts.length != 4) return null;
var order = defaults.opts.order;
var md = order.indexOf('M') < order.indexOf('D')? 1: 2;
return (parseInt(parts[md], 10) <= 12)? parts[md]: parts[md==1? 2: 1];
};
var find_day = function (norm, year, month) {
return norm.replace(year, '').replace(month, '').replace(/-/g, '');
};
var create_absolute = function (obj) {
var time = obj.time.replace(/[-APM]/g, '');
var parts = time.split(':');
parts[1] = parts[1] || 0;
parts[2] = parts[2] || 0;
parts[3] = parts[3] || 0;
var ihr = parseInt(parts[0], 10);
if (obj.time.match(/-AM-/) && ihr == 12) parts[0] = 0;
else if (obj.time.match(/-PM-/) && ihr < 12) parts[0] = ihr + 12;
parts[0] = ("0" + parts[0]).substring(("0" + parts[0]).length - 2);
parts[1] = ("0" + parts[1]).substring(("0" + parts[1]).length - 2);
parts[2] = ("0" + parts[2]).substring(("0" + parts[2]).length - 2);
time = parts[0] + ":" + parts[1] + ":" + parts[2];
var millisecs = parts[3];
var strict = defaults.opts.strict;
if (!obj.year && !strict) obj.year = (new Date()).getFullYear();
var year = parseInt(obj.year, 10);
if (year < 100) {
year += (year<70? 2000: 1900);
}
if (!obj.month && !strict) obj.month = (new Date()).getMonth() + 1;
var month = String(obj.month);
if (month.match(/[A-Z]{3}/)) {
month = "JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-"
.indexOf(month) / 4 + 1;
}
month = ("0" + month).substring(("0" + month).length - 2);
if (!obj.day && !strict) obj.day = (new Date()).getDate();
var day = ("0" + obj.day).substring(("0" + obj.day).length - 2);
var date = new Date();
date.setTime(Date.parse(year + '/' + month + '/' + day + ' ' + time));
date.setMilliseconds(millisecs);
return date;
};
var parse = function (norm) {
return absolute(norm);
};
var absolute = function (norm) {
var obj = find_time(norm);
obj.norm = norm;
obj.year = find_year(obj.date);
obj.month = find_month(obj.date, obj.year);
obj.day = find_day(obj.date, obj.year, obj.month);
return create_absolute(obj);
};
return function (fuzz, opts) {
defaults.opts = { order: defaults.order, strict: defaults.strict };
if (opts && opts.order) defaults.opts.order = opts.order;
if (opts && opts.strict != undefined) defaults.opts.strict = opts.strict;
var date = parse(normalize(fuzz));
return date;
};
})();
/**
*@作者Joey Mazzarelli
*@网站http://bitbucket.org/mazzarelli/js-date/
*@网站http://joey.mazzarelli.com/2008/11/25/easy-date-parsing-with-javascript/
*@版权所有Joey Mazzarelli
*@license-BSD-license
*/
Date.fromString=(函数(){
var默认值={
订单:“MDY”,
严格:假
};
风险值月份=[“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”、“八月”,
“九月”、“十月”、“十一月”、“十二月”];
var abs=[“上午”、“下午”、“下午”、“上午”];
变量标记=函数(str,val){
var lval=val.toLowerCase();
var regex=new RegExp('^'+lval+'|(.*[^:alpha:])'+lval,'g');
返回str.replace(正则表达式,$1'+val);
};
var normalize=函数(str){
str=str.toLowerCase();
str=str.replace(/[^:a-z0-9]/g,'-');
对于(var i=0;i您希望13-13-1986
返回什么?1-13-1987
或无效日期为null/false?那么13-13-1986
显然应该返回false