NancyFX non serializza le date con una Z finale per indicare UTC/Zulu
Domanda
Memorizziamo tutte le nostre date nel nostro database come UTC.
Quando ci vengono restituiti dall'API, sono nel seguente formato
"createdDate":"2014-07-30T18:34:45"
Ma come puoi vedere, la data non ha la Z finale (che indica alla nostra app Angular che è UTC/Zulu).Dovrebbe sembrare come questo
"createdDate":"2014-07-30T18:34:45Z"
Ho la seguente impostazione nel nostro Bootstrapper
JsonSettings.ISO8601DateFormat = true;
Dove nella mia configurazione posso assicurarmi che ci sia un trailing Z
ai fini dell'analisi UTC?
Soluzione
Quale versione di NancyFx stai utilizzando?Perché nella versione 0.23.0 o successiva, il codice JsonSerializer è stato modificato per utilizzare il formato della data "o" invece del formato della data "s", che dovrebbe darti la Z finale che stai cercando.(Ma solo negli orari UTC.)
Questo è il commit che ha apportato questa modifica. Nota come DateTimeKind.Unspecified
le date vengono trattate come locali;questa potrebbe essere una possibile causa del tuo problema, se non stai creando esplicitamente i tuoi oggetti DateTime come DateTimeKind.Utc
.
Di seguito è riportato il codice NancyFx che serializza i valori DateTime, come appare a partire dalla v0.23.0 (dopo tale commit).Da https://github.com/NancyFx/Nancy/blob/v0.23.0/src/Nancy/Json/JsonSerializer.cs, righe 480-518:
void WriteValue (StringBuilder output, DateTime value)
{
if (this.iso8601DateFormat)
{
if (value.Kind == DateTimeKind.Unspecified)
{
// To avoid confusion, treat "Unspecified" datetimes as Local -- just like the WCF datetime format does as well.
value = new DateTime(value.Ticks, DateTimeKind.Local);
}
StringBuilderExtensions.AppendCount(output, maxJsonLength, string.Concat("\"", value.ToString("o", CultureInfo.InvariantCulture), "\""));
}
else
{
DateTime time = value.ToUniversalTime();
string suffix = "";
if (value.Kind != DateTimeKind.Utc)
{
TimeSpan localTZOffset;
if (value >= time)
{
localTZOffset = value - time;
suffix = "+";
}
else
{
localTZOffset = time - value;
suffix = "-";
}
suffix += localTZOffset.ToString("hhmm");
}
if (time < MinimumJavaScriptDate)
time = MinimumJavaScriptDate;
long ticks = (time.Ticks - InitialJavaScriptDateTicks)/(long)10000;
StringBuilderExtensions.AppendCount(output, maxJsonLength, "\"\\/Date(" + ticks + suffix + ")\\/\"");
}
}
Come puoi vedere, richiedendo il formato data ISO 8601 otterrai il formato 2014-07-30T18:34:45 anziché il numero di millisecondi trascorsi dall'epoca, ma assumerà l'ora locale se il valore serializzato ha un Kind uguale a DateTimeKind.Local
.
Quindi ho due suggerimenti per te:aggiorna alla versione 0.23 di NancyFx se sei ancora alla versione 0.22 o precedente (la versione 0.22 utilizzava il formato data "s", che non include informazioni sul fuso orario, per serializzare i valori DateTime).E se gli oggetti DateTime che stai serializzando non sono impostati esplicitamente su DateTimeKind.Utc
, quindi assicurati di specificare Utc
(poiché l'impostazione predefinita è Unspecified
, che NancyFx considera equivalente a Local
).