2013-11-25 1 views
1

Бриз меняет часовой пояс с +1: 00 до 0:00. Значение моего наблюдаемого = 2013-11-11T00: 00: 00 + 01: 00 и saveChanges() отправляется обратно на сервер 2013-11-10T23: 00: 00.000 + 00: 00. В моих таблицах все даты - это предыдущий день.Даты/даты на ветру с установочным интервалом времени 0:00 на SQL Server

До сих пор я опробовал все типы данных ->date, datetime2, datetimeoffset. Бриз всегда отправляет дату -1: 00 час. SQL Server 2008 R2, последняя версия Breeze. Сервер настроен на правильный часовой пояс + 1:00.

Есть ли способ отправить заданный часовой пояс через saveChanges()?

Я изменить настройки FPR newtonsoft так:

JsonSerializerSettings customJsonSetting = new JsonSerializerSettings() 
     { 
      DateFormatHandling = DateFormatHandling.MicrosoftDateFormat, 
      DateTimeZoneHandling = DateTimeZoneHandling.Local 
     }; 
     GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = customJsonSetting; 

Тем не менее, получая 1 час минус. Поскольку мне нужны только даты, часовой пояс не имеет значения для моего приложения.

Спасибо, Патрик

ответ

0

Я думаю, что суть проблемы в том, что Breeze.js использует toISODate сериализовать Js Дата. Это приводит к отправке даты на сервер в виде сериализованного значения, которое вы наблюдаете.

Существует очень мало что можно сделать, чтобы изменить это поведение, по крайней мере, я не смог его найти. Я подозреваю, что это в настоящее время трудно ограничение в бризе согласно документам:

Breeze на клиенте сериализует на ISO 8601 и не поддерживается способ изменить это поведение

Хотя ISO 8601 делает поддержку Сериализация дат с смещением +01 (например), поведение toISODate - сериализовать дату как UTC Z (0 смещение временной зоны).

Существует хак, который я придумал, чтобы попытаться установить дату UTC Z в формате BeforeSaveEntitiesDelegate, но это действительно грубо и довольно ограничено, так как сервер должен сделать несовершенное предположение о том, является ли летнее время наблюдаемый на клиенте, и полагается на собственный конструктор Entity Breeze для предоставления в качестве незанятого значения текущего смещения часового пояса на клиенте.

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

Запрос уже сделано для улучшения, которые вы можете проголосовать до:

http://breezejs.uservoice.com/forums/173093-breeze-feature-suggestions/suggestions/3959108-breeze-clientside-serialization-of-datetimeoffset-

Christian

+0

Есть ли способ справиться с «Датами только», чтобы избежать проблемы с часовым поясом? Мне не нужен временной/часовой пояс, поскольку я имею дело с датами установления, такими как дата рождения, занятость с тех пор и т. Д. – Patrick

+0

Я думал об этом вчера и пришел к выводу, что это не вариант, по крайней мере, для моего дизайна. Основная проблема заключается в том, что если вы отключите время от UTC Z datetime, это приведет к дате, которая не будет такой, какой ожидает пользователь. Например, пользователь в Лондоне входит 1 июня 2013 года; это отправляется по проводу как 2013-05-31 23:00:00; за исключением того, что в течение 31 мая 2013 года будет сохранено время отгонки. Чтобы убрать время, вам понадобится дата-время, отправленное с смещением часового пояса клиента - например, 2013-06-01T00: 00: 00 + 01 – Christian

+0

Патрик, изучите ответ Джея, он прав. Однако я * думаю *, что может сбить с толку, это время, которое вы видите, хранящееся в db. Дата 1 июня 2013 года 12:00 утра хранится как 2013-05-31 23:00:00. Хотя это выглядит некорректно (на 1 час), это НЕ. Это на 100% точнее - это время UTC ZTC. Согласно ответу Джей, это значение, когда оно отправляется обратно клиенту, будет отображаться в более знакомой стоимости 1 июня 2013 года 12:00. Что мне не нравится *, так это то, что значение в db можно сохранить как 2013-06-01 00: 00: 00 + 01. Это выглядит более знакомым, а также сохраняет ценную информацию - часовой пояс клиента – Christian

1

В инициализатора объекта я использую следующие сохранить все даты синхронизируются:

  myObject.formattedMyTime = ko.computed({ 
      read: function() { 
       return moment.utc(myObject.myTime()).format('DD/MM/YYYY HH:mm'); 
      }, 
      write: function (value) { 
       myObject.myTime(moment.utc(value).toDate()); 
      } 
     }); 

Затем я использую только formattedMyTime вместо myTime. Мое программное обеспечение предполагает, что будет использоваться только один часовой пояс, поэтому на самом деле не имеет значения, какой из них фактически использовался.

3

Не уверен, что я понимаю. Javascript внутренне сохраняет все свои даты в виде нескольких миллисекунд с 1 января 1970 года 00:00:00 по UTC. Затем ваш браузер форматирует эти даты в локальном часовом поясе браузера.Но то, что отправляется на сервер/с сервера, всегда является сериализацией ISO8601 фактической даты javascript. Этот формат позволяет представить «точный» момент времени. Этот момент времени будет отформатирован по-разному в зависимости от часового пояса, в который он отформатирован, но сам момент времени не изменяется.

Таким образом, чтобы уточнить, Breeze НЕ меняет даты в любом случае, за исключением случая дат, отправленных с сервера без временной зоны смещения (другой вопрос, который обсуждался в других сообщений на этом форуме.). Я точно не знаю, что вы испытываете, но ваш комментарий о том, что «Сервер настроен на правильный часовой пояс + 1:00.», Меня смущает. Часовой пояс сервера относится только к форматированию даты, а не к ее фактическому значению.

Однако Breeze поддерживает несколько точек перехвата как на сервере, так и на клиенте.

На сервере, если вы используете ASP.NET WebApi или WebApi2, вы можете создать собственную реализацию класса BreezeConfig. BreezeConfig определяет поведение по умолчанию; вы можете подменить свое собственное поведение, исходя из него и переопределяя его виртуальные методы. Breeze.NET обнаружит ваш подкласс среди сборок, на которые ссылается ваш проект, и используйте его вместо BreezeConfig.

Чтобы использовать BreezeConfig для настройки сериализатора Json.Net с определенными настройками. См. http://james.newtonking.com/json/help/index.html. Вы можете заменить эти параметры, написав подкласс BreezeConfig, который переопределяет метод в соответствии с «CreateJsonSerializerSettings», как показано в следующем примере:

public class CustomBreezeConfig : Breeze.WebApi.BreezeConfig {  
    protected override JsonSerializerSettings CreateJsonSerializerSettings() { 
    var baseSettings = base.CreateJsonSerializerSettings();  
    // Default is DateTimeZoneHandling.RoundtripKind - you can change that here. 
    // baseSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; 

    return baseSettings; 

}

Если изменить это, то вы также, вероятно, нужно заменить Бриз клиентский метод breeze.DataType.parseDateFromServer. Например, если вы хотите обрабатывать все даты, сериализованные с сервера как локальные, вы можете сделать что-то вроде следующего.

var _utcOffsetMs = (new Date()).getTimezoneOffset() * 60000; 

// change to parse date as local 
breeze.DataType.parseDateFromServer = function (source) { 
    var dt = breeze.DataType.parseDatesAsUTC(source); 
    if (breeze.core.isDate(dt)) { 
     dt = new Date(dt.getTime() + _utcOffsetMs); 
    } 
    return dt; 
}; 

Обратите внимание, что я только объясняю настройки точек бриза здесь. Вероятно, это не точное решение вашей проблемы.

+1

'baseSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;' сделал трюк для меня. У меня также была такая же проблема, как и вопрос. – Sljux

Смежные вопросы