Por que não existe um verdadeiro tipo de dados "Somente data"?

24

Estou tão ridiculamente frustrado por ter que usar valores DateTime para conjuntos de dados que são realmente "apenas um dia". Os aniversários são o exemplo mais comum, mas isso aparece nos aplicativos de negócios o tempo todo.

Eu me acostumei apenas a definir a parte da Hora dos registros "somente para data" como "meio-dia" (que evita que a data seja sempre alterada, independentemente do fuso horário). Parece um hack, e estou sempre encontrando bugs de desenvolvedores juniores que tropeçam nessa questão.

O tempo é sempre relativo a um ponto fixo. 16:00 é de 4 horas após o meridiano, ou meio-dia. O ponto mais alto do sol em trânsito é observável e permite a criação de um sistema de coordenadas. 3 horas antes do meio dia (Ante Meridian), 2 horas depois do meio dia, 1441899402938 milissegundos desde 1º de janeiro de 1970. Para as pessoas criadas em um mundo cartesiano, isso é uma segunda natureza.

Mas nosso calendário é anterior a Descartes. Meu argumento é que é mais adequadamente pensado como uma enumeração sobre a qual uma função de módulo é aplicada. Segunda-feira segue domingo, e assim por diante até chegar ao fato de que domingo segue sábado. Não há positivo e negativo, é um módulo ou valor absoluto.

Da mesma forma com anos repetindo. A cada 365 dias (mais ou menos), existem vários dias especiais para mim: aniversários, aniversários, aniversários de crianças, etc. etc. nós PODEMOS mapear isso em um número de ponto flutuante e, na verdade, mapear esse número resolve muitos problemas que são realmente difíceis da maneira antiga, mas isso não significa que é a única maneira de fazê-lo.

A conscientização e o entendimento da natureza do "uso de DateTimes para armazenar datas" tornam o programador melhor na minha opinião.

Existe valor em um aplicativo explicitamente destinado a ser um aplicativo de agendamento na definição de uma classe Date ou é "definir todos os horários ao meio-dia" a melhor abordagem? Quais problemas podem ocorrer com o uso do DateTime e com a configuração do componente Hora como Meio-dia? A mudança de fuso horário pode ser considerada nessa abordagem? Eu usei o MomentJS, mas acho que essa é apenas uma classe Date melhor.

Michael Blackburn
fonte
7
esta é uma pergunta bastante interessante, eu acho. Tomemos o exemplo do aniversário, isso realmente faz sentido em humanos, estou morando em um lugar e todo mundo acorda na mesma hora, de certa forma. assim que você precisar expressá-lo matematicamente, ele se tornará muito complexo. Mesmo com coisas como turnos de trabalho vezes de início / fim etc eles não são 'tempos' são 'horas do dia no fuso horário no qual você está trabalhando'
Ewan
3
O NodaTime (uma biblioteca C # para Data e Hora) tem um tipo de datas.
CodesInChaos
5
Armazene seus horários como UTC, sem problemas de data, sem problemas de fuso horário.
Loren Pechtel 11/11/15
3
"Mas, Deus, isso parece um hack, e eu estou sempre encontrando bugs de desenvolvedores juniores que tropeçam nessa questão." - por que você não cria sua própria classe DateOnly ou o que quer que seja e termina o dia?
Brandin
5
@MichaelBlackburn Estou falando sério. Sua explicação soa exatamente a situação para um tipo de dados próprio que aplica a regra de negócios (somente data, por exemplo, você pode armazená-lo como um "DateTime" internamente com a parte do tempo definida para meio-dia), mas depois apenas expor as partes que você deseja (mês , dia etc. ano / sem ano).
Brandin

Respostas:

15

Antes de tudo, vamos tirar uma coisa do caminho: aniversários são uma coisa, datas de nascimento são outra. Um aniversário é um tipo de dados exótico porque não possui apenas os componentes de horas, minutos etc., mas também o componente do ano. Se você realmente deseja lidar com aniversários, recomendo inventar seu próprio tipo de dados, que contém apenas um número de mês e um número de dia, e não está relacionado a nenhum dos tipos de dados de data e hora incorporados.

Por outro lado, se você também deseja acompanhar o ano de nascimento, o que você tem não são os aniversários, são as datas de nascimento . Portanto, a pergunta agora é por que não há um tipo de dados somente para data, para que você possa representar convenientemente as datas de nascimento e, em vez disso, os idiomas populares parecem forçá-lo a usar algum tipo que também inclui um componente de tempo.

Permitam-me mencionar brevemente que não é verdade que todas as linguagens de programação oferecem apenas tipos de dados temporais que incluem um componente de tempo. Encontrei tipos de dados somente de data nos RDBMSes e em seus dialetos SQL correspondentes. Mas isso é irrelevante: o fato de esses tipos de dados existirem não significa que eles sejam bons, e os RDBMSs têm um longo histórico de confusão de armazenamento com representação.

Você entenderá por que é uma má idéia ter esses tipos de dados somente para data no momento em que você perceber que a hora é uma coordenada. A maioria das pessoas tem uma idéia muito vaga do que é o tempo, e essa idéia contém noções culturais misteriosas, como anos, meses e dias, sem perceber que essas noções são exclusivamente representativas : elas são úteis apenas para representar o tempo para um humano e para receber tempo como entrada de um ser humano. Em qualquer camada abaixo do controle da GUI real de entrada de tempo, o tempo deve ser, e geralmente é, representado como uma coordenada de tempo, que é um número único de unidades de tempo desde alguma origem.

Por exemplo, no DateTimetipo de dados do Microsoft Dotnet, a unidade de tempo é de 100 nanossegundos e a origem do tempo é 12:00 da meia-noite de 1º de janeiro de 0001 CE

Outro exemplo de uma notação arcana, exclusivamente representacional, é a medição de ângulos usando graus, minutos de grau e segundos de grau. Obviamente, para obter qualquer cálculo útil, é necessário usar internamente radianos e, se necessário, converter de e para graus ao interagir com um usuário humano.

Portanto, não confunda a representação legível por humanos de uma medida com a natureza real da medida. Muitas vezes, o método ideal para realizar uma medida, que mais se aproxima da natureza da medida, é muito diferente da representação legível por humanos dessa medida.

À luz de tudo isso, sua solicitação de um tipo de dados temporais que representa apenas datas é semelhante a uma solicitação de um tipo de dados angular que seria capaz apenas de representar graus, impedindo explicitamente qualquer precisão maior. Esse tipo de dado seria bastante limitado e, em última análise, inútil, porque você teria que convertê-lo para e de radianos de qualquer maneira, a fim de obter algo útil com ele.

Seu problema com a data de nascimento é que você tem uma coordenada imprecisa da hora: a pessoa nasceu, é claro, em um momento específico, mas a hora e o minuto não foram registrados pelo hospital ou não se preocupam com eles. Então, o que realmente está acontecendo é que sua coordenada de data e hora do nascimento tem uma margem de erro, tolerância ou incerteza, se você desejar, e é melhor tratá-lo da seguinte maneira: coloque-o exatamente no meio do dia e considere uma incerteza implícita de 12 a 12 horas. E essa é precisamente a solução que você chegou intuitivamente.

Mike Nakis
fonte
4
Isso não é verdade para "Dias", que são um conceito ainda mais antigo que o Tempo. Eles são mais apropriadamente pensados ​​como uma enumeração ou um módulo. Domingo segue segunda-feira, etc, até voltarmos para domingo, que segue sábado. É realmente uma coisa diferente.
Michael Blackburn
10
Bem, é claro que o hospital anotou a hora do nascimento - essa é uma prática padrão na maioria dos hospitais. Não é esse o problema. A questão é que, para fins de comemoração de eventos (aniversários, feriados, aniversários, etc.), as pessoas não usam ou desejam uma resolução melhor que 1 dia. Vá perguntar à primeira pessoa que você vê quando é o aniversário deles, e eles lhe dão um mês e um dia, mas nunca uma hora e um minuto. Além disso: usamos unidades que incluem escala o tempo todo: milímetro, quilograma, megawatt e, de fato, microfarad.
Caleb
4
-1: nem todos os usos do tempo representam um único momento no tempo. Um aniversário é uma ideia diferente, representada por um mês e um dia no calendário gregoriano. Faz sentido perguntar "hoje é o aniversário de Kevin?" A resposta depende da localização. Se estou em Sydney, poderia ser meu aniversário, mas se estivesse em Honolulu, ainda não passaria algumas horas.
kevin cline
6
@ MikeNakis O resultado seria microamps, não bobagem. Mais importante: quando você usa uma data em vez de um segundo ou milissegundo, geralmente está falando sobre o dia inteiro - um período de tempo - em vez de um horário específico e, dependendo do contexto, pode ser um evento repetitivo.
Caleb
4
O OP estava falando sobre aniversários, que são exatamente representados por java.util.MonthDay. Um aniversário não é uma medida, é a noção humana de um dia que se repete anualmente. Existem muitas idéias humanas de tempo que não são representadas por um único ponto no tempo.
kevin cline
9

Datas e horários são muitas coisas diferentes, dependendo do contexto, e você precisa de muitos tipos separados para cobrir todos os casos de uso.

O DateTimetipo presente em muitos idiomas representa um ponto preciso no tempo ("tempo instantâneo"). Além disso, temos vários conceitos relativos ou "humanos" de tempo e período de tempo, como dias de calendário, datas recorrentes, meses, anos etc. que são, em muitos casos, ambíguos e dependentes do contexto. Esses tipos não são tão universalmente úteis, mas necessários em domínios de aplicativos específicos, como calendários, ferramentas de agendamento e outros aplicativos que interagem com os conceitos humanos de tempo.

Se você estiver escrevendo algo como um aplicativo de calendário, certamente se beneficiaria do uso de uma biblioteca como o Joda-time, que fornece um conjunto mais rico de tipos de tempo. Por exemplo LocalDate, uma data sem hora. Isso tem semântica diferente de uma comum, DateTimecom a parte do tempo definida como zero, pois DateTimeainda indica um momento específico (meia-noite em um fuso horário específico), enquanto LocalDateindica o dia inteiro e não está vinculado a um fuso horário específico. Isso também significa que você não pode traduzir diretamente um para o outro.

LocalDateé certamente mais simples do que DateTimeporque não precisa levar em consideração os fusos horários, mas você deve estar ciente dos outros problemas, por exemplo, que a data atual pode realmente retroceder quando você cruza um fuso horário e que o mesmo instante no tempo pode correspondem a datas diferentes em fusos horários diferentes. Se você estiver usando datas locais em aplicativos da Web ou em rede, tenha muito cuidado com esses problemas. Remover a parte do tempo de uma data não resolve o problema fundamental dos fusos horários! E se você considerar datas históricas e culturas diferentes, fica ainda mais complicado, pois a mesma data pode corresponder a instâncias totalmente diferentes no tempo, por exemplo, o calendário juliano versus o gregoriano.

Agora você pergunta por que os idiomas não têm algo parecido com o LocalDate incorporado . Bem, primeiro, algumas linguagens como SQL e Visual Basic têm um tipo de data sem parte do tempo. E o Java também adicionou um LocalDatena versão recente. Mas outras plataformas como .Net não. Somente os designers de linguagem podem realmente responder por que isso não está incluído na biblioteca padrão, mas meu palpite seria que "tempo instantâneo" é conceitualmente simples e universalmente útil, enquanto os outros conceitos de tempo são úteis apenas para domínios de aplicativos específicos (como calendários etc. .). Portanto, faz sentido permitir que o desenvolvedor do aplicativo escreva tipos personalizados para lidar com os casos de uso mais complexos ou que ele seja tratado por uma biblioteca de terceiros (como Joda-time).

JacquesB
fonte
5

Estou tão ridiculamente frustrado por ter que usar valores DateTime para conjuntos de dados que são realmente "apenas um dia". Os aniversários são o exemplo mais comum, mas isso aparece nos aplicativos de negócios o tempo todo.

Isso provavelmente ocorre porque o calendário é complicado e usado de tantas maneiras diferentes que ninguém conseguiu imaginar uma classe que seja simples, mas geral o suficiente para ser útil em muitos campos.

O tipo de data comumente encontrado nas linguagens de programação pode ser usado para datar com precisão as transações em um sistema de computador. Outros casos de uso provavelmente exigirão uma biblioteca customizada.

Aqui está uma pequena lista de fatos sobre calendários, demonstrando sua complexidade - a maioria deles é histórica; portanto, se você estiver restringindo sua atenção a datas após 1.1.1970, não será afetado por isso. No entanto, se seu aplicativo precisar trabalhar com datas anteriores ao final do século 19, esses fatos serão importantes. Os possíveis casos de uso são bancos de dados históricos de todos os tipos (livros, genealogia), mas também ativos de grandes empresas ou organizações ainda em atividade atualmente.

Todos esses fatos são citados nas excelentes perguntas frequentes encontradas na biblioteca de calendários do OCaml, escritas por Julien Signolles.

  1. O calendário juliano foi introduzido por Júlio César em 45 aC. Era de uso comum até os anos 1500, quando os países começaram a mudar para o calendário gregoriano (seção 2.2). No entanto, alguns países (por exemplo, Grécia e Rússia) o usaram nos anos 1900, e a igreja ortodoxa na Rússia ainda o usa, assim como algumas outras igrejas ortodoxas.

  2. A mudança do calendário juliano para o gregoriano não ocorreu de maneira uniforme e, dependendo do ano da mudança, 10 a 13 dias foram descartados. Por exemplo, na França, 9 de dezembro de 1582 foi seguido por 20 de dezembro de 1582 e na Grécia, 9 de março de 1924, seguido por 23 de março de 1924.

  3. Mesmo na era moderna, muitos calendários diferentes são usados ​​(gregoriano, ortodoxo, islâmico e chinês) para citar alguns, que usam maneiras diferentes de calcular anos e aniversários ou as celebrações religiosas da data.

Agora você espera um tipo de data que inclua operações úteis para operações comerciais gerais. Acho que não existem operações gerais de negócios. Por exemplo, no mundo das finanças, precisamos calcular:

  1. As frações do ano (como "6 meses" correspondem a "0,5"), que são usadas em conjunto com uma taxa de juros para calcular os juros reais de um empréstimo por um determinado período. Existem 6 a 10 receitas para calcular essas frações, cada uma diferente na maneira como lidam com a duração de um ano bissexto, a posição do período em relação ao último dia de fevereiro e a duração de um mês.

  2. No lançamento da data, ao calcular aniversários, usamos um calendário comercial e uma regra (escolhida entre um conjunto de mais de 6 regras diferentes) para mudar um aniversário de um feriado para um dia útil.

Para as pessoas que trabalham no setor financeiro, qualquer tipo de calendário que não implemente todas essas funções e regras é inútil. É provável que muitos outros setores tenham outros tipos de hábitos e convenções que exigem cálculos personalizados no calendário.

Existe valor em um aplicativo explicitamente destinado a ser um aplicativo de agendamento na definição de uma classe Date ou é "definir todos os horários ao meio-dia" a melhor abordagem? Quais problemas podem ocorrer com o uso do DateTime e com a configuração do componente Hora como Meio-dia? A mudança de fuso horário pode ser considerada nessa abordagem? Eu usei o MomentJS, mas acho que essa é apenas uma classe Date melhor.

Se você precisar acompanhar um único dia do calendário, a melhor maneira é provavelmente usar um número inteiro grande representando o dia juliano desse dia. Os algoritmos para conversão do dia juliano para o dia civil - descritos com ano, mês e calendário - são amplamente conhecidos e exaustivamente testados, para que você possa implementá-los facilmente em seu aplicativo - e descubra qual regra é pertinente em seu dia. caso para calcular o aniversário de um evento ocorrido em 29 de fevereiro.

Michael Le Barbier Grünewald
fonte
2

Acho que Mike Nakis, em sua resposta acima, faz um trabalho melhor do que eu ao explicar como o tempo em geral é uma coordenada absoluta medida e qualquer outra comunicação, suposto estado ou persistência dessa coordenada de tempo é apenas uma representação abstraída da referida coordenada de tempo.

Você fala com essas representações ao se referir ao Dia da Semana como apenas algum tipo de módulo de representação de um momento real. Na realidade, é um pouco mais complicado que isso. Se você foi encarregado de escrever uma função que retornará o dia da semana por um determinado momento, considere as seguintes informações que você precisará como entrada para esse algoritmo. Você precisará do ponto no tempo, do calendário e do fuso horário (lembre-se de que os fusos horários mudam TODO O TEMPO, portanto, você precisa saber quando esse fuso horário efetivo começou e quando terminou em coordenadas de horário específicas. por exemplo!) e, se o horário de verão estiver em vigor, isso também mudará com o tempo. Agora considere se você recebeu um DateTime no fuso horário local,

Você pode ver como essa pergunta aparentemente simples pode ser realmente complicada.

Eu sei a dor que você está sentindo no seu lugar, corrigindo todos os erros em um aplicativo de agendamento de visitas para um produto que foi escrito por desenvolvedores inexperientes. A coisa toda teve que ser descartada.

O tempo é realmente uma coordenada, mas além de uma mera Data, considere outros dados confidenciais que podem ser necessários, como:

Duração: um intervalo de milissegundos que pode ocorrer que significa um período ou passagem de tempo sem coordenadas de tempo específicas especificadas. Um caso de uso pode ser,

Como usuário, eu gostaria que essa tarefa fosse executada 15 segundos após a conclusão do trabalho da meia-noite, todas as quartas-feiras.

Intervalo: um intervalo de tempo entre duas coordenadas de tempo específicas. Um caso de uso em que você pode considerar um intervalo.

Como usuário, preciso ver todos os dias do mês totalmente contidos em um intervalo de tempo especificado.

Outro ponto rápido que eu queria destacar é que você fez um comentário sobre os números de ponto flutuante para dados com base no tempo e eu aconselho isso. A aritmética de ponto flutuante inevitavelmente leva a erros de arredondamento que podem não fornecer uma medida tão precisa quanto o tempo necessário.

Portanto, em conclusão, todas essas informações inevitavelmente levam às seguintes considerações de design:

  • Pontos ou intervalos específicos no tempo devem ser mantidos no UTC ou em algum tipo de dados que contenha informações suficientes para serem facilmente abstraídos de volta ao UTC, quando necessário
  • A lógica do aplicativo deve ser escrita para formatar o UTC ou um intervalo de coordenadas UTC em um estado de dados representacional que seja mais digerível para o usuário final.
  • Durações importantes devem ser persistidas em milissegundos
  • As preferências específicas do local ou do usuário final na exibição de qualquer dado referente ao tempo devem ser mantidas como dados adicionais e tratadas como uma opção de exibição. (Por exemplo, quiosque A, fuso horário central, formato de hora militar ou preferências do usuário B, hora padrão em Tel Aviv (GMT + 7:00) fuso horário, etc ...)
  • Evitar números FP
maple_shaft
fonte
11
Nada disso é "inevitável". Pode ser comum para muitas aplicações, mas o Large Hadron Collider lida com eventos na escala de nanossegundos. Os tempos do sistema foram movidos para microssegundos porque os milissegundos não têm precisão suficiente. Os aplicativos de calendário precisam ter um conceito de data que acontece em um dia local, independentemente de você estar ou não no mesmo fuso horário em que criou o evento.
Alan Shutko 14/09/15
11
@AlanShutko E sim, "dados adicionais" necessários são coisas como o fuso horário local e Dias, e quaisquer outros dados importantes que devem ser capturados. No entanto, essas são apenas abstrações para um único ponto no tempo, mesmo que o ponto no tempo não seja importante para o seu algoritmo. No que diz respeito à escala de nanossegundos e até microssegundos, minha resposta é mais voltada para o software da Web e do tipo LOB. Duvido que a linguagem de escolha do LHC seja C # ou Javascript.
maple_shaft
11
Milissegundos são ótimos para processos físicos repetíveis. Para atividades humanas, algumas vezes a unidade apropriada é de dias nominais, por exemplo, se enviada no final do dia, estará disponível para uso no destino três dias depois.
Kevin cline
No passado, considerei o uso de números de ponto flutuante de 64 bits para coordenadas de tempo e, mais importante, para períodos de tempo, porque eles permitem expressar pequenas quantidades com grande precisão e grandes quantidades, onde a perda de precisão não importa realmente . (E daí que os dinossauros morreram 65 milhões de anos atrás, mais ou menos alguns anos?) Então, por que você diz que eles devem ser evitados?
Mike Nakis
Mike, acho que a preocupação dele é com a matemática FP inevitavelmente arredondando, pois está convertendo de valores decimais para binários. Por exemplo, 0,3 é um decimal de repetição quando expresso como um número FP binário e, portanto, não pode ser representado exatamente. Não é que você esteja perdendo a capacidade, mas a precisão.
Michael Blackburn
2

Em resumo, porque a maioria dos tipos de horário baseados em computador está focada em lidar com o problema de fuso horário e horário corretamente.

Existem 2 casos extremos que não são bem atendidos pela abordagem usual. Definir um horário no outro lado de uma alteração do horário de verão usando a hora local, que depois é convertida no UTC por uma camada de abstração mais baixa e, em seguida, leva 1 hora mais cedo / mais tarde para a sua reunião.

O outro é (conforme a pergunta) modelando informações de datas arbitrárias, como registrar a data de nascimento de uma pessoa. Imagine o caso em que duas pessoas nascem ao mesmo tempo, uma na Nova Zelândia e outra no Havaí. A probabilidade é que eles tenham datas de nascimento diferentes em seus passaportes e, se a pessoa nascida no Havaí se mudar para a Nova Zelândia, ela será considerada um dia mais antiga que a pessoa nascida na Nova Zelândia, apesar de ter vivido exatamente no mesmo período.

A sugestão na pergunta de definir a data para o horário do meio-dia, o UTC funcionará, QUASE em todos os lugares. As compensações do UTC variam de -12 a +14; portanto, há alguns lugares no Pacífico em que essa abordagem falhará. Costumo tratar esses tipos de dados como seqüências de caracteres, em um formato aaaammdd, e se eu tiver que fazer cálculos de comparação entre duas datas, isso pode ser feito com segurança como uma comparação de cadeias. Ao fazer comparações delta (por exemplo, entre data e agora ou quanto tempo até atingirem a idade X), você precisa garantir que todas as datas sejam criadas no mesmo deslocamento UTC e, em seguida, pode usar as funções de hora padrão para realizar o trabalho.

Michael Shaw
fonte
3
" Eu costumo tratar esses tipos de dados como strings, no formato aaaammdd, e se eu tiver que fazer cálculos de comparação entre duas datas, isso pode ser feito com segurança como uma comparação de strings. " Isso com certeza soa como um Datetipo de dados, apenas aString
Ross Patterson
Assim como você diz, é uma representação em cadeia de uma data e, diferentemente do pôster original, a data não é alterada estando no fuso horário UTC + 13.
Michael Shaw
2

Por que não existe um verdadeiro tipo de dados "Somente data"?

Pelas mesmas razões, penso eu, que os valores DateTime são geralmente especificados no UTC: simplicidade e confiabilidade . O ponto de um valor DateTime é especificar um único ponto no tempo que não seja afetado pelo fuso horário, horário de verão, calendário e outros ajustes locais. Os valores DateTime especificam um instante (até o limite da resolução do tipo), não um período ou um conjunto de horários. Essas limitações tornam possível comparar valores DateTime de maneira confiável, previsível e descomplicada.

Tentar especificar uma data com um valor DateTime é como tentar usar um ponto para especificar uma área.Você pode fazer esse trabalho usando uma convenção, como "este ponto representa o centro de um círculo com um raio de 100 m", mas existem muitos problemas: todo mundo precisa usar a mesma convenção, é preciso escrever um monte de código de suporte para tornar o trabalho com o tipo errado menos doloroso, e é praticamente garantido que em algum momento você precisará especificar uma área maior ou menor que a área convencional. O mesmo ocorre com as datas: você pode usar 'meio-dia' como horário convencional para especificar datas, mas depois entra nos fusos horários porque as pessoas esperam especificar datas no horário local, em vez do UTC. E mesmo que você encontre uma maneira satisfatória de usar um DateTime para especificar uma data, precisará de mais informações para saber se é uma data absoluta ou relativa: é 4 de julho, 1776 ou todo 4 de julho? E se você quiser repetir usando outro período? E os calendários têm todos os tipos de problemas malucos: alguns meses são mais longos que outros, alguns anos são mais longos que outros, alguns dias são mais longos que outros e alguns calendários têm lacunas neles. Você não gostaria de resolver esses problemas apenas por dias inteiros, porque os mesmos problemas surgem por períodos mais curtos: você provavelmente gostaria de escrever um código que expressa "tome 1 comprimido a cada 4 horas" tão prontamente quanto "o grupo se reúne a cada terceira sexta-feira ".

Portanto, há muitas complicações envolvidas no trabalho com datas. É relativamente (sem trocadilhos) fácil fornecer um tipo que especifique um ponto no tempo e trabalhe com ele como faria com um número, mas extremamente difícil fornecer um tipo que aborde todas as maneiras pelas quais as datas são usadas.

Como outros apontaram, não são linguagens e bibliotecas que fornecem um bom suporte para datas, e muitas vezes é uma boa idéia para usá-los dado que é muito difícil conseguir o código da data relacionada exatamente correto.

Caleb
fonte
2
"Difícil fornecer um tipo que aborde todas as maneiras pelas quais as datas são usadas." É verdade que é por isso que é uma ideia horrível tentar fornecer um único tipo para fazer tudo. Os primeiros lançamentos Java forneceram apenas java.util.Date e o resultado foi horrível. Em seguida, eles adicionaram uma hierarquia complexa java.util.Calendar e não ficou muito melhor.
Kevin cline #
11
@kevincline Concordo plenamente. O OP não especificou um idioma, então eu estava buscando uma generalidade.
Caleb
" Pelas mesmas razões, eu acho, que os valores DateTime são geralmente especificados no UTC " ... Oh, isso seria verdade. É 2015 e ainda há muito código sendo escrito usando o fuso horário do autor :-(
Ross Patterson
11
Eu estava realmente me perguntando por que não existe uma convenção geralmente aceita em torno de datas. Seu "usar um ponto para representar uma área" resume perfeitamente minha frustração.
Michael Blackburn
2

Por que não existe um verdadeiro tipo de dados "Somente data"?

Existem muitos tipos em várias bibliotecas para vários idiomas. Certamente existe um para o seu idioma atual. O pacote utilitário Java tinha uma API horrível para cálculos de tempo, mas a introdução do pacote java.time tornou a vida muito melhor. Consulte java.time.LocalDate, contendo um valor ano-mês-dia, ou java.time.MonthDay, contendo apenas um número de mês e dia.

Kevin Cline
fonte
1

A manipulação de calendário é um dos aspectos menos compreendidos da computação. Livros inteiros foram escritos sobre o assunto. O @MichealBlackburn está absolutamente certo ao solicitar um tipo de dados somente para data, que não seja resolvido até um ponto da linha do tempo, sujeito a reinterpretação. Historicamente, houve disputas legítimas sobre o significado de uma data. Não é preciso procurar além da adoção do calendário gregoriano para descobrir quão complexo ele pode se tornar. Além disso, os anos nem sempre começaram em 1º de janeiro, mesmo na Europa Ocidental e suas colônias ( por exemplo , a Grã-Bretanha e a América Britânica começaram o ano em 25 de março).

Ross Patterson
fonte
11
Isto está certo. O calendário FAQ cito na minha resposta é um excelente recurso para descobrir as complexidades e subtletie4s de manipulações clandar
Michael Le Barbier Grünewald
-2

Em resposta a:

Bem, eu sinceramente gostaria de saber por que quase todos os idiomas têm apenas um tipo de dados para isso.

O motivo mais comum pode ser "porque não é necessário". Se você deseja um horário que não se importe com horas, minutos, segundos, etc., basta inicializá-lo assim:

date = new DateTime(year, month, day, 0, 0, 0);

Se você quiser, pode estender o DateTime:

public class Date extends DateTime {
    ...
    public Date(int year, int month, int day) {
        this(year, month, day, 0, 0, 0);
    }
}

Nota: ignoro intencionalmente a hora e o fuso horário padrão. Realmente não importa o que você definiu, desde que sejam iguais para todos os Dates. Você pode defender o UTC. Você pode usar o fuso horário em que seu servidor se encontra - de qualquer forma, não acho que seja importante representar um valor impreciso Date. O mesmo com o tempo padrão - você pode fazer 0, meio dia. Não importa. Se o Facebook me enviar uma notificação de aniversário às 00:01, mas eu nasci às 23:59, eu realmente não me importo, e não ficarei ofendido por terem mais de 12 horas de folga.

O acima está em Java, mas funcionaria de maneira semelhante em qualquer linguagem com a DateTimee herança. O Java, na verdade, tem várias maneiras de resolver isso, e o acima foi descontinuado (eles querem que você use Calendaragora). Mas como outros postou comentários, algumas línguas realmente não fornecer uma Dateclasse, presumivelmente, exatamente por esse motivo.

DateProvavelmente , toda implementação é provavelmente apenas um invólucro para a linguagem DateTimee zera o tempo. Caso contrário, você precisaria de um código duplicado para resolver problemas como o número de dias entre duas datas / datas e horários ou se dois Dates são iguais (e 29 de fevereiro e 1 de março?). Geralmente, esse tipo de coisa é resolvido na DateTimeclasse. Faz sentido reutilizar o mesmo código para a Date.

Shaz
fonte
4
-1: use LocalDate se desejar apenas ano + mês + dia. O uso do DateTime para esse fim causará bugs quando outro programador vê o DateTime e assume que ele representa um momento no tempo.
Kevin cline
@kevincline Eu não senti que isso fosse necessário, porque esta pergunta é independente da linguagem. Também acho óbvio que o uso do código rotulado como "Descontinuado" é um cenário de uso por seu próprio risco. Mais importante, eu usei isso apenas como exemplo de algo que você pode fazer em um cenário em que um idioma não possui uma classe LocalDate, ou Datedigita, e você precisa 'fazer o seu próprio'.
Shaz
11
Mas "é necessário" um código claro e conciso e correto que envolva regras de negócios sobre o tempo (em oposição ao tempo físico). se a biblioteca não fornecer tipos para o tempo nominal, será necessário que o programador os invente e a maneira de fazer isso não começará com "DateTime".
Kevin cline
@kevincline Não vejo como o código seria menos claro ou conciso. Qual é a diferença do ponto de vista de um programador entre new Date(2000, 1, 1);e new Date(2000, 1, 1);? Você pode dizer qual deles tem horas, minutos e segundos vazios abaixo? Se você estiver preocupado com a exibição de funções extras (como setMinutes ()), poderá seguir o caminho de ter Datewrap em DateTimevez de herdá-lo e só expor setYear, setMonth, setDay, etc. E certamente não é menos correto que o DateTime da biblioteca que você está usando.
Shaz
Meu background é basicamente C #, que não tem uma construção análoga ao LocalDate. Aparentemente, nós apenas datamos o DateTime.
Michael Blackburn