Create a Date with a set timezone without using a string representation

前端 未结 23 1114
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 01:48

I have a web page with three dropdowns for day, month and year. If I use the JavaScript Date constructor that takes numbers, then I get a Date obje

23条回答
  •  灰色年华
    2020-11-22 01:56

    If you want to deal with the slightly different, but related, problem of creating a Javascript Date object from year, month, day, ..., including timezone – that is, if you want to parse a string into a Date – then you apparently have to do an infuriatingly complicated dance:

    // parseISO8601String : string -> Date
    // Parse an ISO-8601 date, including possible timezone,
    // into a Javascript Date object.
    //
    // Test strings: parseISO8601String(x).toISOString()
    // "2013-01-31T12:34"              -> "2013-01-31T12:34:00.000Z"
    // "2013-01-31T12:34:56"           -> "2013-01-31T12:34:56.000Z"
    // "2013-01-31T12:34:56.78"        -> "2013-01-31T12:34:56.780Z"
    // "2013-01-31T12:34:56.78+0100"   -> "2013-01-31T11:34:56.780Z"
    // "2013-01-31T12:34:56.78+0530"   -> "2013-01-31T07:04:56.780Z"
    // "2013-01-31T12:34:56.78-0330"   -> "2013-01-31T16:04:56.780Z"
    // "2013-01-31T12:34:56-0330"      -> "2013-01-31T16:04:56.000Z"
    // "2013-01-31T12:34:56Z"          -> "2013-01-31T12:34:56.000Z"
    function parseISO8601String(dateString) {
        var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/;
        var m = timebits.exec(dateString);
        var resultDate;
        if (m) {
            var utcdate = Date.UTC(parseInt(m[1]),
                                   parseInt(m[2])-1, // months are zero-offset (!)
                                   parseInt(m[3]),
                                   parseInt(m[4]), parseInt(m[5]), // hh:mm
                                   (m[6] && parseInt(m[6]) || 0),  // optional seconds
                                   (m[7] && parseFloat(m[7])*1000) || 0); // optional fraction
            // utcdate is milliseconds since the epoch
            if (m[9] && m[10]) {
                var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]);
                utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000;
            }
            resultDate = new Date(utcdate);
        } else {
            resultDate = null;
        }
        return resultDate;
    }
    

    That is, you create a 'UTC time' using the date without timezone (so you know what locale it's in, namely the UTC 'locale', and it's not defaulted to the local one), and then manually apply the indicated timezone offset.

    Wouldn't it have been nice if someone had actually thought about the Javascript date object for more than, oooh, five minutes....

提交回复
热议问题