La chaîne n'a pas été reconnue comme un «format DateHeure valide» jj / MM / aaaa

172

J'essaie de convertir ma valeur formatée de chaîne en type de date avec format dd/MM/yyyy.

this.Text="22/11/2009";

DateTime date = DateTime.Parse(this.Text);

Quel est le problème ? Il a un deuxième remplacement qui demande IFormatProvider. Qu'est-ce que c'est? Dois- je également le transmettre? Si oui, comment l'utiliser pour ce cas?

Éditer

Quelles sont les différences entre Parseet ParseExact?

Modifier 2

Les deux réponses de Slaks et de Sam fonctionnent pour moi, actuellement l'utilisateur donne l'entrée mais cela sera assuré par moi qu'elles sont valides en utilisant maskTextbox.

Quelle réponse est la meilleure compte tenu de tous les aspects tels que la sécurité du type, les performances ou quelque chose qui vous plaît

Shantanu Gupta
la source
7
@Edit: C'est à cela que sert la documentation. msdn.microsoft.com/en-us/library/w2sa9yss.aspx
SLaks
2
ParseExact est pour lorsque vous connaissez le format exact de la chaîne de date, Parse est lorsque vous voulez quelque chose qui peut gérer quelque chose d'un peu plus dynamique.
gingerbreadboy

Réponses:

255

Utilisez DateTime.ParseExact.

this.Text="22/11/2009";

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", null);
Samuel Neff
la source
8
Pourquoi devons-nous passer nul ici?
Shantanu Gupta
3
L'entrée peut être "22/11/2009 12:00:00 AM" ou "22/11/2009". La culture de la machine de développement peut également être différente de la culture de la production. Alors, le code ci-dessus fonctionnera-t-il de manière transparente?
Rahatur
8
@Rahat, l'analyse exacte ne fonctionnera pas si le format ne correspond pas. Le modèle de format ci-dessus est dd/MM/yyyydonc une chaîne de texte avec une heure ne sera pas analysée correctement. Vous devrez soit supprimer l'heure, soit l'inclure dans le modèle de format. Il y a une surcharge ParseExactqui accepte un tableau de modèles de format et analysera le texte s'il correspond à l'un d'entre eux.
Samuel Neff
7
@SamuelNeff Pourquoi ne pas utiliser à la CultureInfo.InvariantCultureplace du format actuel si vous définissez quand même un format?
Alvin Wong
3
@Toolkit La raison est que les barres obliques dans la chaîne de format ne sont pas des barres obliques littérales. Ils sont remplacés par la chaîne de séparateur de date dans la culture actuelle. Cela dépend donc de la culture telle qu'elle est écrite ci-dessus. Samuel Neff, essayez Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");, cela cassera votre solution. Pour résoudre ce problème, utilisez "dd'/'MM'/'yyyy"(en protégeant les barres obliques par des guillemets simples), ou @"dd\/MM\/yyyy"("échapper" les barres obliques inversées).
Jeppe Stig Nielsen
44

Vous devez appeler ParseExact, qui analyse une date qui correspond exactement à un format que vous fournissez.

Par exemple:

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);

Le IFormatProviderparamètre spécifie la culture à utiliser pour analyser la date.
À moins que votre chaîne ne vienne de l'utilisateur, vous devriez réussir CultureInfo.InvariantCulture.
Si la chaîne provient de l'utilisateur, vous devez la transmettre CultureInfo.CurrentCulture, qui utilisera les paramètres spécifiés par l'utilisateur dans Options régionales du Panneau de configuration.

SLaks
la source
2
@Slaks: CultureInfo.InvariantCulture n'est pas disponible dans le code. Dois-je utiliser un espace de noms
Shantanu Gupta
3
using System.Globalization;
SLaks
2
Vous pouvez également cliquer avec le bouton droit de la souris sur l'erreur et cliquer sur résoudre, cela mettra l'espace de noms manquant pour vous.
Inkey
vous pouvez également double-cliquer sur l'erreur et voir une flèche vers le bas indiquant les espaces de noms associés que vous pouvez utiliser
Usman Younas
Les espaces comptent aussi, donc par exemple si votre format de chaîne est "MM / jj / aaaa HH: mm: ss" (note - 2 espaces) - alors votre format pour ParseExact doit également inclure les espaces
Chris Halcrow
20

L'analyse d'une représentation sous forme de chaîne d'un DateTime est une chose délicate car différentes cultures ont des formats de date différents. .Net connaît ces formats de date et les extrait de votre culture actuelle ( System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat) lorsque vous appelez DateTime.Parse(this.Text);

Par exemple, la chaîne "22/11/2009" ne correspond pas au ShortDatePattern pour les États-Unis (en-US) mais correspond à la France (fr-FR).

Désormais, vous pouvez soit appeler DateTime.ParseExactet transmettre la chaîne de format exacte que vous attendez, soit transmettre une culture appropriée DateTime.Parsepour analyser la date.

Par exemple, cela analysera votre date correctement:

DateTime.Parse( "22/11/2009", CultureInfo.CreateSpecificCulture("fr-FR") );

Bien sûr, vous ne devriez pas choisir la France au hasard, mais quelque chose qui correspond à vos besoins.

Ce que vous devez savoir, c'est ce qui System.Threading.Thread.CurrentThread.CurrentCultureest défini et si / pourquoi il diffère de ce que vous attendez.

Greg
la source
votre solution ne fonctionne pas pour moi, elle donne une erreur du type "La chaîne n'a pas été reconnue comme un DateHeure valide." et je passe la date d'entrée suivante: "13/06/17" à votre solution mais cela donne une erreur. Aidez-moi.
Ghanshyam Lakhani
16

Bien que les solutions ci-dessus soient efficaces, vous pouvez également modifier le fichier webconfig avec ce qui suit ...

<configuration>
   <system.web>
     <globalization culture="en-GB"/>
   </system.web>
</configuration>

Réf: format Datetime différent sur la machine locale par rapport à la machine de production

Amit Philips
la source
1
Amit Philips, tu m'as sauvé la journée .. J'avais essayé toutes les choses possibles. Et ce petit changement fonctionne. Merci.
RNH
1
Amit, vous êtes vraiment le fils de Dieu.
The Furious Bear
10

Vous devrez peut-être spécifier la culture pour ce format de date spécifique comme dans:

    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); //dd/MM/yyyy

    this.Text="22/11/2009";

    DateTime date = DateTime.Parse(this.Text);

Pour plus de détails, allez ici:

http://msdn.microsoft.com/en-us/library/5hh873ya.aspx

Ricardo Sanchez
la source
4

Après avoir passé beaucoup de temps, j'ai résolu le problème

 string strDate = PreocessDate(data);
 string[] dateString = strDate.Split('/');
 DateTime enter_date = Convert.ToDateTime(dateString[1]+"/"+dateString[0]+"/"+dateString[2]);
atik sarker
la source
3

utilisez ceci pour convertir une chaîne en datetime:

Datetime DT = DateTime.ParseExact(STRDATE,"dd/MM/yyyy",System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat)
AshifJM
la source
3

Sur la base de cette référence , la prochaine approche a fonctionné pour moi:

// e.g. format = "dd/MM/yyyy", dateString = "10/07/2017" 
var formatInfo = new DateTimeFormatInfo()
{
     ShortDatePattern = format
};
date = Convert.ToDateTime(dateString, formatInfo);
Jesús Castro
la source
2
private DateTime ConvertToDateTime(string strDateTime)
{
DateTime dtFinaldate; string sDateTime;
try { dtFinaldate = Convert.ToDateTime(strDateTime); }
catch (Exception e)
{
string[] sDate = strDateTime.Split('/');
sDateTime = sDate[1] + '/' + sDate[0] + '/' + sDate[2];
dtFinaldate = Convert.ToDateTime(sDateTime);
}
return dtFinaldate;
}
Bala Kumar
la source
1

Tout comme quelqu'un l'a dit ci-dessus, vous pouvez l'envoyer en tant que paramètre de chaîne, mais il doit avoir ce format: '20130121' par exemple et vous pouvez le convertir dans ce format en le prenant directement à partir du contrôle. Ainsi, vous l'obtiendrez par exemple à partir d'une zone de texte comme:

date = datetextbox.text; // date is going to be something like: "2013-01-21 12:00:00am"

pour le convertir en: '20130121' vous utilisez:

date = date.Substring(6, 4) + date.Substring(3, 2) + date.Substring(0, 2);

afin que SQL puisse le convertir et le mettre dans votre base de données.

G Jeny Ramirez
la source
0

Vous pouvez également utiliser

this.Text = "22112009";
DateTime newDateTime = new DateTime(Convert.ToInt32(this.Text.Substring(4, 4)), // Year
                                    Convert.ToInt32(this.Text.Substring(2,2)), // Month
                                    Convert.ToInt32(this.Text.Substring(0,2)));// Day
Serkan Hekimoglu
la source
0

A travaillé pour moi sous le code:

DateTime date = DateTime.Parse(this.Text, CultureInfo.CreateSpecificCulture("fr-FR"));

Espace de noms

using System.Globalization;
Anjan Kant
la source
-6

Changer manuellement:

string s = date.Substring(3, 2) +"/" + date.Substring(0, 2) + "/" + date.Substring(6, 4);

À partir du 22/11/2015, il sera converti le 22/11/2015

sarta
la source