我在处理日期方面遇到了一些麻烦。
我有一个带有日期字段的对象:
public DateTime FechaInicio {get;设置;}
此定义在数据库中生成以下字段:
FechaInicio datetime not null
向Web服务发出请求我按以下格式获取日期(在JSON中):
“FechaInicio”:“1982-12-02T00:00:00”
在tne实体上调用FechaInicio()会返回一个javascript Date对象。
创建新实体我得到以下值:
createPalanca var = function () {
MetadataStore var = manager.metadataStore;
metadataStore.getEntityType palancaType = var ("Toggle");
palancaType.createEntity newPalanca = var ();
manager.addEntity (newPalanca);
//Here: newPalanca.FechaInicio () has the value in this format: 1355313343214
//Expected Date object here
newPalanca return;
};
毕竟,我真正的问题是:我应该使用什么格式为日期类型字段分配新值?
编辑:
在做了一些测试之后,我注意到如果我将Date对象分配给属性,在我们到达这一行之前,一切似乎都很好:
saveBundleStringified var = JSON.stringify(saveBundle);
saveBundle内容是:
FechaInicio: Thu Dec 20 2012 00:00:00 GMT+0100 (Hora estándar romance)
和saveBundleStringified:
"FechaInicio": "2012-12-19T23:00:00.000Z" <- I guess this is utc format
最终存储在数据库中的是:2012-12-19 23:00:00.0000000
当返回对SaveChanges的调用结果时,它们将与函数updateEntity中的高速缓存中的实体合并,执行此检查:if(!core.isDate(val))返回false。 因此,它创建了一个具有错误日期的新Date对象:
function fastDateParse(y, m, d, h, i, s, ms){ //2012 12 19 23 00 00 ""
return new Date(y, m - 1, d, h || 0, i || 0, s || 0, ms || 0);
}
如果我错了,请纠正我,但我认为这就是问题所在。
答案 0 :(得分:4)
抱歉这么久......
Breeze的DateTime时区序列化存在错误,默认的DateTime值用于具有不可为空的日期字段的新构造实体。这些是固定的v 0.77.2。请确认这套修复是否适合您。
感谢您找到这些。
要回答您的问题,您对象上的所有日期属性都应设置为javascript日期。 Breeze应该正确处理所有序列化问题。
答案 1 :(得分:1)
日期总是吓唬我。我的直接本能是浏览器和服务器不在同一个TimeZone上;怎么可能我不知道。在任何情况下,它都必然会发生,我想起了在日期时间协调客户端和服务器的各种基本问题。我认为通常的建议一直是保持UTC中的所有内容,并在当地时间调整您向用户显示的内容。
我很怀疑这是一个有用的答案。我不确定Breeze应该在解决这个问题上扮演什么角色。欢迎提出我们可以传播和建立共识的建议。
你也可以澄清这句话:
当返回对SaveChanges的调用结果时,它们将与函数updateEntity中的高速缓存中的实体合并,执行此检查:if(!core.isDate(val))返回false。因此,它创建了一个日期错误的新Date对象
“错误的约会”是什么意思?你是说Breeze认为传入的日期值是无效的格式(而不是你预期的日期以外的日期)?
是的,@ Sascha,Breeze正在使用Web Api标准进行JSON格式化(Json.Net),并且它设置为ISO8601格式,而不是古怪的Microsoft格式(在我写这篇文章时让我失望)。
答案 2 :(得分:0)
Breeze / Web Api似乎需要一些特殊格式的日期(ISO8601)。任何其他格式对我不起作用。 moment.js通过设置和阅读解决了我的问题。如果使用Knockout以特殊绑定显示日期,也可以很好地完成格式化。
entity.someDate(moment().utc().toDate()) // example
它有效。
你也可以使用它:
Date.prototype.setISO8601 = function(string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[10]) {
date.setSeconds(d[10]);
}
if (d[12]) {
date.setMilliseconds(Number("0." + d[12]) * 1000);
}
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
this.setTime(Number(time));
};