繁体   English   中英

使用JavaScript进行巧妙的时间格式化

[英]Clever time formatting with JavaScript

我需要编写一些正则表达式以将整数替换为文本输入字段中的时间格式字符串的帮助。

在我的表单中:我有一个文本输入字段,应该在其中输入数字。 当我写一个数字时:当输入字段失去焦点时,我想用一段JavaScript将其转换为对人类友好的可读时间。 使这个“聪明”的一件事是,我希望能够尽可能地少写:并将其转换为与我的号码相对应的最合适的时间。

让我举几个例子。 如果我写:

7 it would resolve to 07:00
15 it would resolve to 15:00
93 it would resolve to 09:30
1945 it would resolve to 19:45
143 it would resolve to 14:30
... And so on ...

我希望它在输入字段失去焦点之后执行此替换( onblur -event)

也。 我想在夜间设置0前缀。 像这样:

015 = 00:15
 03 = 00:30
012 = 00:12 
... And so on ...

我开始编写if语句来执行此操作,但是我停滞不前,因为我意识到if语句会花费很多,而且不是很可靠。 我觉得正则表达式会更聪明,因为它可以压缩脚本并缩短加载时间。 我掌握了正则表达式的基础知识,但是我不知道如何为此编写一个聪明的表达式。

这是我的代码决定删除之前要达到的目的:

var elem = document.getElementById("incidentHourStart-" + row);

if (elem.value.length === 1) {
    // Must be a whole hour (0-9)
} else if (elem.value.length === 2) {
    // Can be either two digits hour (10-23) or hour + whole minute (73: 07:30)
    if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
        // Two digits, whole hour (10-23)
    } else {
        // First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)   
    }

} else if (elem.value.length === 3) {
    // First digit must be an hour value, middle digit is also hour if it is lower than 23, last digit is then always whole minutes
    if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
        // Two digits, whole hour (10-23)
    } else {
        // First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)   
    }
} else if (elem.value.length === 4) {
    // First two digits must be an hour value, last digits is then fine selected minutes

}

如您所见:看起来非常难看!


更新:

如评论中所述:人们发现我的规则有些混乱。 所以这是我希望它遵循的规则的伪代码。 如果可以巧妙地将其放入正则表达式中:太棒了! 如果不是:我将写出if/else块,或按照建议将Regex分成几部分。

If text-length is equal to 1
    Resolve as whole hour between 0-9

    Examples:
        2 = 02:00
        8 = 08:00
        5 = 05:00

If text-length is equal to 2 AND number is between 10 and 23
    Resolve as whole hour between 10-23

    Examples:
        15 = 15:00
        11 = 11:00
        22 = 22:00

If text-length is equal to 2 AND number is NOT between 10 and 23
    Resolve as whole hour and minutes incremented by 10's (10, 20, 30, 40, 50)

    Examples:
        73 = 07:30
        24 = 02:40
        95 = 09:50

If text-length is equal to 3 AND first two numbers are between 10 and 23
    Resolve two first digits as hours and last digit as minutes incremented by 10's (10, 20, 30, 40, 50)

    Examples:
        133 = 13:30
        195 = 19:50
        111 = 11:10
        162 = 16:20

If text-length is equal to 3 AND first two numbers are NOT between 10 and 23
    Resolve first digit as whole hour, and last two as minutes.

    Examples:
        225 = 02:25
        922 = 09:22
        557 = 05:57
        451 = 04:51

If text-length is equal to 1 AND first digit is equal to 0
    Resolve as mid-night

    Example:
        0 = 00:00

If text-length is equal to 2 AND first digit is equal to 0
    Resolve as mid-night + minutes incremented by 10's (10, 20, 30, 40, 50)

    Examples:
        02 = 00:20
        05 = 00:50
        03 = 00:30

If text-length is equal to 3 AND first digit is equal to 0
    Resolve as mid-night + full minutes.

    Examples:
        024 = 00:24
        011 = 00:11
        056 = 00:56

If text-length is equal to 4
    Resolve as regular minutes and hours without the colon (:)

    Examples:
        1524 = 15:24
        2211 = 22:11

不要让自己变得比自己更难。 简单的说; 不要在一个正则表达式中执行此操作。 同样不要忘记在使用RegEx之前先修剪输入。

首先检查以零开头的前缀,例如:

^0(\d+)$

然后,如果不匹配,请检查常规编号,并根据需要将其与捕获组分开:

^([^0]\d{1,3})$ // Can do negative lookbehind here, but I left it simple in this case

正则表达式经常被误用于以一种模式解决更大的问题。 如果情况需要,最好拆分逻辑。 不要使代码过于复杂。 它将破坏以后需要阅读它的人的大脑。

我找到了一个解决方案,并将其部署了大约1.5个月。 到目前为止:效果很好。 我的同事喜欢此功能,确实节省了很多时间! 到目前为止:尚未向我报告任何错误。


所以这就是我所做的:

我基本上按照问题注释中的if/else块将伪代码重新编写为实际的JavaScript代码。 我将其全部粘贴到我在输入字段上的onblur事件中调用的函数中。 像这样:

<input type="text" id="incidentHourStart-1" onblur="resolveTimeField(1);">

因此,一旦输入字段失去焦点,就会进行格式化。

这是我的函数:

function resolveTimeField(row) {
    var elem = document.getElementById("incidentHourStart-" + row);

    if (elem.value.length === 1) {

        // Must be a whole hour (0-9)
        elem.value = "0" + elem.value + ":00";

    } else if (elem.value.length === 2) {

        // Can be either two digits hour (10-23) or hour + whole minute (73: 07:30)
        if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
            // Two digits, whole hour (10-23)
            elem.value = elem.value + ":00";
        } else {
            // First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)

            var hours = elem.value.substring(0, 1);
            var minutes = elem.value.substring(1, 2);
            elem.value = "0" + hours + ":" + minutes + "0";

        }
    } else if (elem.value.length === 3) {

        // First digit must be an hour value, middle digit is also hour if it is lower than 23, last digit is then always whole minutes
        var firstDigits = elem.value.substring(0, 2);

        if (parseInt(firstDigits) >= 10 && parseInt(firstDigits) <= 23) {

            // 3 digits, first two are hours, and last digit is minutes incremented by 10's
            var hours = elem.value.substring(0, 2);
            var minutes = elem.value.substring(2, 3);
            elem.value = hours + ":" + minutes + "0";

        } else {

            // First digit is hour, and last two is full minutes
            var hours = elem.value.substring(0, 1);
            var minutes = elem.value.substring(1, 3);
            elem.value = "0" + hours + ":" + minutes;

        }
    } else if (elem.value.length === 4) {

        // First two digits must be an hour value, last digits is then fine selected minutes
        var hours = elem.value.substring(0, 2);
        var minutes = elem.value.substring(2, 4);
        elem.value = hours + ":" + minutes;

    }
}

如果您想自己测试代码,这是一个JSFiddle

我的函数采用一个引用为row参数。 这是因为我正在使用的字段位于一个动态表中,该动态表使我的同事可以一次性注册更多数据。

当前,它没有任何形式的输入验证来检查插入的值是否有效。 因此,您可以在字段中写入999之类的内容,并将其解析为09:99 对于我们的环境来说,这不是关键特性,但是我可以想象,如果需要的话,实现起来会相当容易。 如果以后再实现这种验证功能,我将更新此帖子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM