Em um aplicativo Web típico, as datas são recuperadas da camada do banco de dados fortemente tipada (por exemplo, em c # como System.DateTime em vez de System.String).
Quando uma data precisa ser expressa como uma sequência (por exemplo, exibida em uma página), a conversão de DateTime em sequência é feita na camada de apresentação.
Por que é isso? Por que é ruim converter o DateTime em uma string na camada de banco de dados?
Veja também o debate acalorado no bate-papo e a pergunta original que começou tudo isso .
database
sql
formatting
John Wu
fonte
fonte
Respostas:
Datas, DateTimes e realmente qualquer outro objeto digitado geralmente devem ser deixados em seu formato digitado corretamente até o momento em que você precisar que eles sejam transformados em algum outro tipo - especialmente quando esse tipo for uma forma legível por humanos e, especialmente, quando houver perda / tipo de conversão unidirecional.
Por quê? Como se supõe que o tipo fornece muitas funcionalidades práticas úteis, como teste de igualdade adequado, adição e subtração, comparação (maior que, menor que), funcionalidade de fuso horário e local (especialmente importante para qualquer coisa relacionada ao tempo), etc. Se você decidir apoiar os americanos e o formato "Mês dia [º], ano", bem como o estilo britânico comum de "Dia mês ano" ou o padrão ISO de "Ano-mês-dia"? O que você faria se fosse uma string e precisasse fazer essa alteração, analisá-la novamente em uma Data? Ugh, não, obrigado - existem muitos males e erros covardes dessa maneira, que devem ser totalmente evitados.
Mais especificamente, você mencionou a arquitetura em camadas, que possui a camada de apresentação separada dos dados posteriormente. Este é realmente o outro grande motivo para passar uma Data como uma Data e não uma sequência - porque em que tipo de formatação de sequência a data deve ser inserida? Inglês, chinês, com ou sem segundos / milissegundos, nome completo do mês ou dígitos, você deseja classificar o campo de data posteriormente (a classificação de uma sequência exige um determinado formato de sequência, se você deseja que ela funcione corretamente), etc? Tudo isso é uma questão de apresentação - como o usuário deve visualizar os dados - e colocar essa lógica em qualquer outro lugar limitaria a vantagem de ter uma arquitetura hierárquica em primeiro lugar. O banco de dados não precisa saber ou se importar com como você deseja visualizar a data no futuro.
Finalmente, quase todas as aplicações complexas (que são para que servem as arquiteturas em camadas) que se preocupam com o tempo usarão inevitavelmente horários / datas de muitas e muitas maneiras diferentes, e geralmente em todos os níveis diferentes da arquitetura. Os objetos digitados relacionados a horários e datas existem por um motivo muito bom: o próprio tempo e, especialmente, os sistemas de calendário humano, são estranhos e difíceis. Por fim, horários e datas não são cadeias de caracteres pelo mesmo motivo que números inteiros e pontos flutuantes não são cadeias de caracteres, e isso só tornará sua vida mais difícil se você tentar fingir que são realmente apenas matrizes de caracteres, porque simplesmente não são.
fonte
Why? Because it is assumed that the type provides you with lots of handy built in functionality
Na minha opinião, isso é apenas secundário. A verdadeira razão é que o tipo diz o que é algo . Uma data não é uma sequência, apenas se traduz facilmente em uma sequência legível por humanos.Eu quero saber o tipo.
Realmente não me importo se o seu banco de dados armazena informações em uma string, alguns ints ou bytes, porque, no final, sempre são bytes de qualquer maneira. Essa string ocupando mais espaço do que o necessário em seu banco de dados não me incomoda. O que me incomoda é encontrar datas como esta:
10/11/2016
E sem saber se é o décimo primeiro mês ou o décimo mês.
Mas é validado, você diz. Claro que você passa por um processo de validação. A data está perfeitamente correta. Mas aqui estou mantendo essa coisa e tudo que sei é que a data é uma sequência. Eu nem posso te dizer que data é essa.
"Décimo dia de novembro no ano de dois mil e dezesseis anos de nosso senhor."
Isso é uma corda. Uma de nossas apresentações precisa desse formato. Você disse que o banco de dados converte todas as datas em strings, certo? Divirta-se com isso.
O trabalho do banco de dados é armazenar dados que não estão presentes. Claro, você pode fazer isso em strings, mas depois precisa analisá-lo para torná-lo útil para apresentar em outros formatos. Armazená-lo em um formulário analisado padrão para qualquer tipo que o DB ofereça nos coloca o mais perto possível de apresentar o que podemos estar sem ter tomado uma decisão de apresentação. Realmente não importa para mim se o banco de dados faz o backup desse tipo com uma string ou ints ou bytes. Contanto que ele saiba o que está fazendo.
Mas quando você não avisa o banco de dados, estamos lidando com uma data e armazenamos uma data como uma string, você está apresentando prematuramente e favorecendo uma apresentação sobre todas as outras. Isso força todos os outros apresentadores a analisar antes da conversão. Não, o banco de dados não faz parte da camada de apresentação. Não peça para ser.
Da mesma forma, a camada de apresentação não faz parte do banco de dados, portanto, não é aconselhável associar um relatório aos detalhes do banco de dados. É muito mais robusto agir sobre os tipos.
fonte
Localidade
A conversão de data em string para fins de apresentação requer conhecer as preferências do usuário, pois a mesma data exata geralmente deve ser exibida de maneira diferente para usuários em diferentes localidades. Mesmo se você usar um único código de idioma em seu aplicativo, o comportamento adequado deverá usar o código de idioma do aplicativo em vez do servidor de banco de dados; e não é garantido que eles sejam idênticos, mesmo que nesse momento coincidam coincidentemente.
A conversão de um tipo de dados de data universal para uma sequência específica de código de idioma deve ocorrer na camada de apresentação, porque é a camada que sabe como essa conversão deve ser realizada.
fonte
Isso é indesejável pelo mesmo motivo que você não deseja converter cegamente qualquer tipo em uma string assim que atinge a camada do aplicativo. Existe uma grande probabilidade de você querer usar esse objeto de alguma maneira antes de apresentá-lo ao usuário (se você o apresentar ao usuário). Para este exemplo específico, imagine que você precisava fazer algumas contas matemáticas no objeto. Não há desvantagem em converter o objeto em uma string precisamente antes de exibi-lo.
fonte
Os tipos existem por uma razão: se eles não adicionassem nenhum benefício, não os teríamos e não os usaríamos; teríamos apenas "o tipo" e tudo seria isso. Eles não são apenas convenientes, mas também agregam segurança e eficiência. A seguir, é apresentada uma lista de por que você deve sempre persistir tipos no formato nativo e não como seqüências de caracteres . Usei
DateTime
como exemplo a maior parte do tempo, mas os mesmos princípios se aplicam a qualquer tipo primitivo, como números inteiros, decimais, binários etc.Banco de dados
Restrições
Restrição de tipo
Quase todos os armazenamentos de dados permitem especificar restrições nos dados, isso inclui restrições de tipo. Um dos principais benefícios da especificação de uma
DateTime
instância é que os dados armazenados serão restritos a esse tipo. Nunca será possível inserir nada além de uma data e hora, independentemente de como os dados foram inseridos no armazenamento. O último é importante para sistemas maiores, onde existem vários processos que interagem diretamente com a loja. Isso também inclui a tentativa de adicionar datas defeituosas como 30 de fevereiro (de qualquer ano), pois fevereiro pode ter apenas 29 dias em um ano bissexto e 28 dias em anos não bissextos.Restrições de validação
Também há restrições de validação que podem ser implementadas no Data Store, como garantir que uma data inserida não exceda a data atual ou que uma data de início ocorra antes de uma data de término.
Operações
A maioria das lojas de dados também têm construído em operações / funções como
DateAdd
ouDatePart
no MS SQL Server. Isso permite que você comece a filtrar ou selecionar dados específicos enquanto os dados ainda estão na loja (ainda não recuperados para o aplicativo).Formato universalmente aceito
Ao usar o tipo nativo, outros desenvolvedores ou sistemas que também interagem com a loja não precisam ser informados nos mínimos detalhes de como esse tipo primitivo é armazenado. Não é esse o caso se esse tipo foi armazenado como uma sequência, então você deve garantir que todos entendam o formato dessa
DateTime
representação de sequência. Esse sistema se torna frágil ao lidar com dados que abrangem localidades, regiões e culturas na origem dos dados, o local físico de um aplicativo e os atributos do usuário / sistema final que está interagindo com esses dados. Exemplo: o formato da data em um país pode ser MM / dd / aaaa (como nos EUA), mas em outro pode ser dd / MM / aaaa, detectar essa diferença se torna quase impossível.Rapidez
Velocidade de recuperação, velocidade de validação, velocidade de operações e eficiência de armazenamento também são fatores importantes. Exemplo da velocidade de recuperação: os armazenamentos de dados permitem índices em colunas e esses índices geralmente podem ser usados com mais eficiência se o tipo for armazenado em seu formato nativo.
Aplicação
Data de acesso
A execução de consultas na loja se torna mais simples usando o sistema de tipo nativo, pois os desenvolvedores, mais uma vez, não precisam adivinhar o formato de armazenamento. Quase todos os provedores de aplicativos de armazenamento de dados ( exemplo: ado.net ) fornecem mecanismos para criar as consultas parametrizadas adequadas com base nos tipos nativos transmitidos. Veja um exemplo de adição da parte Data a uma consulta ado.net em um armazenamento do Sql Server, fazer o mesmo com strings seria muito complicado e frágil / propenso a erros.
Operações
Os tipos nativos no código também fornecem operações padrão como o tipo .net
System.Date
. As operações são geralmente de natureza matemática, como adicionar datas, encontrar a diferença entre datas, etc. Novamente, isso não é possível com facilidade nos tipos de string.Camada de apresentação
Localidade
Quando um tipo primitivo é finalmente convertido em uma sequência na camada de apresentação ( o local correto na pilha do programa), o programador agora tem várias opções para exibi-lo corretamente de acordo com o contexto em que é apresentado. Esse contexto geralmente consiste no significado real dos dados e na localidade do usuário.
Exemplo 1Uma instância de data e hora pode ser formatada automaticamente com base no código do idioma do usuário.
Exemplo 2Uma instância decimal pode estar representando um valor (moeda) e o código do idioma do usuário também deve exibir o valor de acordo com sua preferência. Um aplicativo c # pode então exibir o valor usando
Isso pode ser crítico, pois culturas diferentes exibem números de maneira diferente. No período dos EUA (.) E vírgula (,) têm o significado reverso exato, como na Holanda.
Localização
Isso é muito específico para
DateTime
instâncias. Uma data e hora representam uma ocorrência em um momento específico, mas isso geralmente deve ser transmitido / apresentado ao usuário, dependendo de seu próprio fuso horário. Exemplo: umaDateTime
instância2016-09-21T23:38:21.399Z
pode ser exibida como9/21/2016 5:21 PM
para um usuário no fuso horário oriental nos EUA. Existem várias maneiras de fazer isso, mas torna-se quase impossível se a instância de data e hora for mantida na memória como um tipo de sequência ou no armazenamento de dados como um tipo de sequência.Regra geral
As 2 regras gerais para um aplicativo seguem quando se trata de converter qualquer tipo primitivo em uma representação de cadeia de caracteres.
fonte
Não há realmente nada de errado em fazer isso (é feito o tempo todo nos serviços), desde que você esteja usando um formato não ambíguo para a sua data. Por inequívoca, quero dizer que não apenas a data está clara (por exemplo, MM / DD vs. DD / MM), mas também em que fuso horário está. Então, com antecedência, se você vai representar suas datas como texto, use um formato ISO . Eu prefiro as cadeias de tempo baseadas em UTC.
Prós:
Contras:
Se alguém dissesse que queria fazer isso, eu perguntaria "por quê?" porque não há muito sentido nisso. Se o motivo pelo qual alguém deseja retornar a data como uma String é porque eles apenas a exibem diretamente, esse não é um bom motivo para usar Strings no banco de dados.
fonte