如何从 JavaScript 中的用户输入将时间解析为 Date 对象?

新手上路,请多包涵

我正在开发一个表单小部件,供用户将一天中的时间输入文本输入(用于日历应用程序)。使用 JavaScript(我们正在使用 jQuery FWIW),我想找到解析用户输入到 JavaScript Date() 对象的文本的最佳方法,这样我就可以轻松地对其进行比较和其他操作。

我尝试了 parse() 方法,它对我的需要来说有点太挑剔了。我希望它能够将以下示例输入时间(除了其他逻辑上相似的时间格式之外)成功解析为相同的 Date() 对象:

  • 1:00 PM
  • 1:00 PM
  • 下午 1:00
  • 1:00 PM
  • 1:00 PM。
  • 下午 1:00
  • 下午 1 点
  • 下午 1 点
  • 1页
  • 下午 1 点
  • 下午 1 点
  • 1p
  • 13:00
  • 13

我在想我可能会使用正则表达式来拆分输入并提取我想用来创建我的 Date() 对象的信息。做这个的最好方式是什么?

原文由 Joe Lencioni 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 516
2 个回答

适用于您指定的输入的快速解决方案:

 function parseTime( t ) {
   var d = new Date();
   var time = t.match( /(\d+)(?::(\d\d))?\s*(p?)/ );
   d.setHours( parseInt( time[1]) + (time[3] ? 12 : 0) );
   d.setMinutes( parseInt( time[2]) || 0 );
   return d;
}

var tests = [
  '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm',
  '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400',
  '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p',
  '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ];

for ( var i = 0; i < tests.length; i++ ) {
  console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) );
}

它也应该适用于其他一些品种(例如,即使使用 am,它仍然有效)。显然,这很粗糙,但它也很轻巧(例如,使用它比使用完整的库便宜得多)。

警告:该代码不适用于 12:00 AM 等。

原文由 John Resig 发布,翻译遵循 CC BY-SA 3.0 许可协议

提供的所有示例在凌晨 12:00 到 12:59 期间都无法正常工作。如果正则表达式与时间不匹配,它们也会抛出错误。以下处理这个:

 function parseTime(timeString) {
	if (timeString == '') return null;

	var time = timeString.match(/(\d+)(:(\d\d))?\s*(p?)/i);
	if (time == null) return null;

	var hours = parseInt(time[1],10);
	if (hours == 12 && !time[4]) {
		  hours = 0;
	}
	else {
		hours += (hours < 12 && time[4])? 12 : 0;
	}
	var d = new Date();
	d.setHours(hours);
	d.setMinutes(parseInt(time[3],10) || 0);
	d.setSeconds(0, 0);
	return d;
}

var tests = [
  '1:00 pm','1:00 p.m.','1:00 p','1:00pm','1:00p.m.','1:00p','1 pm',
  '1 p.m.','1 p','1pm','1p.m.', '1p', '13:00','13', '1a', '12', '12a', '12p', '12am', '12pm', '2400am', '2400pm', '2400',
  '1000', '100', '123', '2459', '2359', '2359am', '1100', '123p',
  '1234', '1', '9', '99', '999', '9999', '99999', '0000', '0011', '-1', 'mioaw' ];

for ( var i = 0; i < tests.length; i++ ) {
  console.log( tests[i].padStart( 9, ' ' ) + " = " + parseTime(tests[i]) );
}

这将适用于在其中任何位置包含时间的字符串。所以“abcde12:00pmdef”将被解析并返回中午 12 点。如果期望的结果是它只返回一个时间,而字符串中只包含一个时间,则可以使用以下正则表达式,前提是您将“time[4]”替换为“time[6]”。

 /^(\d+)(:(\d\d))?\s*((a|(p))m?)?$/i

原文由 Nathan Villaescusa 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题