javascript regex iso datetime

前端 未结 9 1933
没有蜡笔的小新
没有蜡笔的小新 2020-12-02 16:31

does anyone have a good regex pattern for matching iso datetimes?

ie: 2010-06-15T00:00:00

9条回答
  •  既然无缘
    2020-12-02 17:19

    The ISO 8601 specification allows a wide variety of date formats. There's a mediocre explanation as to how to do it here. There is a fairly minor discrepancy between how Javascript's date input formatting and the ISO formatting for simple dates which do not specify timezones, and it can be easily mitigated using a string substitution. Fully supporting the ISO-8601 specification is non-trivial.

    Here is a reference example which I do not guarantee to be complete, although it parses the non-duration dates from the aforementioned Wikipedia page.

    Below is an example, and you can also see it's output on ideone. Unfortunately, it does not work to specification as it does not properly implement weeks. The definition of the week number 01 in ISO-8601 is non-trivial and requires some browsing the calendar to determine where week one begins, and what exactly it means in terms of the number of days in the specified year. This can probably be fairly easily corrected (I'm just tired of playing with it).

    function parseISODate (input) {
        var iso = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;
    
        var parts = input.match(iso);
    
        if (parts == null) {
            throw new Error("Invalid Date");
        }
    
        var year = Number(parts[1]);
    
        if (typeof parts[2] != "undefined") {
            /* Convert weeks to days, months 0 */
            var weeks = Number(parts[2]) - 1;
            var days  = Number(parts[3]);
    
            if (typeof days == "undefined") {
                days = 0;
            }
    
            days += weeks * 7;
    
            var months = 0;
        }
        else {
            if (typeof parts[4] != "undefined") {
                var months = Number(parts[4]) - 1;
            }
            else {
                /* it's an ordinal date... */
                var months = 0;
            }
    
            var days   = Number(parts[5]);
        }
    
        if (typeof parts[6] != "undefined" &&
            typeof parts[7] != "undefined")
        {
            var hours        = Number(parts[6]);
            var minutes      = Number(parts[7]);
    
            if (typeof parts[8] != "undefined") {
                var seconds      = Number(parts[8]);
    
                if (typeof parts[9] != "undefined") {
                    var fractional   = Number(parts[9]);
                    var milliseconds = fractional / 100;
                }
                else {
                    var milliseconds = 0
                }
            }
            else {
                var seconds      = 0;
                var milliseconds = 0;
            }
        }
        else {
            var hours        = 0;
            var minutes      = 0;
            var seconds      = 0;
            var fractional   = 0;
            var milliseconds = 0;
        }
    
        if (typeof parts[10] != "undefined") {
            /* Timezone adjustment, offset the minutes appropriately */
            var localzone = -(new Date().getTimezoneOffset());
            var timezone  = parts[10] * 60;
    
            minutes = Number(minutes) + (timezone - localzone);
        }
    
        return new Date(year, months, days, hours, minutes, seconds, milliseconds);
    }
    
    print(parseISODate("2010-06-29T15:33:00Z-7"))
    print(parseISODate("2010-06-29 06:14Z"))
    print(parseISODate("2010-06-29T06:14Z"))
    print(parseISODate("2010-06-29T06:14:30.2034Z"))
    print(parseISODate("2010-W26-2"))
    print(parseISODate("2010-180"))
    

提交回复
热议问题