Различия в часовых поясах, приводящие к неправильному оставшемуся времени при использовании Laravel и javascript - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь узнать оставшееся время на странице бронирования. Я даю javascript дату и точное время начала бронирования следующим образом:

if (Auth()->user()->role == 1) { //this is the owner of the time slot that was selected. So it makes sense not to set a time zone for him.
    $dateTime = Carbon::parse($dateTime . ' ' . $book->from);
} else { //this is a normal user
    $dateTime = Carbon::parse($dateTime . ' ' . $book->from)->setTimezone(Auth()->user()->time_zone);
}

А функция javascript обрабатывает это следующим образом:

<script>
$(document).ready(function() {
    var tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1)
    $('.date').datepicker({minDate: tomorrow, dateFormat: 'yy-mm-dd'});

    currentDate = new Date();
    currentDateNextFiveDays =  currentDate;
    remainingTime =  new Date(currentDateNextFiveDays) - new Date(currentDate);
    // Set the date we're counting down to
    var countDownDate = new Date("{{$dateTime}}");
    // Update the count down every 1 second
    var x = setInterval(function() {
        // Get today's date and time
        var now = new Date().getTime();
        // Find the distance between now and the count down date
        var distance = countDownDate - now;
        // Time calculations for days, hours, minutes and seconds
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        // days = days * 24;
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        // hours = hours + days;
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);
        // Display the result in the element with id="demo"
        if(-3000 < distance && distance < -1000) {
            location.reload();
        }
        if(distance > 0) {
            if(days > 0) {
                $('.remaining-time').text(days + " " + "@lang('profile.lang_day')");
            }
            else {
                $('.remaining-time').text(hours + " " + "@lang('profile.lang_hour')" + " " + minutes + " " + "@lang('profile.lang_minutes')" + " " + seconds + " " + "@lang('profile.lang_second')");
            }
        }
        else {
            $('.remaining-time-button').hide();
        }
    }, 1000);
});

Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

Код работает отлично, но всякий раз, когда я использую два браузера из разных стран, он дает разные результаты. (Плюс 3 часа, плюс 10 часов .. в зависимости от часовых поясов)

Часовой пояс сервера находится в Азии / Эр-Рияде. И я сохраняю часовой пояс пользователя каждый раз, когда он входит в систему, но я не уверен, как это мне поможет в этом случае. Я без проблем показываю дату и время (относительно часового пояса), но оставшееся время неверно.

1 Ответ

0 голосов
/ 30 мая 2020

Утверждение комментария неточно. Делать иначе для пользователей в том же или другом часовом поясе не имеет значения. Вы должны передать JS строку ISO с часовым поясом GMT (это делается автоматически, если вы отправляете ее через ответ JSON. Вы получите строку вида 2020-06-30T19:49:03.123Z, где Z означает GMT.

Так что используйте:

 $dateTime = Carbon::parse($dateTime . ' ' . $book->from)->toJSON();

Для всех пользователей. Так new Date("{{$dateTime}}"); прекрасно поймет, что это дата по Гринвичу, и преобразует ее. Итак, если ваш сценарий JS не испортит часовой пояс, она везде будет одинаковой продолжительности.

...