web-dev-qa-db-fra.com

DateTime "null" valeur

J'ai beaucoup cherché mais je n'ai pas trouvé de solution. Comment gérez-vous un DateTime qui devrait pouvoir contenir une valeur non initialisée (équivalente à null)? J'ai une classe qui pourrait avoir une valeur de propriété DateTime définie ou non. Je pensais initialiser le détenteur de la propriété à DateTime.MinValue, qui pourrait ensuite être facilement vérifié. Je suppose que c'est une question assez commune, comment faites-vous cela?

256
Mats

Pour DateTimes normal, si vous ne les initialisez pas du tout, ils correspondront à DateTime.MinValue, car il s'agit d'un type de valeur plutôt que d'un type de référence.

Vous pouvez également utiliser un DateTime nullable, comme ceci:

DateTime? MyNullableDate;

Ou la forme la plus longue:

Nullable<DateTime> MyNullableDate;

Et, enfin, il existe un moyen intégré de faire référence à la valeur par défaut de n’importe quel type. Cela retourne null pour les types de référence, mais pour notre exemple DateTime, il retournera la même chose que DateTime.MinValue:

default(DateTime)
400
Joel Coehoorn

Si vous utilisez .NET 2.0 (ou une version ultérieure), vous pouvez utiliser le type nullable:

DateTime? dt = null;

ou

Nullable<DateTime> dt = null;

puis plus tard:

dt = new DateTime();

Et vous pouvez vérifier la valeur avec:

if (dt.HasValue)
{
  // Do something with dt.Value
}

Ou vous pouvez l'utiliser comme:

DateTime dt2 = dt ?? DateTime.MinValue;

Vous pouvez lire plus ici:
http://msdn.Microsoft.com/en-us/library/b3h38hb0.aspx

83
Mark Ingram

DateTime? MyDateTime {get; set;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
28
Iman Abidi

La voie suivante fonctionne aussi bien

myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;

Veuillez noter que la propriété PublishDate devrait être DateTime?

24
Aleksei

J'envisagerais d'utiliser un types nullable .

DateTime? myDate au lieu de DateTime myDate.

12
David Mohundro

Vous pouvez utiliser une classe nullable.

DateTime? date = new DateTime?();
6
Aaron Smith

Vous pouvez utiliser un DateTime nullable pour cela.

Nullable<DateTime> myDateTime;

ou la même chose écrite comme ceci:

DateTime? myDateTime;
6
Patrik Svensson

Il convient de souligner que, bien qu'une variable DateTime ne puisse pas être null, elle peut tout de même être comparée à null sans erreur de compilation:

DateTime date;
...
if(date == null) // <-- will never be 'true'
  ...
6
uncoder

Je règle toujours l'heure sur DateTime.MinValue. De cette façon, je n’obtiens aucune exception NullErrorException et je peux la comparer à une date qui, à mon avis, n’est pas définie.

5
Patrick Desjardins

Vous pouvez définir le DateTime sur Nullable. Par défaut, DateTime n'est pas nullable. Vous pouvez le rendre annulable de plusieurs manières. Utilisation d'un point d'interrogation après le type DateTime? myTime ou en utilisant le style générique Nullable. J'ai ajouté quelques liens sur msdn.

tilisation de Nullable

Nullable

4
user29958

Soyez juste averti: lorsque vous utilisez un objet Nullable, il ne s'agit évidemment plus d'un objet datetime pur: vous ne pouvez donc pas accéder directement aux membres DateTime. Je vais essayer d'expliquer.

En utilisant Nullable <>, vous encapsulez DateTime dans un conteneur (merci aux génériques) dont la valeur est nullable - de toute évidence, son objectif. Ce conteneur possède ses propres propriétés que vous pouvez appeler pour fournir un accès à l'objet DateTime susmentionné; après avoir utilisé la propriété correcte, dans le cas présent Nullable.Value, vous avez alors accès aux membres DateTime standard, aux propriétés, etc.

Alors maintenant, la question vient à l’esprit quant à la meilleure façon d’accéder à l’objet DateTime. Il y a plusieurs façons, le numéro 1 est de loin le meilleur et le 2 est "mec pourquoi".

  1. Utilisation de la propriété Nullable.Value,

    DateTime date = myNullableObject.Value.ToUniversalTime(); //Works

    DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails

  2. Conversion de l'objet nullable en date-heure à l'aide de Convert.ToDateTime (),

    DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why...

Bien que la réponse soit bien documentée à ce stade, je pense que l'utilisation de Nullable valait probablement la peine d'être signalée. Désolé si vous n'êtes pas d'accord.

edit: Suppression d'une troisième option car elle était un peu trop spécifique et dépendait de la casse.

3
Gabe

Bien que tout le monde vous ait déjà donné la réponse, je mentionnerai un moyen qui permet de passer facilement une date/heure à une fonction

(ERREUR: impossible de convertir system.datetime? À system.datetime]

DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);

Maintenant, vous pouvez passer dte dans la fonction sans aucun problème.

2
No Holidays

J'ai eu le même problème que je devais donner Null comme paramètre pour DateTime lors du test de l'unité pour Throws ArgumentNullException.Il a fonctionné dans mon cas en utilisant l'option suivante:

Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
1
Kiril Dobrev

Si vous vous attendez parfois à null, vous pouvez utiliser quelque chose comme ceci:

var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)

Dans votre référentiel, utilisez date-heure nullable.

public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
1
DarkoM

Étant donné la nature d'un type de données date/heure, il ne peut pas contenir de valeur null. En d'autres termes, il doit contenir une valeur. Elle ne peut être ni vide ni vide. Si vous marquez une variable date/heure comme étant nullable, vous ne pourrez alors lui affecter qu'une valeur nulle. Donc, ce que vous cherchez à faire est une des deux choses (il y en a peut-être plus, mais je ne peux penser qu'à deux):

  • Attribuez une valeur date/heure minimale à votre variable si vous n'en avez pas. Vous pouvez également attribuer une valeur maximale de date/heure - selon votre choix. Assurez-vous simplement que votre site est cohérent lors de la vérification de vos valeurs de date/heure. Choisissez d'utiliser min ou max et respectez-le.

  • Marquez votre variable date/heure comme étant nullable. De cette façon, vous pouvez définir votre variable date/heure sur null si vous n’avez pas de variable.

Permettez-moi de démontrer mon premier point en utilisant un exemple. Le type de variable DateTime ne peut pas être défini sur null, il nécessite une valeur. Dans ce cas, je vais le définir sur la valeur minimale de DateTime s'il n'y a pas de valeur.

Mon scénario est que j'ai une classe BlogPost. Il a beaucoup de champs/propriétés différents mais j’ai choisi d’en utiliser deux pour cet exemple. DatePublished est le moment où l'article a été publié sur le site Web et doit contenir une valeur de date/heure. DateModified est le moment où une publication est modifiée, elle ne doit donc pas nécessairement contenir de valeur, mais peut contenir une valeur.

public class BlogPost : Entity
{
     public DateTime DateModified { get; set; }

     public DateTime DatePublished { get; set; }
}

Utilisation de ADO.NET pour extraire les données de la base de données (attribuez DateTime.MinValue s'il n'y a pas de valeur):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

Vous pouvez accomplir mon deuxième point en marquant le champ DateModified comme nullable. Maintenant, vous pouvez le définir sur null s'il n'y a pas de valeur pour cela:

public DateTime? DateModified { get; set; }

En utilisant ADO.NET pour obtenir les données de la base de données, cela aura un aspect légèrement différent de la façon dont cela a été fait ci-dessus (attribution de null au lieu de DateTime.MinValue):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

J'espère que cela aide à dissiper toute confusion. Étant donné que ma réponse est environ 8 ans plus tard, vous êtes probablement un expert en programmation C # à ce jour :)

0
Brendan Vogt