Breezejs: дата не установлена ​​в нужное время

Я заметил, что если свойство даты возвращается с сервера со значением "2013-07-11T17: 11: 04.700", тогда ветер меняет значение на Thu Jul 11 ​​19:11:04 UTC + 0200 2013.

Обратите внимание, что время на 2 часа вперед!

Я уже сталкивался с этой проблемой при сохранении объектов, поэтому мне пришлось явно преобразовать свои свойства даты с помощью momentjs:

 date.hours(date.hours() - moment().zone() / 60);

Но теперь кажется, что проблема возникает и при выполнении операций чтения.

Какой лучший способ убедиться, что бриз не изменяет значения моих свойств даты?

Ответ 1

Breeze не обрабатывает время, отправляемые на сервер и с сервера каким-либо образом EXCEPT, чтобы добавить спецификатор часового пояса UTZ для любых дат, возвращаемых с сервера, у которого его еще нет. Это делается только потому, что разные браузеры интерпретируют даты без спецификатора часового пояса по-разному, и мы хотим согласованности между браузерами.

Источником ваших проблем, вероятно, будет то, что при сохранении данных с датами в базе данных тип данных dateTime, который вы используете, НЕ содержит смещение часового пояса. Это означает, что когда данные извлекаются, вы, скорее всего, "теряете" смещение, и упомянутое выше значение по умолчанию Breeze может быть исправлено с помощью типа данных даты базы данных с смещением часового пояса (datetime2 или datetimeoffset в SQLServer).

Обратите внимание, что ваш браузер форматирует даты в соответствии с текущим часовым поясом.

Другой подход заключается в том, что вы можете заменить Breeze DataType.parseDateFromServer, чтобы НЕ принимать информацию о часовом поясе, если она не указана:

breeze.DataType.parseDateFromServer = function (source) {
     return new Date(Date.parse(source));
};

Однако это может привести к тому, что разные браузеры интерпретируют строки DateTime без смещения часового пояса по-разному... Таким образом, вы все равно можете получить странные результаты в зависимости от браузера. Если это произойдет, вам нужно будет добавить код обнаружения браузера в фрагмент выше.

Другой альтернативой является использование библиотеки moment.js следующим образом.

breeze.DataType.parseDateFromServer = function (source) {
     var date = moment(source); 
     return date.toDate();   
};

Не уверен, насколько это полезно, но, надеюсь, поведение Бриза яснее.

Ответ 2

По умолчанию Breeze не предоставляет никакого способа сделать это, но вы можете оставить ниже кода в файле модели js модели, чтобы решить эту проблему.

breeze.DataType.parseDateFromServer = function (source) {
                if (typeof source === 'string') {
                    //Check for local offset time or UTC time from server
                    if (source.slice(-1) !== "Z") {
                        var oldSource = source;

                        try {
                            source = source.substring(0, source.lastIndexOf("-") - 1)
                            source = new Date(source);
                            var tzDifference = source.getTimezoneOffset();
                            //convert the offset to milliseconds, add to targetTime, and make a new Date
                            var offsetTime = new Date(source.getTime() + tzDifference * 60 * 1000);
                            return offsetTime;
                        }
                        catch (err) {
                            source = new Date(source);
                            return source;
                        }
                    }
                    else {
                        source = new Date(source);

                        var tzDifference = source.getTimezoneOffset();
                        //convert the offset to milliseconds, add to targetTime, and make a new Date
                        var offsetTime = new Date(source.getTime() + tzDifference * 60 * 1000);

                        return offsetTime;
                    }
                }
            }