11
votes

Convertir.TodateTime provoque la formateXception sur les valeurs de date / heure de l'après-midi

Nous avons une application d'analyse des valeurs de date / heure dans le format suivant:

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)


0 commentaires

8 Réponses :


0
votes

On dirait que l'objet de la culture ne comprend pas la notation de temps militaire. Je ne sais honnêtement pas où aller de là, mais cela peut vous donner un point de départ.


0 commentaires

7
votes

Si vous connaissez exactement le format, indiquez l'application ce qu'elle est - utilisez datetime.parseexact code> au lieu de DateTime.parse code>. (Et comme d'autres l'ont dit, spécifiez également la culture invariante, d'emporter plus de variation.) Cela vous donne beaucoup plus de contrôle:

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);
    }
}


0 commentaires

2
votes

La solution est très simple, utilisez cultureinfo.invarianTculture . Pour les échantillons de données qui sont la seule chose sensible à faire.

Je sais que cela n'explique pas la différence, mais votre logiciel ne devrait vraiment pas compter sur la culture «Parfait» (sauf peut-être dans l'interface utilisateur).


1 commentaires

Même avec la culture invariante, je ne voudrais pas compter sur les formats par défaut - spécifier le format explicitement, il est clair que vous attendez.



0
votes

Quelle est la valeur du cultureinfo.dateTimeformat ? Selon MSDN :

"L'utilisateur peut choisir de remplacer certaines des valeurs associées au Culture actuelle des fenêtres à travers le Partie des options régionales et de langues du panneau de commande. Par exemple, le l'utilisateur peut choisir d'afficher la date dans un format différent ou d'utiliser un monnaie autre que la valeur par défaut pour la culture.

Si UseUserAveroverride est vrai et le La culture spécifiée correspond au courant Culture des fenêtres, la cultureinfo utilise ces substitutions, y compris l'utilisateur Paramètres des propriétés de la DateTimeFormatinfo Instance renvoyée par la propriété DateTimeFormat, et les propriétés du numérosformatinfo instance renvoyée par le numérosformat biens. Si les paramètres utilisateur sont incompatible avec la culture associé au cultureinfo, pour exemple, si le calendrier sélectionné est pas l'un des facultatifscalendars, le résultats des méthodes et des valeurs des propriétés ne sont pas définies.

la valeur de DateTimeFormat Propriété et la propriété NumberForSat n'est pas calculé avant votre L'application accède à la propriété. Si L'utilisateur peut changer le courant culture à une nouvelle culture alors que le l'application est en cours d'exécution et puis le L'application accède à la DateTimeFormat ou NumberFormat propriété, l'application récupère Les valeurs par défaut pour la nouvelle culture au lieu des dérogations pour le Culture originale. Préserver le remplacements pour le courant d'origine culture, l'application doit accéder à le DateTimeFormat et NumberFormat Propriétés avant de changer le courant Culture. "

pourrait-il être un certain paramètre d'utilisateur est surmonté cela?


0 commentaires

0
votes

C'est une supposition sauvage, mais peut-être que quelque chose comme cette séquence d'événements aurait pu causer le problème:

  1. Un administrateur passe dans les paramètres internationaux du panneau de contrôle sur tous les serveurs et modifie le format de l'heure de "HH: MM: SS" à "HH: MM: SS TT".
  2. L'administrateur recycle le pool d'applications (ou le service IIS, ou la machine) sur un seul des serveurs.

    Tous les nouveaux threads de travailleur ASP.NET sur le serveur recyclé, le format de l'heure recyclé et leur DateTime.Parse échouera. Toutefois, si les autres serveurs utilisent toujours les threads de travailleur d'origine, ils n'ont pas encore détecté les modifications apportées à la culture actuelle DateTimeFormatinfo .

    C'est un scénario très improbable, mais encore une fois, vous avez une situation très improbable. Vous pouvez essayer de recycler le pool d'applications correspondant sur tous les serveurs et voir si quelque chose change.


0 commentaires

3
votes

Nous avons également rencontré le même problème. Il suffit de recycler votre pool de demande.


1 commentaires

Oui mais pourquoi? Nous avons le même problème sporadiquement. Notre service Web convertit un objet DateTime C # à une chaîne et la transmet à une procédure de base de données SQL Server qui attend un smalldateTime. Pour une raison quelconque, cela change parfois l'heure de 12 heures, l'envoi de la date d'aujourd'hui se passe comme aujourd'hui à midi (12:00:00) au lieu d'aujourd'hui à minuit (12:00:00).



3
votes

Nous avons un service Web C # .NET 2.0 en cours d'exécution sur un serveur Windows 2003. Ce service fonctionnait depuis plus de deux ans. Nous avons récemment fait des erreurs de victoires dans cette application. Le message d'erreur est "String non reconnu comme une dateTétime valide". Une autre servie Web retourne une date et cette fonction doit renvoyer une valeur comme

"5/10/2010 12:00:00 AM"

Lorsque les erreurs se produisent, la fonction renvoie

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

Le retour incorrect a l'espace blanc à la fin et non AM.

Ce problème est apparu et a disparu plusieurs fois au cours des deux prochaines semaines. Après avoir examiné les journaux de Windows, nous avons remarqué que les heures de début et de fin des erreurs coïncidaient (dans une minute ou deux) d'un recyclage de pool d'applications défini (par défaut) pour se produire toutes les 29 heures. Ce problème ne s'est produit que sur le serveur Web de production et non sur les serveurs de développement ou de test. Nous avons essayé de remplacer le serveur et il n'y avait aucune erreur pendant un mois. Maintenant, les erreurs ont recommencé. Nous réinitialisons manuellement la piscine et le problème a disparu immédiatement. Nous préférerions ne pas voir cela comme une solution acceptable, car la piscine recycle régulièrement. Nous ne savons pas si nous avons besoin de la recyclage de la piscine, mais nous croyons comprendre que les recycles réguliers aident à la performance des applications.

L'application Web utilise déjà parseexact () mais la chaîne de format ressemble à ceci:

"AAAA-MM-DDHHHH: MM: SS.0Z"

au lieu de

"AAAA-MM-DD HH: MM: SS"

suggéré par Jon Skeet dans ce fil. Je ne sais pas si cela ferait beaucoup de différence.

Nous avons également vérifié les paramètres de culture.

Il semble clair que le problème commence par le recyclage du pool d'applications, mais je ne sais pas ce qui se passe sous la hotte pendant ce recyclage. La plupart du temps, le recyclage n'a pas d'effet négatif, et lorsque les erreurs se produisent, le prochain recyclage a toujours arrêté les erreurs.


2 commentaires

@Dan Bruton Nous ne l'avons pas corrigé. Le problème a lancé un coup de pied à quelques reprises depuis que j'ai écrit cela et que le recyclage corrige temporairement le problème. Nous envisageons de modifier le calendrier de la recyclage pour s'assurer que cela se produit à la même période chaque semaine et que nous sommes prêts, mais nous n'avons toujours aucune idée de ce que le vrai problème est. Nous avons également travaillé avec Microsoft à ce sujet et ils ne semblent pas avoir une meilleure idée que nous.


Toute autre mise à jour à ce sujet? J'ai été témoin de ce même problème moi-même et j'ai pris une mémoire de mémoire du processus au moment où elle se produirait. Ce que j'ai vu, il y avait là que vous stockiez une date d'heure comme un objet générique, puis la retirez-la en tant que DateTime perdait les informations de culture (très au hasard, bien sûr ... apparemment impossible à reproduire)



1
votes

Je viens de trouver des informations sur ce qui cause cette question. Notre client C # envoie une date d'activité (date uniquement) en tant que valeur de chaîne à un service Web. Le service Web passe cette chaîne dans un sqlparameter à un SQLCOMMAND à une procédure stockée qui accepte un paramètre DateTime code> pour la date de travail.

Le système d'un client était soudainement mal se comporter. J'ai utilisé le profileur SQL Server pour regarder les appels RPC et remarqua que le paramètre Date avait soudainement un composant temporel. Ceci est censé être une valeur de date seulement-- IE 10/27/2012 12:00:00 AM. P>

J'ai modifié la procédure stockée pour ajouter un Waitfor Delay '00: 01: 00 ' code>. J'ai ensuite acquis une mémoire de mémoire du service Web alors qu'elle faisait appel à cette procédure stockée. P>

examinant la mémoire de mémoire, j'ai constaté que le client était passé dans la chaîne de date correcte de "2012-10 -25 00:00:00 "dans un ensemble de données de paramètres. Le service Web est en quelque sorte gâché la conversion de ces dates lorsqu'elle a appelé la procédure stockée. J'ai trouvé le SQLCOMMAND dans la décharge et examiné le SQLPARAMÈTRE correspondant au paramètre de date de la procédure stockée. La valeur était "10/25/2012 12:00:00 h" MM: SS TT ". L'amdesignor était "am", mais le pmdesignator était une chaîne vide em>! J'ai vérifié que c'était la cause de la mauvaise date en C # en exécutant la commande suivante: p> xxx pré>

Le résultat était "10/25/2012 12:00:00" "qui correspond à ce que Brian Begley dans sa réponse. L'utilisation du format invariant donne un résultat très similaire: P>

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


0 commentaires