Em nosso projeto C #, temos a necessidade de representar uma data sem hora. Eu sei da existência do DateTime, no entanto, ele incorpora uma hora do dia também. Quero deixar explícito que certas variáveis e argumentos de método são baseados em datas . Portanto, não posso usar a DateTime.Date
propriedade
Quais são as abordagens padrão para este problema? Certamente não sou o primeiro a encontrar isso? Por que não há Date
classe em C #?
Alguém tem uma boa implementação usando uma estrutura e talvez alguns métodos de extensão em DateTime e talvez implementando alguns operadores como == e <,>?
DateTime
cria?Respostas:
Permita-me adicionar uma atualização a esta pergunta clássica:
A biblioteca Noda Time de Jon Skeet agora está bastante madura e tem um tipo apenas para data chamado
LocalDate
. (Local neste caso significa apenas local para alguém , não necessariamente local para o computador onde o código está sendo executado.)Um tipo apenas de data chamado
Date
é uma adição proposta ao .NET Core, por meio do projeto corefxlab . Você o encontrará noSystem.Time
pacote, junto com umTimeOfDay
tipo e vários métodos de extensão para os tipos existentes.Estudei esse problema de maneira significativa, então também compartilharei vários motivos para a necessidade desses tipos:
Há uma discrepância lógica entre um valor apenas para data e um valor para data à meia-noite.
Nem todo dia local tem meia-noite em todos os fusos horários. Exemplo: a transição do horário de verão na primavera para o futuro no Brasil move o relógio de 11:59:59 para 01:00:00.
Uma data e hora sempre se refere a uma hora específica dentro do dia, enquanto uma data apenas pode se referir ao início do dia, ao final do dia ou a todo o intervalo do dia.
Anexar uma hora a uma data pode fazer com que a data mude conforme o valor é passado de um ambiente para outro, se os fusos horários não forem monitorados com muito cuidado. Isso normalmente ocorre em JavaScript (cujo
Date
objeto é realmente uma data + hora), mas pode acontecer facilmente em .NET também, ou na serialização conforme os dados são passados entre JavaScript e .NET.Serializar um
DateTime
com XML ou JSON (e outros) sempre incluirá a hora, mesmo que não seja importante. Isso é muito confuso, especialmente considerando coisas como datas de nascimento e aniversários, em que o tempo é irrelevante.Arquitetonicamente,
DateTime
é um objeto-valor DDD , mas viola o Princípio da Responsabilidade Única de várias maneiras:Ele é projetado como um tipo de data + hora, mas geralmente é usado apenas como data (ignorando a hora) ou apenas hora do dia (ignorando a data). (
TimeSpan
também é frequentemente usado para a hora do dia, mas isso é outro tópico.)O
DateTimeKind
valor anexado à.Kind
propriedade divide o tipo único em três. OUnspecified
tipo é realmente a intenção original da estrutura e deve ser usado dessa forma. OUtc
tipo alinha o valor especificamente com UTC, e oLocal
tipo alinha o valor com o fuso horário local do ambiente.O problema de ter um sinalizador separado para o tipo é que toda vez que você consome um
DateTime
, você deve verificar.Kind
para decidir qual comportamento tomar. Todos os métodos do framework fazem isso, mas outros geralmente esquecem. Isso é realmente uma violação SRP, pois o tipo agora tem dois motivos diferentes para mudar (o valor e o tipo).Os dois levam a usos de API que compilam, mas geralmente são absurdos ou têm casos extremos estranhos causados por efeitos colaterais. Considerar:
Em resumo, embora um
DateTime
possa ser usado apenas para uma data, ele só deve fazê-lo quando todos os lugares que o usam forem muito cuidadosos para ignorar a hora e também para não tentar converter de e para UTC ou outro fusos horários.fonte
System.Time.Date
terminasse na estrutura .NET: /System.Time
como qualquer outro pacote. Só não é "oficial" ainda.Eu suspeito que não haja nenhuma
Date
classe dedicada pura porque você já tem umaDateTime
que pode lidar com isso. TerDate
levaria à duplicação e confusão.Se você quiser a abordagem padrão, observe a
DateTime.Date
propriedade que fornece apenas a parte da data de aDateTime
com o valor da hora definido para 12:00:00 meia-noite (00:00:00).fonte
Mandei um email para [email protected] e essa é a resposta
No meu e-mail, eu questionava se era porque DateTime usa TimeZoneInfo para obter a hora da máquina - na propriedade Now. Eu diria que é porque "as regras de negócio" são "muito acopladas", eles me confirmaram.
fonte
SpaceTime
aula! Ei, de acordo com Einstein, espaço e tempo estão fortemente acoplados, então não devemos precisar diferenciá-los também, certo? (!!!!!!!!!!!) Eu estou meio novo para C #, mas eu tenho que dizer, é um campo minado vindo de VB.NET, onde é, simplesmente,date
,Today()
,now
, etc. NãoDateTime
lixo prefixo, não sujando sobre. (E esses pontos-e-vírgulas e essaDate
tipo e o resultado deve ser do tipoDate
- se fosse oDate
tipo resultado esperado como string sem tempo. Por exemplo, Delphi também tem Date como DateTime, mas digite informações diferentes para Date e DateTime.Criei uma estrutura de data simples para momentos em que você precisa de uma data simples sem se preocupar com a parte do tempo, fusos horários, local vs. utc, etc.
https://github.com/claycephus/csharp-date
fonte
Se você precisar executar comparações de datas, use
Se você estiver exibindo na tela, use
fonte
Permita-me especular: talvez seja porque até o SQL Server 2008 não havia tipo de dados Date no SQL, então seria difícil armazená-los no SQL server ?? E afinal é um produto Microsoft?
fonte
Quem sabe porque é assim. Existem muitas decisões de design incorretas no .NET framework. No entanto, acho que este é um problema bem menor. Você sempre pode ignorar a parte da hora, portanto, mesmo se algum código decidir que DateTime se refira a mais do que apenas a data, o código que se preocupa deve olhar apenas para a parte da data. Alternativamente, você pode criar um novo tipo que representa apenas uma data e usar funções em DateTime para fazer o trabalho pesado (cálculos).
fonte
Por quê? Podemos apenas especular e isso não ajuda muito a resolver problemas de engenharia. Um bom palpite é que
DateTime
contém todas as funcionalidades que tal estrutura teria.Se for realmente importante para você, apenas envolva
DateTime
em sua própria estrutura imutável que apenas expõe a data (ou observe aDateTime.Date
propriedade).fonte
Além da resposta de Robert, você também tem o
DateTime.ToShortDateString
método. Além disso, se você realmente deseja um objeto Date, pode sempre usar o padrão Adapter e envolver o objeto DateTime, expondo apenas o que deseja (ou seja, mês, dia, ano).fonte
Sempre há a
DateTime.Date
propriedade que corta a parte do tempo doDateTime
. Talvez você possa encapsular ou envolver DateTime em seu próprio tipo de data.E para a pergunta por que, bem, acho que você terá que perguntar a Anders Heljsberg.
fonte
Porque para saber a data, você tem que saber a hora do sistema (em ticks), que inclui a hora - então por que jogar fora essa informação?
DateTime
tem umaDate
propriedade se você não se importa nem um pouco com o tempo.fonte
Sim, também System.DateTime é selado. Já vi algumas pessoas brincar com isso criando uma classe personalizada apenas para obter o valor da string de tempo, conforme mencionado em postagens anteriores, coisas como:
Isso talvez seja desnecessário, já que você poderia facilmente extrair GetShortTimeString de um tipo DateTime antigo sem uma nova classe
fonte
Se você usar as propriedades Date ou Today para obter apenas a parte da data do objeto DateTime.
Em seguida, você obterá o componente de data apenas com o componente de hora definido para meia-noite.
fonte