UTC实时时钟,不适用于负时区

时间:2019-01-04 06:33:43

标签: javascript html datetime

在我的应用程序中,我需要根据存储在数据库中的不同时区创建实时时钟。

我几乎成功了。

但是现在我正面临着负面的时间,我没有办法找出解决方案。

我正在new Date()的帮助下获得UTC时间,并从数据库中计算了提供的时区。

情况1:0:31 (UTC time) + 5:30 (timezone) = '06:01'

情况2:06:31 (UTC time) - 6:30 (timezone) = '00:01'

情况3:5:0 (UTC time) - 7:0 (timezone) = '-02:00'

情况1和2正常工作,但是在第三种情况下我得到了负值,这是错误的。

我试图在代码中添加注释,以更好地了解我在这里所做的事情。希望对您有所帮助。

我们将不胜感激任何帮助。

function runClock() {

  setInterval(function() {
    //debugger
    var time = new Date();
    // take timezone from HTML element
    // ex: +:5:30
    var getTimezone =  "-:7:0" //$("#timeZone").text();

    // split into array to get oparator (Positive and Negative Timezone)
    var oparator = getTimezone.split(":")[0];
    var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];

    // get UTC hours
    var hours = 5 //time.getUTCHours();
    var minutes = 0 //time.getUTCMinutes();
    var UTCTIME = timeStringToFloat(hours + ":" + minutes);
    var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
    var finalTime = "";


    // Convert time folloed by Colon into decimals
    // ex: 1:45 = 1.75
    function timeStringToFloat(time) {
      var hoursMinutes = time.split(/[.:]/);
      var hh = parseInt(hoursMinutes[0], 10);
      var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
      return hh + mm / 60;
    }


    // Convert time folloed by float into Colon
    // ex: 1.75 = 1:45
    function floatToTime(FT) {
      var splittedTime = FT.toString().split(".");
      var hh = splittedTime[0];
      var mm = "";

      if (splittedTime[1]) {
        mm = Math.round((splittedTime[1] / 100) * 60);
      } else {
        mm = "0";
      }

      finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
    }


    // Calculate time (UTC + or - Timezone)
    // Ex: 00:15 (UTC) + 5:30 = 5:45
    function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
      if (oparator == "+") {
        var FT = UTCTIME + TIMEZONEOFFSETTIME;
        FT = FT.toFixed(2);
        floatToTime(FT);
      } else {
        var FT = UTCTIME - TIMEZONEOFFSETTIME;
        FT = FT.toFixed(2);
        floatToTime(FT);
      }
    }


    // Parse Seconds
    function seconds() {
      var j = "";
      if (time.getUTCSeconds() < 10) {
        j = "0" + time.getUTCSeconds();
      } else {
        j = time.getUTCSeconds()
      }
      return j;
    }

    CalcTime(UTCTIME, TIMEZONEOFFSETTIME);

    $("#clockTime").text(finalTime + ":" + seconds());
  }, 1000);

}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<b id="clockTime"></b>

4 个答案:

答案 0 :(得分:1)

当你消极时,你应该只是“循环回到” 23:59。您可以添加一些东西检查它是否变为负数,然后重新添加缺少的时间:

function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
      if (oparator == "+") {
        var FT = UTCTIME + TIMEZONEOFFSETTIME;
        FT = FT.toFixed(2);
        floatToTime(FT);
      } else {
        var FT = UTCTIME - TIMEZONEOFFSETTIME;

        // Offset any negative times;
        if (FT < 0) {
          FT += 24;
        }

        FT = FT.toFixed(2);
        floatToTime(FT);
      }
    }

但是理想情况下,您真的不想处理这类时区问题,因为其他库已经在处理它,例如moment.js

function runClock() {

  setInterval(function() {
    //debugger
    var time = new Date();
    // take timezone from HTML element
    // ex: +:5:30
    var getTimezone =  "-:7:0" //$("#timeZone").text();

    // split into array to get oparator (Positive and Negative Timezone)
    var oparator = getTimezone.split(":")[0];
    var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];

    // get UTC hours
    var hours = 5 //time.getUTCHours();
    var minutes = 0 //time.getUTCMinutes();
    var UTCTIME = timeStringToFloat(hours + ":" + minutes);
    var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
    var finalTime = "";


    // Convert time folloed by Colon into decimals
    // ex: 1:45 = 1.75
    function timeStringToFloat(time) {
      var hoursMinutes = time.split(/[.:]/);
      var hh = parseInt(hoursMinutes[0], 10);
      var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
      return hh + mm / 60;
    }


    // Convert time folloed by float into Colon
    // ex: 1.75 = 1:45
    function floatToTime(FT) {
      var splittedTime = FT.toString().split(".");
      var hh = splittedTime[0];
      var mm = "";

      if (splittedTime[1]) {
        mm = Math.round((splittedTime[1] / 100) * 60);
      } else {
        mm = "0";
      }

      finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
    }


    // Calculate time (UTC + or - Timezone)
    // Ex: 00:15 (UTC) + 5:30 = 5:45
    function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
      if (oparator == "+") {
        var FT = UTCTIME + TIMEZONEOFFSETTIME;
        FT = FT.toFixed(2);
        floatToTime(FT);
      } else {
        var FT = UTCTIME - TIMEZONEOFFSETTIME;
        
        // Offset any negative times;
        if (FT < 0) {
          FT += 24;
        }
        
        FT = FT.toFixed(2);
        floatToTime(FT);
      }
    }


    // Parse Seconds
    function seconds() {
      var j = "";
      if (time.getUTCSeconds() < 10) {
        j = "0" + time.getUTCSeconds();
      } else {
        j = time.getUTCSeconds()
      }
      return j;
    }

    CalcTime(UTCTIME, TIMEZONEOFFSETTIME);

    $("#clockTime").text(finalTime + ":" + seconds());
  }, 1000);

}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<b id="clockTime"></b>

答案 1 :(得分:1)

您要恢复/显示给定时区偏移量的时间吗?除非您出于业余爱好而这么做,否则请远离字符串方法并使用date函数,不是吗?

/vacatures/jobapplication/facility-manager%20qsdf 

甚至应避免直接操纵时区偏移。如果可以,请使用具有实时时区名称的toLocaleString,然后将为您处理诸如夏令时之类的问题。 Chrome似乎支持许多命名的时区,但我无法轻易找到确定的列表,并且可能因浏览器而异。

答案 2 :(得分:0)

如果您不想使用时区处理随附的诸如moment.js之类的库,而只需要添加/减去给定日期的小时数,如何将它们转换为通用时间单位并在该时间单位上进行操作? / p>

const timezoneString = '-:12:30';
const parts = timezoneString.split(':');
const timezone = (parts[0] === '-' ? -1 : 1) * (parseInt(parts[1]) + (parseInt(parts[2]) / 60.0));
const timeZoneMillis = timezone * 3600 * 1000;
const now = new Date();
const inZone = new Date(now.getTime() + timeZoneMillis);
console.log(now, inZone);

像这样的事情会将它们转换成毫秒的时间戳,并减去许多小时,然后将其转换回日期。

答案 3 :(得分:0)

在您的FT值中加上24,然后除以24:

function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
      if (oparator == "+") {
        var FT = UTCTIME + TIMEZONEOFFSETTIME;
      } else {
        var FT = UTCTIME - TIMEZONEOFFSETTIME + 24;
        FT = FT % 24;
      }

      FT = FT.toFixed(2);
      floatToTime(FT);
    }

工作示例:https://codepen.io/anon/pen/VqQqoo