2016-03-30 22 views
13

C'è questo servizio web SOAP che mi manda gli oggetti datetime nel seguente formatocome analizzare e generare oggetti DateTime in formato ISO 8601

2016-03-29T12:20:35.093-05:00 

Questo è il giorno 29 del mese di marzo dell'anno 2016. Ora: 12: 20: 35.093 (GMT-5).

Voglio essere in grado di creare un oggetto DateTime, in questo modo:

DateTime.Now 

e ottenere la rappresentazione di stringa nel formato descritto sopra e anche l'operazione inversa, creare un DateTime da una stringa come quella dato sopra.

Ho provato quanto segue al fine di creare la data:

new DateTime(2016, 3, 29, 12, 20, 35, 093, DateTimeKind.Utc) 

Tuttavia, non posso non vedere come specifie GMT-5 ci ...

non lo faccio sapere come convertire un DateTime nel formato stringa specificato, sia.

Utilizzando il codice di Nate che sto facendo quanto segue:

var d = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-3)); 

FormatIso8601(d) 

Tuttavia questa chiamata sta tornando: "2016-03-29T15: 20: 35Z" invece di:

"2016-03-29T12:20:35.093-03:00" 

che è ciò di cui ho effettivamente bisogno.

Penso che questo funziona:

 d.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz") 
+1

Hai ancora tenta di provare l'uso 'DateTime.Parse'? – leppie

+0

Sì, ma non sono riuscito a trovare il modo di farlo. Altrimenti non sarei venuto qui per chiedere –

+3

Hai bisogno di spiegare cosa puoi o non puoi fare, esattamente. – leppie

risposta

21

Il formato si sta descrivendo è ISO 8601.

Dato che si sta lavorando con i timestamp che includono un componente del fuso orario, si consiglia vivamente di utilizzare DateTimeOffset anziché DateTime. Rende le cose molto più facili!

Per creare un DateTimeOffset per una data, l'ora e il fuso orario determinato offset, utilizzare la seguente sintassi:

var date = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-5)); 
// March 29, 2016 at 12:20:35.93 GMT-5 

Questo codice formattare un DateTimeOffset come ISO 8601:

public static string FormatIso8601(DateTimeOffset dto) 
{ 
    string format = dto.Offset == TimeSpan.Zero 
     ? "yyyy-MM-ddTHH:mm:ss.fffZ" 
     : "yyyy-MM-ddTHH:mm:ss.fffzzz"; 

    return dto.ToString(format, CultureInfo.InvariantCulture); 
} 

E, per analizzare una stringa di nuovo a DateTimeOffset:

public static DateTimeOffset ParseIso8601(string iso8601String) 
{ 
    return DateTimeOffset.ParseExact(
     iso8601String, 
     new string[] { "yyyy-MM-dd'T'HH:mm:ss.FFFK" }, 
     CultureInfo.InvariantCulture, 
     DateTimeStyles.None); 
} 

Se si deve tornare a un DateTime è possibile ottenere questo dal DateTimeOffset. UtcDateTime proprietà.

+0

Grazie mille. È sicuro farlo? ParseIso8601 (myDate) .DateTime per ottenere un oggetto datetime? Nel mio sistema avrei bisogno di datetimes invece di datetimeoffsets, se possibile. Grazie –

+0

È possibile, ma fai attenzione agli effetti collaterali indesiderati: il tempo che ottieni dipende dal fuso orario locale della tua macchina. UtcDateTime restituirà sempre un tempo UTC, se si desidera evitare tale conversione. –

+1

Quindi è impossibile ottenere un oggetto DateTime che rappresenta la stessa ora esatta passata nella stringa a ParseIso8601? –

12

Un modo più semplice è utilizzare il metodo ToString su DateTimeOffset con l'argomento "o". Questa stampa automaticamente la data nel formato ISO8601

DateTimeOffset.Now.ToString("o"); 

Il metodo parse statico è anche in grado di analizzare correttamente una data in formato ISO8601.

DateTimeOffset.Parse("2016-25-12T20:45:30.3124+01:00"); 
DateTimeOffset.Parse("2016-25-12T20:45:30.3124Z"); 
0

Risposta semplice: DateTime.UtcNow.ToString("o")