JavaScript解析不带日期的时间

73

我需要在代码中解析和操作不带日期的时间。例如,我可能会从时间选择器中得到字符串“15:00”。我想将其转换为某种类型的时间对象 - 我通常使用具有独立日期、时间和日期时间对象的Python。

然而,我看到的所有解决方案都集中于使用日期对象。这不能解析像“15:00”这样的字符串,因为它需要天信息。我不想向时间添加任意日期信息 - 特别是因为日期似乎根据日期和语言环境对诸如夏令时之类的事情做出假设,并且存在自动尝试将时间转换为给定语言环境的风险。此外,我想能够添加时间,例如“15:00 + 1小时”

如何推荐解析和处理与日期无关的“原始”时间?


如果您不想编写自己的代码来完成此操作,可以使用Moment.jsDate.js - Pointy
我建议你自己写几行代码来实现。因为这个问题很简单,也没有时间上的限制。 - Denys Séguret
1
这正是我希望避免的。Moment.js和Date.js都专注于DateTime,而不是Time,因此在使用之前仍然需要将任意日期信息粘合到时间上。我可以想象它的实现并不基本复杂,但我很惊讶为什么这种功能还不存在。 - mangecoeur
2
日期包括时间,你知道的,所以只需处理1970年1月1日,完成后丢弃剩余部分。这些额外的数据信息并不会减慢时间操作的速度... - dandavis
8个回答

89

这里有一个 moment.js 的解决方案,适用于 12 或 24 小时制时间:

moment('7:00 am', ['h:m a', 'H:m']); // Wed Dec 30 2015 07:00:00 GMT-0600 (CST)
moment('17:00', ['h:m a', 'H:m']);   // Wed Dec 30 2015 17:00:00 GMT-0600 (CST)
moment('17:00 am', ['h:m a', 'H:m']);// Wed Dec 30 2015 17:00:00 GMT-0600 (CST)
moment('17:00 pm', ['h:m a', 'H:m']);// Wed Dec 30 2015 17:00:00 GMT-0600 (CST)

http://momentjs.com/docs/#/parsing/string-formats/


2
我已经找了一整天了。 - Samuel Thompson
1
哇...这就是它!基本上,对于我的(可能也是OP的)用例来说,日期不重要。只需要将时间字符串转换为有效的momentjs对象。想想其他网站上的所有帖子都在谈论这样的“不幸”和“不可能”,呵呵。谢谢你! - Sun Lee
1
@SunLee,“不可能”只是另一份工作 :-) - Michael Cole
1
这可能会在夏令时时刻让你措手不及。 - jiroch
那是一个非常戏剧化的编程日。 - Michael Cole

26

很不幸,目前没有一个完美的解决方案。JavaScript只有一个Date对象,但这个名称可能是错误的,因为它实际上是日期时间。

你可能需要更深入地思考一件事情 - 你说你只想处理时间,但是你指的是“一天中的特定时间”还是“一段时间的长度”?这是两个相关但略有不同的概念。

例如,你说你可能需要一个操作,比如“15:00 + 1小时”。很明显,无论如何都应该是16:00。但是如果是“15:00 + 10小时”呢?如果你说的是一段时间,那么它将变成25:00,但如果你是在讲特定时间,那么它可能是01:00。

实际上,它可能并不是01:00,因为并不是所有的一天都有24小时。某些天有23、23.5、24.5或25小时,这取决于时区以及夏令时是否在那一天开始或停止。因此,在特定时间的上下文中,你可能需要在计算中包括一个特定的日期和时区。当然,如果你在谈论纯粹的24小时日子,那么这一点就无关紧要了。

如果你在谈论“时间长度”,你可能需要再看一下moment.js,但不是moment对象。那里有另一个对象,moment.duration。参考文档在这里

最后,你可能需要考虑使用纯JavaScript将时间字符串解析为小时和分钟的数字。根据需要进行操作,然后再输出一个字符串。但是你的问题似乎是在寻求更管理的解决方案。


4
很遗憾,我正在寻找“时间点”,而不是持续时间(因此moment.js无法使用)。看起来没有托管的解决方案,我必须使用正则表达式字符串解析 - 这很遗憾,因为这种琐碎的工作容易出现微妙的错误,我更喜欢由经过充分测试的库处理。 - mangecoeur
如果你能将这个时间与特定的日期联系起来,那么Date或者moment仍然是一个好主意。但是如果它总是独立的(比如餐厅每周每天的营业时间),边界情况就会更加复杂。我不知道有哪些好的js库可以处理这种情况,抱歉。 - Matt Johnson-Pint
2
这个有什么变化吗?我需要在JavaScript中完全分离的时间(小时和分钟)。 - codewise

21

由于我已经在应用程序中使用了 moment,所以最终我使用了以下内容:

var str = '15:16:33';
var d = new moment(str, 'HH:mm:ss');

参见Moment String+Format文档,了解其他可用的格式字符串。


5

我知道我比这个聚会晚了8年,但值得注意的是,moment.js已经不再开发,并且正在维护上节奏。他们实际上不建议在新应用程序中使用moment.js。

更多详细信息请参见此处:https://momentjs.com/docs/


2

最近我为一个项目需要做这件事,但实际上并不需要包含moment.js。我使用的方法是手动解析时间,像这样:

function parseTime(time) {    
    let timeInt = parseInt(time);
    let minutes = time.substring(3,5);

    // you could then add or subtract time here as needed

    if(time > '12:00') {
         return `${timeInt - 12}:${minutes} PM`;
    } else {
         return `${timeInt}:${minutes} AM`;
    }
}

如果您不想使用moment,可以将此内容作为替代的启动程序。请注意,此示例使用es6语法。


1
我们知道在JavaScript中,Date类必须始终包含一个日期,仅输入时间是不够的。
但是当被询问时,我不需要输入日期。这可能意味着:
  • 您打算将两个日期进行比较。
  • 这两个日期共享同一天。
如果是这样,那么作为一个技巧,您可以将一个特定的日期(任何日期)作为字符串添加到您的时间中。(例如:0000-01-01
例如,以下代码是不正确的:

var d1 = '00:53:57.123';
var d2 = '00:53:58.124';
console.log(new Date(d2).getTime() - new Date(d1).getTime());
//result: NaN

但是这样你可以得到正确的结果:

var d1 = '00:53:57.123';
var d2 = '00:53:58.124';
d1 = '0000-01-01 ' + d1;
d2 = '0000-01-01 ' + d2;
console.log(new Date(d2).getTime() - new Date(d1).getTime());
//result: 1001


1

好的,我知道我来晚了。像是迟了6年,但这是我需要解决的问题,我需要将其格式化为HH:mm:ss(24小时制)。

moment().format(moment.HTML5_FMT.TIME_SECONDS); // 17:44:56

您也可以传递参数,如 2019-11-08T17:44:56.144

moment('2019-11-08T17:44:56.144').format(moment.HTML5_FMT.TIME_SECONDS); // 17:44:56

https://momentjs.com/docs/#/parsing/special-formats/


0

我知道我是在8年后写这篇文章的,但现在不建议使用moment.js库,因为它已经不再受支持了。luxo.js是首选(就像moments.js的进化版),你可以在这里找到更多信息:https://moment.github.io/luxon/api-docs/index.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接