2009-10-16 10 views
11

Abbiamo un'applicazione di analisi i valori di data/ora nel seguente formato:Convert.ToDateTime provoca FormatException alla data pomeriggio/ora valori

2009-10-10 09:19:12.124 
2009-10-10 12:13:14.852 
2009-10-10 13:00:00 
2009-10-10 15:23:32.022 

Un particolare server di tutto l'improvviso (oggi) iniziate ad un'analisi non corretta qualsiasi ore 13:00:00 o successive. Questo particolare client ha cinque server e solo uno ha il problema. Abbiamo dozzine di altri client con un totale di centinaia di server senza il problema.

System.FormatException: String was not recognized as a valid DateTime. 
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles) 
at System.DateTime.Parse(String s, IFormatProvider provider) 
at System.Convert.ToDateTime(String value, IFormatProvider provider) 
at System.String.System.IConvertible.ToDateTime(IFormatProvider provider) 
at System.Convert.ToDateTime(Object value) 

ho fatto un test utilizzando DateTime.Parse (s, CultureInfo.CurrentCulture) a paragone di DateTime.Parse (s, CultureInfo.InvariantCulture) e il problema mostra solo con CurrentCulture. Tuttavia, CurrentCulture è "en-US", proprio come tutti gli altri server e non c'è nulla di diverso che posso trovare nelle impostazioni regionali o della lingua.

Qualcuno ha visto questo prima? Suggerimenti relativi a ciò che posso esaminare?

EDIT: Grazie per le risposte finora. Tuttavia, sto cercando suggerimenti su quale configurazione esaminare in modo che possa aver causato questo cambiamento improvviso del comportamento e smettere di funzionare quando ha funzionato per anni e funziona su centinaia di altri server. L'ho già cambiato per la prossima versione, ma sto cercando una modifica alla configurazione per correggerla nel frattempo per l'installazione corrente.

risposta

3

Abbiamo anche riscontrato lo stesso problema. Basta riciclare il pool di applicazioni.

+0

Sì, ma ... perché? Abbiamo lo stesso problema sporadicamente. Il nostro servizio Web converte un oggetto DateTime C# in una stringa e lo passa a una procedura di database di SQL Server che si aspetta una piccola data. Per qualche ragione, a volte questo sposta il tempo di 12 ore, quindi l'invio della data di oggi passa come oggi a mezzogiorno (12:00:00 PM) invece di oggi a mezzanotte (12:00:00). –

0

Sembra che in qualche modo l'oggetto della cultura non stia interpretando la notazione militare del tempo. Onestamente non sono sicuro di dove andare da lì, ma potrebbe darti un punto di partenza.

7

Se si conosce esattamente il formato, indicare all'applicazione cosa è: utilizzare DateTime.ParseExact anziché solo DateTime.Parse. (E come altri hanno detto, specificare la cultura invarianti pure, per togliere più variazioni.) Che ti dà molto più controllo:

using System; 
using System.Globalization; 

class Test 
{ 
    static void Main() 
    { 
     Parse("2009-10-10 09:19:12.124"); 
     Parse("2009-10-10 12:13:14.852"); 
     Parse("2009-10-10 13:00:00"); 
     Parse("2009-10-10 15:23:32.022"); 
    } 

    static readonly string ShortFormat = "yyyy-MM-dd HH:mm:ss"; 
    static readonly string LongFormat = "yyyy-MM-dd HH:mm:ss.fff"; 

    static readonly string[] Formats = { ShortFormat, LongFormat }; 

    static void Parse(string text) 
    { 
     // Adjust styles as per requirements 
     DateTime result = DateTime.ParseExact(text, Formats, 
               CultureInfo.InvariantCulture, 
               DateTimeStyles.AssumeUniversal); 
     Console.WriteLine(result); 
    } 
} 
2

La soluzione è molto semplice, utilizzare CultureInfo.InvariantCulture. Per i dati di esempio è l'unica cosa sensata da fare.

So che questo non spiega la differenza, ma il software in realtà non dovrebbe fare affidamento sulla cultura "predefinita" (tranne forse nell'interfaccia utente).

+1

Anche con la cultura invariabile non farei affidamento sui formati predefiniti - specificare il formato in modo esplicito, quindi è chiaro cosa aspettarsi. –

0

Qual è il valore della proprietà CultureInfo.DateTimeFormat? According to MSDN:

"L'utente potrebbe scegliere di ignorare alcuni dei valori associati al cultura corrente di Windows attraverso la porzione opzioni internazionali e della lingua del Pannello di controllo, ad esempio, l'utente potrebbe scegliere di. visualizzare la data in un formato diverso o per utilizzare un valuta diversa da quella di default per la cultura.

Se UseUserOverride è vero e il lingua specificata corrisponda al cur affittare cultura Windows, il CultureInfo utilizza tali sostituzioni, tra utente impostazioni per le proprietà dell'istanza DateTimeFormatInfo restituiti dalla proprietà DateTimeFormat, e le proprietà del NumberFormatInfo istanza restituita dal NumberFormat proprietà.Se le impostazioni utente sono incompatibili con la cultura associato al CultureInfo, per esempio, se il calendario è selezionata non una delle OptionalCalendars, i risultati dei metodi ei valori delle proprietà sono indefiniti.

Il valore della proprietà DateTimeFormat e la proprietà NumberFormat non viene calcolato fino a quando l'applicazione accede alla proprietà. Se l'utente può modificare l'attuale cultura a una nuova cultura mentre l'applicazione è in esecuzione e quindi l'applicazione accede alla proprietà DateTimeFormat o NumberFormat , l'applicazione recupera le impostazioni predefinite per la nuova cultura invece delle sostituzioni per la cultura originale . Per conservare i le sostituzioni per la corrente cultura d'origine, l'applicazione deve accedere il DateTimeFormat e NumberFormat proprietà prima di cambiare l'attuale cultura ".

Potrebbe essere una certa regolazione utente è over-riding questo?

0

E 'un ipotesi, ma forse qualcosa di simile sequenza di eventi potrebbero aver causato il problema:

  1. un amministratore va in Cont rol Impostazioni internazionali di Panel su tutti i server e cambia il formato dell'ora da "HH: mm: ss" a "hh: mm: ss tt".
  2. L'amministratore ricicla il pool di applicazioni (o il servizio IIS o la macchina) su uno solo dei server.

Tutti i nuovi thread di lavoro ASP.NET sul server riciclato ora vedranno il formato dell'ora modificato e i loro metodi DateTime.Parse avranno esito negativo. Tuttavia, se gli altri server stanno ancora utilizzando i thread di lavoro originali, non hanno ancora rilevato le modifiche alla cultura corrente DateTimeFormatInfo.

È uno scenario molto improbabile, ma ripeto, si ha una situazione molto improbabile. Potresti provare a riciclare il pool di applicazioni in questione su tutti i server e vedere se qualcosa cambia.

3

Abbiamo un servizio Web C# .NET 2.0 in esecuzione su un server Windows 2003. Quel servizio è attivo da più di due anni. Recentemente abbiamo srtarted degli errori in quell'applicazione. Il messaggio di errore è "La stringa non è stata riconosciuta come un DateTime valido". Un'altra servie web restituisce una data, e che la funzione dovrebbe restituire un valore come

"5/10/2010 00:00:00"

Quando gli errori si verificano la funzione restituisce

"5/10/2010 00:00:00"

il ritorno non corretta, dispone di spazi bianchi alla fine e non AM.

Questo problema è apparso e scomparso più volte nelle prossime due settimane. Dopo aver esaminato i registri di Windows, abbiamo notato che l'ora di inizio e di fine degli errori coincidevano (entro un minuto o due) di un riciclo del pool di applicazioni impostato (per impostazione predefinita) da verificarsi ogni 29 ore. Questo problema si è verificato solo sul server Web di produzione e non sui server di sviluppo o di test. Abbiamo provato a sostituire il server e non ci sono stati errori per un mese. Ora gli errori sono ricominciati. Abbiamo ripristinato manualmente il pool e il problema è scomparso immediatamente. Preferiremmo non considerarla come una soluzione accettabile, poiché la piscina ricicla regolarmente. Non sappiamo se abbiamo bisogno del riciclo della piscina, ma siamo consapevoli che i ricicli regolari aiutano le prestazioni delle applicazioni.

L'applicazione web utilizza ParseExact() già, ma la stringa di formato è simile al seguente:

"AAAA-MM-DDHH: mm: ss.0Z"

invece di

"yyyy-mM-dd hh: mm: ss"

suggerito da Jon Skeet in questa discussione. Non so se questo farebbe molta differenza.

Abbiamo anche controllato le impostazioni della cultura.

Sembra chiaro che il problema inizia con il riciclo del pool di applicazioni, ma non ho idea di cosa si verifichi durante il ciclo di riciclo. Il più delle volte il riciclo non ha alcun effetto negativo e quando si verificano gli errori, il prossimo riciclo ha sempre bloccato gli errori.

+0

@Dan Bruton Non l'abbiamo risolto. Il problema si è risolto in un paio di volte da quando ho scritto questo, e il riciclaggio risolve temporaneamente il problema. Stiamo valutando di cambiare i tempi del riciclo per assicurare che accada alla stessa ora ogni settimana e siamo pronti per questo, ma non abbiamo ancora idea di quale sia il vero problema. Abbiamo lavorato anche con Microsoft su questo, e non sembrano avere un'idea migliore di noi. –

+0

Eventuali altri aggiornamenti su questo? Ho assistito personalmente a questo stesso problema e ho preso un ricordo della memoria del processo nel momento in cui stava accadendo. Quello che ho visto era che la memorizzazione di un datetime come un oggetto generico, quindi l'estrazione di un datetime stava perdendo le informazioni sulla cultura (molto casualmente, ovviamente ... apparentemente impossibile da riprodurre) – mpeterson

1

Ho appena trovato alcune informazioni su ciò che sta causando questo problema. Il nostro client C# invia una data di business (solo data) come valore di stringa a un servizio Web. Il servizio Web passa questa stringa in uno SqlParameter a un SqlCommand a una stored procedure che accetta un parametro datetime per la data dell'attività.

Il sistema di un cliente si è improvvisamente comportato in modo anomalo. Ho usato SQL Server Profiler per guardare le chiamate RPC e ho notato che il parametro data aveva improvvisamente un componente orario. Questo dovrebbe essere un valore solo per la data-- cioè il 27/10/2012 alle 12:00 AM.

Ho modificato la stored procedure per aggiungere WAITFOR DELAY '00:01:00'. Ho quindi acquisito un dump della memoria del servizio Web mentre stava effettuando la chiamata a questa stored procedure.

Esaminando il dump della memoria, ho rilevato che il client aveva passato la stringa di data corretta di "2012-10-25 00:00:00" in un DataSet di parametri. Il servizio web in qualche modo ha incasinato la conversione di queste date quando ha chiamato la stored procedure. Ho trovato il SqlCommand nel dump ed ho esaminato lo SqlParameter corrispondente al parametro data della stored procedure. Il valore era "25/10/2012 12:00:00 PM".

Guardando tutti gli oggetti CultureInfo, ho trovato che la locale 1033 per "en-US" aveva una stringa lunga di "h: mm: ss tt". L'AMDesignator era "AM", ma il PMDesignator era una stringa vuota! Ho verificato questa è stata la causa della data di male in C# eseguendo il comando seguente:

// clear the PM designator 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "" 
// this will yield "12/25/2012 12:00:00 " (note the extra space at the end) 
Convert.ToDateTime("10/25/2012").ToString() 

Il risultato è stato "2012/10/25 00:00:00", che corrisponde a quello che Brian Begley nella sua risposta.Utilizzando il formato invariante produce un risultato molto simile:

// clear the PM designator 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "" 
// this will yield "10/25/2012 12:00:00" 
Convert.ToDateTime("10/25/2012").ToString(System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) 
// restore the PM designator to "PM" 
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator = "PM" 
// this will yield "10/25/2012 00:00:00" 
Convert.ToDateTime("10/25/2012").ToString(System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) 

devo ancora determinare che cosa sta causando il CultureInfo essere danneggiato.

Si noti che Microsoft is aware of this issue. L'articolo collegato dice che si applica solo a Windows Server 2003 e che è disponibile un hotfix.

+0

+1 per informazioni interessanti e problemi simili . –