如何获得客户的确切当地时间?

时间:2012-05-18 20:47:43

标签: javascript jquery datetime geolocation timezone

无论客户端系统的时区如何,获取客户端本地时间的最佳方法是什么?我正在创建一个应用程序,我首先需要获取客户端访问位置的确切时间和日期。即使检测客户端系统的IP地址也有缺点,或者检测客户端系统的时区有时可能存在风险。那么,有什么方法可以真正可靠并且不容易出错,因为向客户显示错误的时间和日期是非常令人尴尬的。

15 个答案:

答案 0 :(得分:42)

在JavaScript中?只需实例化一个新的 Date object

var now = new Date();

这将创建一个具有客户端本地时间的新Date对象。

答案 1 :(得分:18)

现在,您可以获得只有一行代码的用户的正确时区:

const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions

然后,您可以使用moment-timezone来解析时区,如:

const currentTime = moment().tz(timezone).format();

答案 2 :(得分:10)

如果您想知道客户相对于GMT / UTC的时区,请转到:

var d = new Date();
var tz = d.toString().split("GMT")[1].split(" (")[0]; // timezone, i.e. -0700

如果你想要时区的实际名称,你可以试试这个:

var d = new Date();
var tz = d.toString().split("GMT")[1]; // timezone, i.e. -0700 (Pacific Daylight Time)

更新1

根据您的第一条评论,您也可以使用d.getTimezoneOffset()来获取UTC的分钟数。虽然有几个陷阱。

  1. 返回的分钟符号(+/-)可能与您期望的相反。如果您 UTC后8小时,它将返回480而不是-480。有关更多文档,请参阅MDNMSDN
  2. 它实际上并没有返回客户端报告的时区,就像我给出的第二个例子一样。只是当前从UTC偏移的分钟数。所以它会根据夏令时变化。
  3. 更新2

    虽然字符串拆分示例有效,但它们可能会令人困惑。这是一个应该更容易理解的正则表达式版本,可能更快(虽然两种方法都非常快)。

    如果您想知道客户相对于GMT / UTC的时区,请转到:

    var gmtRe = /GMT([\-\+]?\d{4})/; // Look for GMT, + or - (optionally), and 4 characters of digits (\d)
    var d = new Date().toString();
    var tz = gmtRe.exec(d)[1]; // timezone, i.e. -0700
    

    如果您想要时区的实际名称,请尝试以下方法:

    var tzRe = /\(([\w\s]+)\)/; // Look for "(", any words (\w) or spaces (\s), and ")"
    var d = new Date().toString();
    var tz = tzRe.exec(d)[1]; // timezone, i.e. "Pacific Daylight Time"
    

答案 3 :(得分:2)

我不得不解决这个问题,以为我会留下我的答案。 jQuery不需要我曾经更新过该元素,因为我已经将对象缓存了。

我首先编写了一个php函数,将所需的日期/时间返回到我的HTML模板

 /**
 * Gets the current location time based on timezone
 * @return string
 */


function get_the_local_time($timezone) {

    //$timezone ='Europe/London';

    $date = new DateTime('now', new DateTimeZone($timezone));

    return array(
        'local-machine-time' => $date->format('Y-m-d\TH:i:s+0000'),
        'local-time' => $date->format('h:i a')
    );

}

然后在我的HTML模板中使用它来显示初始时间,并在数据属性中呈现javascript所需的日期格式。

        <span class="box--location__time" data-time="<?php echo $time['local-machine-time']; ?>">
            <?php  echo $time['local-time']; ?>
        </span>

然后我在我的日期对象上使用getUTCHours来返回时间而不管用户的时区

  

getUTCHours()方法返回的小时(从0到23)   指定的日期和时间,按照世界时间。

var initClocks = function() {

    var $clocks = $('.box--location__time');

    function formatTime(hours, minutes) {

        if (hours === 0) {
            hours = 12;
        }

        if (hours < 10) {
            hours = "0" + hours;
        }

        if (minutes < 10) {
            minutes = "0" + minutes;
        }

        return {
            hours: hours,
            minutes: minutes
        }
    }

    function displayTime(time, $clockDiv) {

        var currentTime = new Date(time);

        var hours = currentTime.getUTCHours();
        var minutes = currentTime.getUTCMinutes();
        var seconds = currentTime.getUTCSeconds();
        var initSeconds = seconds;

        var displayTime = formatTime(hours, minutes);

        $clockDiv.html(displayTime.hours + ":" + displayTime.minutes + ":" + seconds);

        setInterval(function() {

            if (initSeconds > 60) {
                initSeconds = 1;
            } else {
                initSeconds++;
            }

            currentTime.setSeconds(initSeconds);

            hours = currentTime.getUTCHours();
            minutes = currentTime.getUTCMinutes();
            seconds = currentTime.getUTCSeconds();

            displayTime = formatTime(hours, minutes);

            $clockDiv.html(displayTime.hours + ":" + displayTime.minutes + ":" + seconds);

        }, 1000);

    }



    $clocks.each(function() {

        displayTime($(this).data('time'), $(this));

    });

};

然后我使用setSeconds方法根据页面加载后的秒数(简单间隔函数)更新日期对象,并更新HTML

答案 4 :(得分:2)

尝试

let s= new Date().toLocaleString();

console.log(s);

答案 5 :(得分:1)

我发现显示城市或位置的当地时间的最可靠方法是点按时区API,例如Google Time Zone API。它返回正确的时区,更重要的是,任何位置的Day Light Savings Time偏移量,就我所知,只能使用JavaScript的Date()对象。有一个很好的教程,使用API​​来获取和显示本地时间here

var loc = '35.731252, 139.730291' // Tokyo expressed as lat,lng tuple
var targetDate = new Date() // Current date/time of user computer
var timestamp = targetDate.getTime()/1000 + targetDate.getTimezoneOffset() * 60 // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC
var apikey = 'YOUR_TIMEZONE_API_KEY_HERE'
var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + loc + '&timestamp=' + timestamp + '&key=' + apikey

var xhr = new XMLHttpRequest() // create new XMLHttpRequest2 object
xhr.open('GET', apicall) // open GET request
xhr.onload = function(){
    if (xhr.status === 200){ // if Ajax request successful
        var output = JSON.parse(xhr.responseText) // convert returned JSON string to JSON object
        console.log(output.status) // log API return status for debugging purposes
        if (output.status == 'OK'){ // if API reports everything was returned successfully
            var offsets = output.dstOffset * 1000 + output.rawOffset * 1000 // get DST and time zone offsets in milliseconds
            var localdate = new Date(timestamp * 1000 + offsets) // Date object containing current time of Tokyo (timestamp + dstOffset + rawOffset)
            console.log(localdate.toLocaleString()) // Display current Tokyo date and time
        }
    }
    else{
        alert('Request failed.  Returned status of ' + xhr.status)
    }
}
xhr.send() // send request

来自:Displaying the Local Time of Any City using JavaScript and Google Time Zone API

答案 6 :(得分:1)

为了使用纯Javascript获取本地时间 使用此内置功能

// return new Date().toLocaleTimeString();

请参见以下示例

 function getLocaltime(){
   return new Date().toLocaleTimeString();
 }
 console.log(getLocaltime());

答案 7 :(得分:1)

  • 直接这样:

    new Date((new Date().setHours(new Date().getHours() - (new Date().getTimezoneOffset() / 60)))).toISOString()
    
  • 这个实用函数的更多细节

    function getLocaLTime() {
      // new Date().getTimezoneOffset() : getTimezoneOffset in minutes 
      //for GMT + 1 it is (-60) 
      //for GMT + 2 it is (-120) 
      //..
      let time_zone_offset_in_hours = new Date().getTimezoneOffset() / 60;
      //get current datetime hour
      let current_hour = new Date().getHours();
      //adjust current date hour 
      let local_datetime_in_milliseconds = new Date().setHours(current_hour - time_zone_offset_in_hours);
      //format date in milliseconds to ISO String
      let local_datetime = new Date(local_datetime_in_milliseconds).toISOString();
      return local_datetime;
      }
    

答案 8 :(得分:0)

我的代码是

  <html>
  <head>
  <title>Title</title>
  <script type="text/javascript"> 
  function display_c(){
  var refresh=1000; // Refresh rate in milli seconds
  mytime=setTimeout('display_ct()',refresh)
  }

  function display_ct() {
  var strcount
  var x = new Date()
  document.getElementById('ct').innerHTML = x;
  tt=display_c();
  }
  </script>
  </head>

  <body onload=display_ct();>
  <span id='ct' ></span>

  </body>
  </html>

如果您想要更多代码,请访问我的博客http://mysimplejavascriptcode.blogspot.in/

答案 9 :(得分:0)

您还可以创建自己的nodeJS端点,使用heroku之类的东西发布它并访问它

<meta property="og:title" content="Your link title" />
<meta property="og:description" content="Some description of your webpage" />

然后只需在JS上访问它

require("http").createServer(function (q,r) {
    r.setHeader("accees-control-allow-origin","*")
    r.end(Date.now())
}).listen(process.env.PORT || 80)

这仍然与托管节点应用程序的任何计算机有关,但是也许您可以以某种方式获取位置并根据当前时区提供适合其他时区的不同端点(例如,如果服务器恰好位于加利福尼亚州)然后对于纽约时区,只需将fetch ("http://someGerokuApp") .then(r=>r.text) . then (r=>console.log(r)) 毫秒添加到Date.now()即可添加3小时)

为简单起见,如果可以从服务器获取位置并将其作为响应头发送,则可以只在客户端中针对不同时区进行计算

实际上,使用heroku可以让您指定应在https://devcenter.heroku.com/articles/regions#specifying-a-region部署的区域,您可以将该区域用作参考。

编辑 只是意识到时区位于日期字符串本身中,所以可以将整个内容作为标头支付给客户端读取

1000*60*60*3

答案 10 :(得分:0)

以下是使用fetch和https://worldtimeapi.org/api

的版本,在2020年9月运行良好

fetch("https://worldtimeapi.org/api/ip")
  .then(response => response.json())
  .then(data => console.log(data.dst,data.datetime));

答案 11 :(得分:0)

我发现此功能在所有项目中都非常有用。您也可以使用它。

getStartTime(){
    let date = new Date();
    var tz = date.toString().split("GMT")[1].split(" (")[0];
    tz = tz.substring(1,5);
    let hOffset = parseInt(tz[0]+tz[1]);
    let mOffset = parseInt(tz[2]+tz[3]);
    let offset = date.getTimezoneOffset() * 60 * 1000;
    let localTime = date.getTime();
    let utcTime = localTime + offset;
    let austratia_brisbane = utcTime + (3600000 * hOffset) + (60000 * mOffset);
    let customDate = new Date(austratia_brisbane);

    let data = {
        day: customDate.getDate(),
        month: customDate.getMonth() + 1,
        year: customDate.getFullYear(),
        hour: customDate.getHours(),
        min: customDate.getMinutes(),
        second: customDate.getSeconds(),
        raw: customDate,
        stringDate: customDate.toString()
    }

    return data;
  }

这将为您提供时间,具体取决于您的时区。

谢谢。

答案 12 :(得分:0)

我需要向服务器报告客户端发生的本地时间。 (在这个特定的商业案例中,UTC 没有提供任何价值)。我需要使用 toIsoString() 使格式与 .Net MVC 兼容,但 toIsoString() 这总是将其转换为 UTC 时间(已发送到服务器)。

受到 'amit saini' 答案的启发,我现在使用这个

    function toIsoStringInLocalTime(date) {
        return new Date((date.getTime() + (-date.getTimezoneOffset() * 60000))).toISOString()
    }

答案 13 :(得分:-1)

尝试这种方式

    function timenow(){
    var now= new Date(), 
    ampm= 'am', 
    h= now.getHours(), 
    m= now.getMinutes(), 
    s= now.getSeconds();
    if(h>= 12){
        if(h>12) h -= 12;
        ampm= 'pm';
    }

    if(m<10) m= '0'+m;
    if(s<10) s= '0'+s;
    return now.toLocaleDateString()+ ' ' + h + ':' + m + ':' + s + ' ' + ampm;
}

toLocaleDateString()

是一个更改日期时间格式的功能,如toLocaleDateString("en-us")

答案 14 :(得分:-1)

new Date(Date.now() + (-1*new Date().getTimezoneOffset()*60000)).toISOString()