2009-10-16 12 views
11

mamy analizowania aplikacji wartości daty/godziny w następującym formacie:Convert.ToDateTime powoduje FormatException na bieżąco popołudnie/ceni czas

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 

jednego konkretnego serwera wszystkie z nagłym (dzisiaj) rozpoczęte braku analizować każdy razy 13:00:00 lub później. Ten konkretny klient ma pięć serwerów i tylko jeden ma problem. Mamy dziesiątki innych klientów z setkami serwerów bez problemu.

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) 

I prowadziła badanie przy DateTime.Parse (s, CultureInfo.CurrentCulture) comapred do DateTime.Parse (s, CultureInfo.InvariantCulture) i problem pokazuje tylko z CurrentCulture. Jednak CurrentCulture jest "en-US", podobnie jak wszystkie inne serwery i nie ma nic, co można znaleźć w ustawieniach regionalnych lub językowych.

Czy ktoś to widział wcześniej? Sugestie dotyczące tego, na co mogę spojrzeć?

EDYCJA: Dziękuję za odpowiedzi do tej pory. Jednak szukam sugestii na temat konfiguracji, która mogła spowodować zmianę zachowania i przestać działać, gdy działa od lat i działa na setkach innych serwerów. Już zmieniłem to dla następnej wersji, ale szukam zmiany konfiguracji, aby naprawić to w międzyczasie dla bieżącej instalacji.

Odpowiedz

3

Również napotkaliśmy ten sam problem. Po prostu odzyskuj swoją pulę aplikacji.

+0

Tak, ale ... dlaczego? Ten sam problem występuje sporadycznie. Nasz serwis internetowy konwertuje obiekt C# DateTime na ciąg znaków i przekazuje go do procedury bazy danych programu SQL Server, która oczekuje niewielkiego czasu. Z jakiegoś powodu czasami przesuwa to czas o 12 godzin, więc wysłanie dzisiejszej daty mija tak jak dziś w południe (12:00:00) zamiast dzisiaj o północy (12:00:00). –

0

Wygląda na to, że obiekt kultury nie rozumie militarnej notacji czasu. Naprawdę nie jestem pewien, dokąd się udać, ale może dać ci punkt wyjścia.

7

Jeśli znasz dokładnie format, powiedz aplikacji, co to jest - użyj DateTime.ParseExact zamiast tylko DateTime.Parse. (I jak mówili inni, określ kultury niezmienny, jak również, aby zabrać dowolną więcej wariancji). To daje dużo większą kontrolę:

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

Rozwiązanie jest bardzo proste, należy CultureInfo.InvariantCulture. Dla przykładowych danych, które są jedyną rozsądną rzeczą do zrobienia.

Wiem, że to nie wyjaśnia różnicy, ale twoje oprogramowanie naprawdę nie powinno polegać na "domyślnej" kulturze (może poza tym w interfejsie użytkownika).

+1

Nawet przy niezmiennej kulturze nie polegałbym na domyślnych formatach - jawnie określ format, a następnie jasne, czego się spodziewasz. –

0

Jaka jest wartość właściwości CultureInfo.DateTimeFormat? According to MSDN:

„Użytkownik może wybrać, aby zastąpić niektóre wartości związanych z bieżącej kultury systemu Windows przez część Opcje regionalne i językowe z Panelu Sterowania Na przykład, użytkownik może wybrać. wyświetlanie daty w innym formacie lub używanie walucie innej niż domyślna dla kultury.

Jeśli UseUserOverride jest prawdą i określona kultura pasuje CUR wynajem kulturę systemu Windows, CultureInfo używa tych przesłonięcia, w tym użytkownikiem ustawienia właściwości przykład DateTimeFormatInfo zwróconego przez właściwość DateTimeFormat i właściwości NumberFormatInfo przykład zwracanej przez NumberFormat nieruchomości.Czy ustawienia użytkownika są niezgodne z kulturą związanego z CultureInfo na przykład, jeżeli wybrany kalendarz jest żaden z OptionalCalendars, że wyniki metody i wartości właściwości są niezdefiniowane.

Wartość nieruchomości DateTimeFormat a właściwość numberFormat nie jest liczony do momentu aplikacja dostęp do nieruchomości. Jeśli użytkownik może zmienić obecną kultury do nowej kultury, podczas gdy aplikacja jest uruchomiony, a następnie aplikacja dostęp właściwość DateTimeFormat lub numberFormat , aplikacja pobiera domyślne ustawienia dla nowej kultury zamiast nadpisania dla oryginalna kultura. Aby zachować przesłonięcia dla oryginalnego bieżącym kultury, aplikacja powinna przejść DateTimeFormat i numberFormat właściwości przed zmianą aktualnego kulturę.”

Może to być jakiś ustawień użytkownika jest nadrzędnym jest?

0

to dzikie przypuszczenie, ale może coś w tej sekwencji zdarzeń mogło spowodować problem:

  1. administrator idzie do Cont rol Panel International ustawienia na wszystkich serwerach i zmienia format czasu z "HH: mm: ss" na "hh: mm: ss tt".
  2. Administrator przetwarza pulę aplikacji (lub usługę IIS lub maszynę) tylko na jednym z serwerów.

Wszystkie nowe wątki pracujące w środowisku ASP.NET na serwerze z odzysku będą teraz wyświetlane w zmienionym formacie czasu, a ich metody będą nieudane. Jeśli jednak inne serwery nadal używają oryginalnych wątków roboczych, to nie wykryły jeszcze zmian w obecnej kulturze DateTimeFormatInfo.

To bardzo mało prawdopodobny scenariusz, ale z drugiej strony sytuacja jest bardzo nieprawdopodobna. Możesz spróbować użyć odpowiedniej puli aplikacji na wszystkich serwerach i sprawdzić, czy coś się zmieni.

3

Mamy usługę WWW w języku C# .NET 2.0 działającą na serwerze Windows 2003. Usługa ta działa od ponad dwóch lat. Niedawno zaczęliśmy doświadczać błędów w tej aplikacji. Komunikat o błędzie to "Ciąg nie został rozpoznany jako poprawny DateTime". Innym internetowej servie zwraca datę i że funkcja powinna zwrócić wartość jak

„5/10/2010 12:00:00 AM”

Gdy błędy występujące funkcja zwraca

"10.05.2010 12:00:00"

nieprawidłowe powrotny ma spacji na końcu i bez AM.

Ten problem pojawił się i zniknął kilka razy w ciągu najbliższych kilku tygodni. Po przeanalizowaniu dzienników systemu Windows zauważyliśmy, że czas rozpoczęcia i zakończenia błędów zbiegł się (w ciągu minuty lub dwóch) z zawracania puli aplikacji, który jest ustawiony (domyślnie) co 29 godzin. Ten problem wystąpił tylko na serwerze produkcyjnym, a nie na serwerach programistycznych lub testowych. Próbowaliśmy zastąpić serwer i nie było błędów przez miesiąc. Teraz błędy zaczęły się ponownie. Ręcznie zresetowaliśmy pulę i problem zniknął natychmiast. Nie chcemy tego postrzegać jako akceptowalnego rozwiązania, ponieważ pula podlega regularnej recyrkulacji. Nie wiemy, czy musimy zrezygnować z puli, ale rozumiemy, że regularne odzyskiwanie danych pomaga w wydajności aplikacji.

Aplikacja internetowa wykorzystuje ParseExact() już, ale ciąg formatu wygląda następująco:

"yyyy-MM-ddHH: mm: ss.0Z"

zamiast

"rrrr mM-dd HH: mM: SS"

sugeruje Jon Skeet w tym wątku. Nie wiem, czy to by miało duże znaczenie.

Sprawdziliśmy również ustawienia kultury.

Wydaje się jasne, że problem zaczyna się od recyklingu puli aplikacji, ale nie mam pojęcia, co dzieje się pod maską podczas tej operacji. W większości przypadków recykling nie ma negatywnego wpływu, a gdy wystąpią błędy, następny recykling zawsze zatrzymywał błędy.

+0

@Dan Bruton Nie naprawiliśmy tego. Problem pojawił się kilka razy, odkąd to napisałem, a recykling rozwiązuje problem tymczasowo. Rozważamy zmianę czasu recyklingu, aby mieć pewność, że zdarza się to w tym samym czasie każdego tygodnia i jesteśmy na to gotowi, ale wciąż nie mamy pojęcia, jaki jest prawdziwy problem. Pracowaliśmy z tym również nad Microsoftem i wydaje się, że nie mają lepszego pomysłu niż my. –

+0

Jakieś inne informacje na ten temat? Sam byłem świadkiem tego samego problemu i w tym czasie wziąłem pod uwagę pamięć tego procesu. To, co tam zobaczyłem, polegało na przechowywaniu datetime jako obiektu generycznego, a następnie wycofaniu go z bazy danych, tracąc informacje o kulturze (bardzo losowo, oczywiście ... pozornie niemożliwe do odtworzenia) – mpeterson

1

Właśnie znalazłem informacje o przyczynie tego problemu. Nasz klient C# wysyła datę biznesową (tylko datę) jako wartość ciągu do usługi WWW. Usługa sieciowa przekazuje ten ciąg w SqlParameter do SqlCommand do procedury przechowywanej, która akceptuje parametr datetime dla daty biznesowej.

System klienta nagle zachowywał się niepoprawnie. Użyłem programu SQL Server Profiler do obejrzenia wywołań RPC i zauważyłem, że parametr daty nagle zawiera komponent czasu. To ma być wartość tylko dla daty - tj. 10/27/2012 12:00:00.

Zmodyfikowałem procedurę przechowywaną, aby dodać WAITFOR DELAY '00:01:00'. Następnie uzyskałem zrzut pamięci usługi internetowej podczas wykonywania wywołania tej procedury przechowywanej.

Badając zrzut pamięci, stwierdziłem, że klient przeszedł poprawny łańcuch daty "2012-10-25 00:00:00" w zestawie parametrów. Usługa sieciowa w jakiś sposób zawiodła konwersję tych dat, kiedy wywołała procedurę przechowywaną. Znalazłem SqlCommand w zrzucie i zbadałem parametr SqlParameter odpowiadający parametrowi daty procedury składowanej. Wartość wynosiła "10/25/2012 12:00:00 PM".

Patrząc na wszystkie obiekty CultureInfo, stwierdziłem, że locale 1033 dla "en-US" ma długi ciąg "h: mm: ss tt". AMDesignator był "AM", ale PMDesignator był pusty ciąg! I zweryfikować to było przyczyną złej daty w C#, uruchamiając następujące polecenie:

// 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() 

Wynik był „25.10.2012 12:00:00”, który odpowiada temu, co Brian Begley w swojej odpowiedzi.Korzystanie niezmiennego wzoru daje bardzo podobny wynik:

// 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) 

mam jeszcze ustalić, co jest przyczyną CultureInfo być uszkodzony.

Należy pamiętać, że Microsoft is aware of this issue. Łączony artykuł mówi, że dotyczy tylko systemu Windows Server 2003 i dostępna jest poprawka.

+0

+1 za interesujące informacje i podobne problemy . –

Powiązane problemy