Pergunta

Alguém poderia aconselhar o atual "melhores práticas" em torno tipos Date e Calendar.

Ao escrever novo código, é melhor a favorecer sempre Calendar sobre Date, ou existem circunstâncias em que Date é o tipo de dados mais apropriado?

Foi útil?

Solução

Data é uma classe simples e é principalmente lá por razões de compatibilidade com versões anteriores. Se você precisa definir datas específicas ou fazer data aritmética, use um calendário. Calendários também lidar com localização. As funções de manipulação de data anteriores do Data desde então foi substituído.

Pessoalmente, eu tendem a usar tanto tempo em milissegundos como um longo (ou longa, conforme o caso) ou o Calendário quando há uma escolha.

Tanto a data eo calendário são mutáveis, que tende a questões presentes ao usar em uma API.

Outras dicas

A melhor maneira para novo código (se a sua política permite que o código de terceiros) é usar a Joda Tempo .

Ambos, Data Calendário , tem tantos problemas de design que nem são boas soluções para o novo código.

  • Date e Calendar são realmente o mesmo conceito fundamental (ambos representam um instante no tempo e são invólucros em torno de um valor long subjacente).

  • Pode-se argumentar que Calendar é realmente ainda mais quebrado do que Date é, como parece fatos concretos oferecer cerca de coisas como o dia da semana ea hora do dia, enquanto que se você mudança sua propriedade timeZone, o concreto se transforma em manjar branco! Nem objetos são realmente úteis como uma loja de ano-mês-dia ou tempo do dia por este motivo.

  • Use Calendar apenas como uma calculadora que, quando dado Date e TimeZone objetos, fará os cálculos para você. Evitar o seu uso para digitação propriedade em um aplicativo.

  • Use SimpleDateFormat juntamente com TimeZone e Date para gerar exibição Strings.

  • Se você está se sentindo uso aventureiro Joda-Time, embora seja desnecessariamente complicado IMHO e está prestes a ser substituído pelo JSR-310 Data API, em qualquer caso.

  • Eu respondi antes que não é difícil de rolar sua própria classe YearMonthDay, que usa Calendar sob o capô para cálculos de data. Eu estava downvoted pela sugestão, mas eu ainda acredito que é um válido porque Joda-Time ( e JSR-310 ) são realmente tão mais complicada para a maioria dos casos de uso.

Data é melhor para armazenar um objeto de data. É o persistiu, aquele serializado ...

Calendário é melhor para manipular datas.

Nota: nós também favorecem às vezes java.lang.Long sobre data, porque a data é mutável e, portanto, não thread-safe. Em um objeto Date, use setTime () e getTime () para alternar entre os dois. Por exemplo, uma constante data na aplicação (exemplos: o 1970/01/01 zero, ou um END_OF_TIME aplicativo que você defina a 2099/12/31, aqueles são muito úteis para substituir valores nulos como hora de início e de término, especialmente quando você persistir los no banco de dados, como SQL é tão peculiar com nulos).

Eu geralmente uso Data, se possível. Embora seja mutável, os mutantes são realmente obsoleto. No final, basicamente, envolve um longo que representaria a data / hora. Por outro lado, gostaria de usar Calendários se eu tiver que manipular os valores.

Você pode pensar nisso desta maneira: você só pode usar StringBuffer somente quando você precisa ter cordas que você pode facilmente manipular e, em seguida, convertê-los em seqüências usando o método toString (). Da mesma forma, eu só uso Calendar se eu precisar manipular dados temporal.

Para as melhores práticas, que tendem a usar objetos imutáveis, tanto quanto possível fora do modelo de domínio . Ele reduz significativamente as chances de quaisquer efeitos secundários e é feito para você pelo compilador, ao invés de um teste JUnit. Você usa esta técnica, criando privado finais campos em sua classe.

E voltando à analogia StringBuffer. Aqui está um código que mostra como converter entre Calendário e Data

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);

Dates devem ser utilizados como pontos imutáveis ??no tempo; Calendars são mutáveis, e pode ser passado ao redor e modificado se você precisar de colaborar com outras classes de avançar com uma data final. Considerá-los análogo ao String e StringBuilder e você vai entender como eu considero que deve ser utilizado.

(E sim, eu sei A data não é realmente tecnicamente imutável, mas a intenção é que ele não deve ser mutável, e se nada chama os métodos obsoletos, então é assim.)

tl; dr

aconselhar o atual "melhores práticas" em torno Date e Calendar

é melhor para favorecer sempre Calendar sobre Date

Evite essas classes legadas completamente. Use java.time aulas vez .

Detalhes

A resposta por Ortomala Lokni é direito de sugerir utilizando o moderno java.time aulas em vez dos legados de idade aulas de data e hora problemáticos (Date, Calendar, etc). Mas essa resposta sugere a classe errada como equivalente (ver o meu comentário sobre isso Resposta).

Usando java.time

As classes java.time são um vasta melhoria sobre os legados aulas de data e hora, diferença noite e dia. As classes de idade são mal-concebido, confuso e problemático. Você deve evitar as velhas classes sempre que possível. Mas quando você precisa converter de / para o velho / novo, você pode fazê-lo chamando novos métodos adicionar aos velhos classes.

Para mais informações sobre conversão, consulte minha resposta e bacana diagrama a outra pergunta, Converter java.util.Date para o ‘tipo java.time’

Como pesquisar Stack Overflow dá muitas centenas de exemplos de perguntas e respostas sobre o uso java.time. Mas aqui está uma sinopse rápida.

Instant

Obter o momento atual com uma Instant. A Instant classe representa um momento no cronograma em UTC com uma resolução de nanossegundos (até nove (9) dígitos de uma fração decimal).

Instant instant = Instant.now();

ZonedDateTime

Para ver esse mesmo momento simultânea através da lente de de alguma região específica parede-relógio , aplicar um fuso horário ( ZoneId ) para obter um ZonedDateTime .

Fuso horário

Especifique um tempo apropriado nome de zona no formato de continent/region, como America/Montreal , Africa/Casablanca , ou Pacific/Auckland. Nunca utilize o 3-4 letras, como EST ou IST como eles são não fusos horários verdadeiros, não padronizados, e nem mesmo únicos (!).

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();

Offset

Um fuso horário é a história de uma região de mudanças em sua deslocamento de-UTC . Mas às vezes você são dadas apenas um deslocamento sem a zona cheia. Nesse caso, use a classe OffsetDateTime.

ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );

O uso de um fuso horário é preferível a utilização de um mero deslocamento.

LocalDateTime

O “local” nos meios aulas Local… qualquer localidade, não uma determinada localidade. Assim, o nome pode ser contra-intuitivo.

LocalDateTime, LocalDate e LocalTime falta propositadamente qualquer informação sobre a zona de deslocamento ou tempo. Então eles fazem não representam momentos reais, eles são não pontos na linha do tempo. Em caso de dúvida ou confusão, uso ZonedDateTime em vez de LocalDateTime. Pesquisar Stack Overflow para muito mais discussão.

Cordas

Do Não fundir data-tempo objetos com cordas que representam o seu valor. Você pode analisar uma seqüência para obter um objeto de data e hora, e você pode gerar uma seqüência de um objeto de data e hora. Mas a corda não é a própria data-hora.

Saiba mais sobre ISO 8601 formatos padrão, usados ??por padrão nas classes java.time.


Sobre java.time

O java.time framework é construído em Java 8 e posterior. Essas classes suplantar o problemático idade legados aulas de data e hora, como java.util.Date , Calendar , e SimpleDateFormat .

O Joda-Time projeto , agora em < a href = "https://en.wikipedia.org/wiki/Maintenance_mode" rel = "nofollow noreferrer"> modo de manutenção , aconselha migração para o java.time classes.

Para saber mais, consulte a A Oracle Tutorial . E busca Stack Overflow para muitos exemplos e explicações. Especificação é JSR 310 .

Usando um driver JDBC compatível com JDBC 4.2 ou mais tarde, você pode trocar java.time objetos diretamente com seu banco de dados. Não há necessidade de cordas nem java.sql. * Classes.

Onde obter as classes java.time?

O ThreeTen-Extra projeto estende java.time com aulas adicionais. Este projeto é um campo de provas para possíveis adições futuras para java.time. Você pode encontrar algumas classes úteis aqui, como Interval , YearWeek , YearQuarter , e mais .

Com Java 8, a nova java .time empacotar deve ser usado.

Objetos são imutáveis, fusos horários e dias de economia de luz são tidos em conta.

Você pode criar um ZonedDateTime objeto de um velho java.util.Date objeto como este :

    Date date = new Date();
    ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());

Eu sempre defendo Joda-time . Aqui está o porquê.

  1. a API é consistente e intuitiva. Ao contrário do APIs java.util.Date/Calendar
  2. não sofrem de problemas de segmentação, ao contrário de java.text.SimpleDateFormat etc. (eu vi inúmeros problemas do cliente relacionados com a não percebendo que a data / hora padrão formatação não é thread-safe)
  3. que é a base das novas APIs de data / hora Java ( JSR310 , prevista para Java 8. Então você estará usando APIs que se tornarão centrais APIs Java.

EDIT: A data / aulas em tempo Java introduzidas com Java 8 estão agora a solução preferida, se você pode migrar para Java 8

Um pouco tarde na festa, mas Java tem uma nova API Data Hora no JDK 8. Você pode querer atualizar sua versão JDK e abraçar o padrão. Não mais confuso data / calendário, frascos não mais 3rd party.

A data deve ser desenvolvido-re. Em vez de ser um longo interger, deve segurar ano, mês, dia, hora, minuto, segundo, como campos separados. Pode ser até bom para armazenar a zona de calendário e tempo esta data está associado.

Em nossa conversa natural, se configurar uma nomeação em 1 de novembro de 2013 13:00 NY Time, este é um DateTime. Não é um calendário. Assim, devemos ser capazes de conversar como esta em Java também.

Quando Data é armazenado como um inteiro longo (de segundos mili desde 01 de janeiro de 1970 ou algo assim), calculando a sua data atual depende do calendário. Diferentes calendários dará data diferente. Esta é a partir do potencial de dar um tempo absoluto (por exemplo, 1 segundo após triliões big bang). Mas muitas vezes nós também precisamos de uma maneira conveniente de conversa, como um objeto encapsulando ano, mês etc.

Gostaria de saber se há novos avanços em Java para reconciliar esses 2 objetivos. Talvez meu conhecimento java é muito antiga.

Btw "data" é geralmente marcado como "/ obsoleto obsoleto" (eu não sei exatamente por isso) - algo sobre isso está escrito lá Java: Por que o construtor Data obsoleta, e o que eu uso em vez disso?

Parece que é um problema do construtor só- maneira via new Date (int ano, mês int, dia int) , maneira recomendada é através de calendário e conjunto params separadamente .. ( Calendário cal = Calendar.getInstance (); )

Eu uso o calendário quando eu preciso de algumas operações específicas sobre as datas como mover-se no tempo, mas Data acho que é útil quando você precisa formatar a data para se adaptar às suas necessidades, recentemente descobri que Locale tem um monte de operações úteis e methods.So estou usando Locale agora!

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