UTC, часы не работают с отрицательным часовым поясом - PullRequest
0 голосов
/ 04 января 2019

В моем приложении мне нужно создать живые часы в соответствии с разными часовыми поясами, которые хранятся в базе данных.

Я почти достиг этого.

Но теперь я сталкиваюсь с отрицательным временем вчасы, и у меня нет идей, чтобы найти решение.

Я получаю время UTC с помощью new Date() и вычисляю время с предоставленным часовым поясом из базы данных.

Дело 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 голосов
/ 04 января 2019

Вы хотите восстановить / отобразить время для данного смещения часового пояса?Если вам не нравится делать это для хобби, держитесь подальше от строковых методов и используйте функции даты, нет?

var offsetMS = -5.5 * 3600000
var myDate = new Date()
var dateWithOffset = new Date( myDate.getTime() + offsetMS )
var formatted = dateWithOffset.toLocaleString("en-GB",{timeZone:"UTC",hour:"numeric",minute:"numeric"})
console.log(formatted)

Следует избегать даже прямого манипулирования смещением часового пояса.Если вы можете использовать toLocaleString с реальным именем часового пояса, то такие вопросы, как переход на летнее время, будут решены за вас.Современные браузеры поддерживают все часовые пояса iana, поэтому пусть они делают свою работу.

0 голосов
/ 04 января 2019

Вы должны просто вернуться к 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>
0 голосов
/ 04 января 2019

Добавьте 24 к вашему FT значению и оставьте деление на 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

0 голосов
/ 04 января 2019

Если вы не хотите использовать такую ​​библиотеку, как moment.js, которая поставляется с обработкой часового пояса, и вам просто нужно добавить / вычесть часы из определенной даты, как насчет преобразования их в общую единицу времени и работы с ней?

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);

Что-то вроде этого преобразует их в метку времени в миллисекунды, вычитает это количество часов и переводит их обратно в дату.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...