Pregunta

He estado buscando mucho pero no pude encontrar una solución. ¿Cómo lidiar con un DateTime que debería poder contener un valor no inicializado (equivalente a nulo)? Tengo una clase que puede tener un valor de propiedad DateTime establecido o no. Estaba pensando en inicializar el propietario de la propiedad a DateTime.MinValue, que luego podría verificarse fácilmente. Supongo que esta es una pregunta bastante común, ¿cómo haces eso?

¿Fue útil?

Solución

Para los DateTimes normales, si no los inicializa, coincidirán con DateTime.MinValue , porque es un tipo de valor en lugar de un tipo de referencia.

También puede usar un DateTime anulable, como este:

DateTime? MyNullableDate;

O la forma más larga:

Nullable<DateTime> MyNullableDate;

Y, finalmente, hay una forma integrada de hacer referencia al valor predeterminado de cualquier tipo. Esto devuelve null para los tipos de referencia, pero para nuestro ejemplo DateTime, devolverá lo mismo que DateTime.MinValue :

default(DateTime)

Otros consejos

Si está utilizando .NET 2.0 (o posterior) puede usar el tipo anulable:

DateTime? dt = null;

o

Nullable<DateTime> dt = null;

luego más tarde:

dt = new DateTime();

Y puede verificar el valor con:

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

O puedes usarlo como:

DateTime dt2 = dt ?? DateTime.MinValue;

Puedes leer más aquí:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

DateTime? MyDateTime {get; set;}

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

La forma siguiente también funciona

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

Tenga en cuenta que la propiedad PublishDate debe ser DateTime?

Consideraría usar un tipos anulables .

DateTime? myDate en lugar de DateTime myDate .

Puede usar una clase anulable.

DateTime? date = new DateTime?();

Puedes usar un DateTime anulable para esto.

Nullable<DateTime> myDateTime;

o lo mismo escrito así:

DateTime? myDateTime;

Siempre configuro la hora en DateTime.MinValue . De esta manera no obtengo ninguna excepción NullErrorException y puedo compararla con una fecha que sé que no está establecida.

Vale la pena señalar que, si bien una variable DateTime no puede ser null , aún puede compararse con null sin un error de compilación :

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

Puedes establecer el DateTime en Nullable. Por defecto, DateTime no es anulable. Puede hacerlo anulable de varias maneras. ¿Usa un signo de interrogación después del tipo DateTime? myTime o usando el estilo genérico Nullable. He añadido un par de enlaces en msdn.

Using Nullable

Nullable

Solo tenga cuidado: cuando use un Nullable, obviamente ya no es un objeto datetime 'puro', por lo que no puede acceder directamente a los miembros de DateTime. Voy a tratar de explicar.

Al utilizar Nullable < > básicamente, está envolviendo DateTime en un contenedor (gracias a los genéricos) del cual es anulable, obviamente su propósito. Este contenedor tiene sus propias propiedades a las que puede llamar y que proporcionarán acceso al objeto DateTime mencionado anteriormente; después de usar la propiedad correcta, en este caso Nullable.Value, tendrá acceso a los miembros estándar de DateTime, propiedades, etc.

Entonces, ahora el problema viene a la mente en cuanto a la mejor manera de acceder al objeto DateTime. Hay algunas maneras, el número 1 es, por mucho, el mejor y el 2 es " dude por qué " ;.

  1. Usando la propiedad Nullable.Value,

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

    DateTime date = myNullableObject.ToUniversalTime (); // No es un objeto de fecha y hora, falla

  2. Convirtiendo el objeto anulable a datetime utilizando Convert.ToDateTime (),

    DateTime date = Convert.ToDateTime (myNullableObject) .ToUniversalTime (); // funciona pero porque ...

Aunque la respuesta está bien documentada en este momento, creo que vale la pena publicar el uso de Nullable. Lo siento si no está de acuerdo.

editar: se eliminó una tercera opción porque era un poco demasiado específica y dependía del caso.

Aunque todos ya le han dado la respuesta, mencionaré una manera que facilita pasar una fecha y hora a una función

[ERROR: no se puede convertir system.datetime? a system.datetime]

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

Ahora puede pasar dte dentro de la función sin problemas.

Si, a veces, espera nulo, podría usar algo como esto:

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

En su repositorio use datetime nulo.

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

Tuve el mismo problema que tuve que darle a Null como parámetro para DateTime mientras realizaba la prueba de unidad para Throws ArgumentNullException. Funcionó en mi caso usando la siguiente opción:

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

Dada la naturaleza de un tipo de datos de fecha / hora, no puede contener un valor null , es decir, debe contener un valor, no puede estar en blanco o no contener nada. Si marca una variable de fecha / hora como nullable , solo podrá asignarle un valor nulo. Entonces, lo que estás buscando es una de dos cosas (puede que haya más, pero solo puedo pensar en dos):

  • Asigne un valor mínimo de fecha / hora a su variable si no tiene un valor para ella. También puede asignar un valor máximo de fecha / hora, de la forma que más le convenga. Solo asegúrese de ser consistente en todo el sitio cuando verifique sus valores de fecha / hora. Decide utilizar min o max y apégate a él.

  • Marque su variable de fecha / hora como nullable . De esta manera, puede establecer su variable de fecha / hora en null si no tiene una variable.

Déjame demostrar mi primer punto usando un ejemplo. El tipo de variable DateTime no se puede establecer en nulo, necesita un valor, en este caso lo estableceré en el valor mínimo de DateTime si no hay ningún valor .

Mi escenario es que tengo una clase BlogPost . Tiene muchos campos / propiedades diferentes, pero elegí solo usar dos para este ejemplo. DatePublished es cuando la publicación se publicó en el sitio web y debe contener un valor de fecha / hora. DateModified es cuando se modifica una publicación, por lo que no tiene que contener un valor, pero puede contener un valor.

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

     public DateTime DatePublished { get; set; }
}

Usando ADO.NET para obtener los datos de la base de datos (asigne DateTime.MinValue si no hay ningún valor):

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

Puede lograr mi segundo punto marcando el campo DateModified como Nullable . Ahora puede establecerlo en null si no tiene ningún valor:

public DateTime? DateModified { get; set; }

Usando ADO.NET para obtener los datos de la base de datos, se verá un poco diferente a la forma en que se hizo anteriormente (asignando null en lugar de DateTime.MinValue ):

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

Espero que esto ayude a aclarar cualquier confusión. Dado que mi respuesta es aproximadamente 8 años después, probablemente ya sea un programador experto en C # :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top