Pergunta

Eu tenho procurado muito, mas não conseguiu encontrar uma solução. Como você lida com um DateTime que deve ser capaz de conter um valor não inicializado (equivalente a null)? Eu tenho uma classe que pode ter um conjunto valor da propriedade DateTime ou não. Eu estava pensando em inicializar o titular da propriedade para DateTime.MinValue, que então poderia ser facilmente verificada. Eu acho que esta é uma pergunta muito comum, como você faz isso?

Foi útil?

Solução

Para DateTimes normais, se você não inicializá-los em tudo, então eles vão corresponder DateTime.MinValue, porque é um tipo de valor, em vez de um tipo de referência.

Você também pode usar um DateTime anulável, como este:

DateTime? MyNullableDate;

Ou a forma mais:

Nullable<DateTime> MyNullableDate;

E, finalmente, há um construído em forma de referenciar o padrão de qualquer tipo. Isso retorna null para tipos de referência, mas para o nosso exemplo DateTime ele irá retornar o mesmo que DateTime.MinValue:

default(DateTime)

Outras dicas

Se você estiver usando o .NET 2.0 (ou posterior), você pode usar o tipo anulável:

DateTime? dt = null;

ou

Nullable<DateTime> dt = null;

, em seguida, mais tarde:

dt = new DateTime();

E você pode verificar o valor com:

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

Ou você pode usá-lo como:

DateTime dt2 = dt ?? DateTime.MinValue;

Você pode ler mais aqui:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

DateTime? MyDateTime {get; set;}

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

A seguir caminho funciona bem

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

Por favor, note que a propriedade PublishDate deve ser DateTime?

eu consideraria usando um anuláveis ??tipos .

DateTime? myDate vez de DateTime myDate.

Você pode usar uma classe anulável.

DateTime? date = new DateTime?();

Você pode usar um DateTime anulável para isso.

Nullable<DateTime> myDateTime;

ou a mesma coisa escrito assim:

DateTime? myDateTime;

Eu sempre definir o tempo para DateTime.MinValue. Desta forma, eu não obter qualquer NullErrorException e posso compará-lo para uma data que eu sei que não está definido.

É importante ressaltar que, enquanto uma variável DateTime não pode ser null, ele ainda pode ser comparado a null sem um erro do compilador:

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

Você pode definir o DateTime para Nullable. Por padrão DateTime não é anulável. Você pode torná-lo nulo em um par de formas. Usando um ponto de interrogação após o tipo DateTime? MyTime ou usando o estilo genérico Nullable. Eu adicionei um par de links no MSDN.

Usando Nullable

Nullable

Apenas ser avisado - Ao usar um Nullable sua, obviamente, não é mais um 'puro' datetime objeto, como tal, você não pode acessar os membros DateTime diretamente. Vou tentar explicar.

Ao usar Nullable <> você está envolvendo basicamente DateTime em um recipiente (obrigado genéricos) das quais é anulável - obviamente o seu propósito. Este recipiente tem suas próprias propriedades que você pode chamar que irá proporcionar o acesso ao objeto DateTime acima mencionado; depois de usar a propriedade correta - neste caso Nullable.Value - então você tem acesso aos membros DateTime padrão, propriedades etc

.

Então - agora a questão vem à mente como a melhor maneira de acessar o objeto DateTime. Existem algumas maneiras, o número 1 é de longe o melhor e 2 é "cara porquê".

  1. Usando a propriedade Nullable.Value,

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

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

  2. Convertendo o objecto nulo em datetime usando Convert.ToDateTime (),

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

Embora a resposta é bem documentada neste momento, acredito que o uso de Nullable foi provavelmente vale postagem sobre. Desculpe se você discordar.

edit:. Removido uma terceira opção, uma vez que foi um pouco demasiado específica e caso dependente

Embora todos já lhe deu a resposta, eu vou falar uma forma que torna mais fácil para passar uma data e hora em uma função

[ERROR: Não é possível converter System.DateTime? para System.DateTime]

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

Agora você pode passar DTE dentro da função sem quaisquer problemas.

Se você é, às vezes, esperando nula você poderia usar algo como isto:

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

Em seu uso de data e hora nulo capaz repositório.

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

Eu tive o mesmo problema que eu tive que dar nulo como parâmetro para DateTime durante a execução de teste de unidade para Lança ArgumentNullException.It trabalhou no meu caso usando a seguinte opção:

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

Dada a natureza de uma data / hora tipo de dados não pode conter um valor null, ou seja, ele precisa conter um valor, ele não pode estar em branco ou conter nada. Se você marcar uma variável de data / hora como nullable então só você pode atribuir um valor nulo a ele. Então, o que você está procurando fazer é uma de duas coisas (pode haver mais, mas eu só posso pensar em dois):

  • Atribuir um valor de data mínimo / hora para a variável, se você não tem um valor para ele. Você pode atribuir um valor máximo de data / hora, bem como - Independentemente da forma como lhe convier. Apenas certifique-se que você é consistente local de largura ao verificar seus valores data / hora. Decidir sobre o uso min ou max e ficar com ela.

  • Mark sua data variável / hora como nullable. Desta forma, você pode definir a variável de data / hora para null se você não tem uma variável a ele.

Deixe-me demonstrar o meu primeiro ponto usando um exemplo. O tipo de variável DateTime não pode ser definido como nulo, ele precisa de um valor, neste caso eu vou configurá-lo para o valor mínimo da DateTime se não houver nenhum valor.

O meu cenário é que eu tenho uma classe BlogPost. Ele tem muitos campos / propriedades diferentes, mas eu escolhi usar apenas dois para este exemplo. DatePublished é quando o artigo foi publicado no site e tem que conter um valor de data / hora. DateModified é quando um post for modificado, por isso não tem de conter um valor, mas pode conter um valor.

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

     public DateTime DatePublished { get; set; }
}

Usando ADO.NET para obter os dados do banco de dados (DateTime.MinValue atribuir é não há nenhum valor):

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

Você pode fazer o meu segundo ponto, marcando o campo DateModified como nullable. Agora você pode configurá-lo para null se não houver nenhum valor para ele:

public DateTime? DateModified { get; set; }

Usando ADO.NET para obter os dados do banco de dados, ele vai olhar um pouco diferente para a forma como foi feito acima (atribuindo null vez 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 isso ajude a esclarecer qualquer confusão. Dado que a minha resposta é de cerca de 8 anos mais tarde você é provavelmente um programador C # especialista até agora:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top