Question

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?

Était-ce utile?

La solution

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;

Enfin, il existe une méthode intégrée pour référencer les valeurs par défaut de tous les types. Cela renvoie null pour les types de référence, mais pour notre exemple DateTime, il retournera la même chose que DateTime.MinValue :

default(DateTime)

Autres conseils

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 en lire plus ici:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

DateTime? MyDateTime {get; set;}

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

La méthode suivante fonctionne également

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

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

J'envisagerais d'utiliser un types nullable .

DateTime? myDate au lieu de DateTime myDate .

Vous pouvez utiliser une classe nullable.

DateTime? date = new DateTime?();

Vous pouvez utiliser un DateTime nullable pour cela.

Nullable<DateTime> myDateTime;

ou la même chose écrite comme ceci:

DateTime? myDateTime;

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.

Il convient de noter 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'
  ...

Vous pouvez définir 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.

Utilisation de Nullable

Nullable

Soyez juste averti - Lorsque vous utilisez Nullable, ce n’est évidemment plus un objet datetime pur: vous ne pouvez donc pas accéder directement aux membres DateTime. Je vais essayer d'expliquer.

En utilisant Nullable < > vous enveloppez essentiellement DateTime dans un conteneur (merci les 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, aux propriétés, etc.

Alors - maintenant, le problème vient à l’esprit quant à la meilleure façon d’accéder à l’objet DateTime. Il existe 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 (); // Objet non datetime, échoue

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

    DateTime date = Convert.ToDateTime (myNullableObject) .ToUniversalTime (); // fonctionne mais pourquoi ...

Bien que la réponse soit bien documentée à ce stade, j'estime que l'utilisation de Nullable méritait sans doute 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.

Bien que tout le monde vous ait déjà donné la réponse, je vais mentionner 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.

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 une date et heure NULL.

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

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

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

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

  • Attribuez une valeur date / heure minimale à votre variable si vous n’avez pas de valeur pour celle-ci. 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 nullable . De cette façon, vous pouvez définir votre variable date / heure sur null si vous n’avez pas de variable.

Me laisser 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 correspond au moment où l'article a été publié sur le site Web et doit contenir une valeur date / heure. DateModified correspond au moment où une publication est modifiée. Il n'est donc pas nécessaire qu'elle contienne une 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 obtenir 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 . Vous pouvez maintenant le définir sur null s'il n'y a pas de valeur pour cela:

public DateTime? DateModified { get; set; }

L’utilisation de ADO.NET pour extraire les données de la base de données donnera un aspect légèrement différent de celui décrit 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 vous aidera à 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:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top