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

前端 未结 23 1107
爱一瞬间的悲伤
爱一瞬间的悲伤 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....

    0 讨论(0)
  • 2020-11-22 01:56
    // My clock 2018-07-25, 00:26:00 (GMT+7)
    let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0)
    const myTimeZone = 7; // my timeZone 
    // my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond);
    // 2018-07-24:17:26:00 = x (milliseconds)
    // finally, time in milliseconds (GMT+7) = x + myTimezone 
    date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 );
    // date.toISOString() = 2018-07-25, 00:26:00 (GMT+7)
    
    0 讨论(0)
  • 2020-11-22 01:58

    I believe you need the createDateAsUTC function (please compare with convertDateToUTC)

    function createDateAsUTC(date) {
        return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
    }
    
    function convertDateToUTC(date) { 
        return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); 
    }
    
    0 讨论(0)
  • 2020-11-22 01:58

    getTimeZoneOffset is minus for UTC + z.

    var d = new Date(xiYear, xiMonth, xiDate);
    if(d.getTimezoneOffset() > 0){
        d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
    }
    
    0 讨论(0)
  • 2020-11-22 02:00

    SOLVED:

    When I create a date object:

    new Date(year, month, day, hour, minute)

    I works fine on localhost. When I deploy to server it breaks, because server is in another timezone.

    I can't use getTimezoneOffset(). I need the timezoneOffset of my home - dependent on summertime/wintertime

    // add diff minutes between myself (HOME) and server 
    timezoneHomeOffset (d, tz = 'Europe/Copenhagen') {
      const utc = new Date(d.getTime())
      const dHome = new Date(d.toLocaleString('en-US', { timeZone: tz }))
      const diff = Math.round((utc - dHome) / 60000) // 60*1000 => minutes
      d.setMinutes(d.getMinutes() + diff)
      return d
    }
    
    0 讨论(0)
  • 2020-11-22 02:01

    Best Solution I have seen from this came from

    http://www.codingforums.com/archive/index.php/t-19663.html

    Print Time Function

    <script language="javascript" type="text/javascript">
    //borrowed from echoecho
    //http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
    workDate = new Date()
    UTCDate = new Date()
    UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)
    
    function printTime(offset) {
        offset++;
        tempDate = new Date()
        tempDate.setTime(UTCDate.getTime()+3600000*(offset))
        timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
        timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
        timeValue += " hrs."
        return timeValue
        }
        var now = new Date()
        var seed = now.getTime() % 0xfffffff
        var same = rand(12)
    </script>
    
    Banff, Canada:
    <script language="JavaScript">document.write(printTime("-7"))</script>
    

    Full Code Example

    <html>
    
    <head>
    <script language="javascript" type="text/javascript">
    //borrowed from echoecho
    //http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
    workDate = new Date()
    UTCDate = new Date()
    UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)
    
    function printTime(offset) {
    offset++;
    tempDate = new Date()
    tempDate.setTime(UTCDate.getTime()+3600000*(offset))
    timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
    timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
    timeValue += " hrs."
    return timeValue
    }
    var now = new Date()
    var seed = now.getTime() % 0xfffffff
    var same = rand(12)
    </script>
    
    </head>
    
    <body>
    Banff, Canada:
    <script language="JavaScript">document.write(printTime("-7"))</script>
    <br>
    Michigan:
    <script language="JavaScript">document.write(printTime("-5"))</script>
    <br>
    Greenwich, England(UTC):
    <script language="JavaScript">document.write(printTime("-0"))</script>
    <br>
    Tokyo, Japan:
    <script language="JavaScript">document.write(printTime("+9"))</script>
    <br>
    Berlin, Germany:
    <script language="JavaScript">document.write(printTime("+1"))</script>
    
    </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题