Habēmus Java 8 Finalmente Java sabe trabalhar com datas e horários
Por que uma nova API? public boolean isMesNatal(Calendar calendar){ return calendar.get(Calendar.MONTH) == 11; }
public boolean isMesNatal(Calendar calendar){ return calendar.get(Calendar.MONTH) == 11; } Por que uma nova API? Dezembro == 11
Por que uma nova API? Calendar dataNascimento = Calendar.getInstance(); dataNascimento.set(1983, Calendar.NOVEMBER, 15); Pessoa pessoa = new Pessoa(dataNascimento); //Afirmação válida assert pessoa.getDataNascimento() .get(Calendar.DAY_OF_MONTH) == 15;
Por que uma nova API? Calendar dataNascimento = Calendar.getInstance(); dataNascimento.set(1983, Calendar.NOVEMBER, 15); Pessoa pessoa = new Pessoa(dataNascimento); pessoa.getDataNascimento().add(Calendar.DAY_OF_MONTH, 10); //Afirmação inválida assert pessoa.getDataNascimento() .get(Calendar.DAY_OF_MONTH) == 15; Calendar é mutável
Por que uma nova API? public class Pessoa{ private Calendar dataNascimento; // encapsulada public Pessoa(Calendar dataNascimento){ this.dataNascimento = dataNascimento; } public Calendar getDataNascimento() { return (Calendar) this.dataNascimento.clone(); } }
Por que uma nova API? long duracao = turno.getDuracao(); // horas? minutos? milisegundos?
Por que uma nova API? public class Turno { /** * @return duração de um turno de * trabalho em milisegundos */ public long getDuracao(){ … } }
Evolução 1996 - java.util.Date (JDK 1.0) 1997 - java.util.Calendar (JDK 1.1) 2005 - Joda-Time (third library) 2007 - JSR-310
JSR 310 ● Início oficial em 30/01/2007 ● Líderes ○ Stephen Colebourne ○ Michael Nascimento Santos ○ Roger Riggs ● Baseada fortemente no Joda Time ○ http://blog.joda.org/2009/11/why-jsr-310-isn-joda- time_4941.html
Date Time API JDK 1.8
Princípios fundamentais ● Imutável ● Modelo rico, compreensível e fluente ● Separação de cronologias
Rico modelo de dados Explorando alguns dos novos tipos de dados disponíveis
Datas ● LocalDate ○ Datas consistêm em dia, mês e ano ○ Data de nascimento, feriado, emissão de NF LocalDate.of(2014, Month.MAY, 17);
Horas ● LocalTime ○ Horários consitêm em hora, minutos e segundos ○ Horário de início do expediente, horário do despertador LocalTime.of(13, 10);
Datas e horas ● LocalDateTime ○ Composto por data e horas ○ Data e hora de um atendimento médico, entrada de log, marcação de ponto LocalDateTime.of(2014, Month.MAY, 17, 13, 10);
Mais modelos ● YearMonth ○ ano e mês de alistamento militar ● MonthDay ○ mês e dia de nascimento ● Year ○ ano de fabricação de um automóvel ● Instant ○ um ponto na linha do tempo ○ remete à classe j.u.Date
Mais modelos ● DayOfWeek ○ enum com os dias da semana, SUNDAY, MONDAY.. ● Month ○ enum com os meses do ano JANUARY, FEBRUARY ● ZonedDateTime ○ Time-zones são tratadas separadamente ○ Data e hora em um determinado time-zone ■ Remete à classe java.util.Calendar
A partir do Java 8 será muito importante a escolha correta do tipo de dado baseado na necessidade de cada aplicação.
Formatação e Parsing ● LocalDate.now().format(...) ● LocalDate.parse(...) ● Resolve o problema de thread-safety da API atual
Períodose durações ● Period ○ Montante de tempo em termos de dias, meses e anos ■ 2 anos, 5 meses e 7 dias ● Duration ○ Montante de tempo em termos de tempo ■ 36 segundos ■ 5 horas ■ Porém suporta o conceito de dias com 24 horas
Adjusters ● Usado para alterações complexas ○ ajustar uma data para o último dia do mês ○ ajustar uma data para o proximo dia útil public interface TemporalAdjuster { Temporal adjustInto(Temporal entrada); } LocalDate dataAjustada = data.with(ultimoDiaDoMes()); LocalDate dataAjustada = data.with(proximoDiaUtil());
Adjusters // 2000-10-15, domingo LocalDate date = LocalDate.of(2000, Month.OCTOBER, 15); // primeiro dia do mês: 2000-10-01 date.with(TemporalAdjusters.firstDayOfMonth()); // Primeira segunda do mês: 2000-10-02 date.with(TemporalAdjusters.firstInMonth( DayOfWeek.MONDAY)); // último dia do mês: 2000-10-31 date.with(TemporalAdjusters.lastDayOfMonth());
Adjusters // primeiro dia do próximo mês: 2000-11-01 date.with(TemporalAdjusters.firstDayOfNextMonth()); // primeiro dia do próximo ano: 2001-01-01 date.with(TemporalAdjusters.firstDayOfNextYear()); // primeiro dia do ano: 2000-01-01 date.with(TemporalAdjusters.firstDayOfYear());
Testabilidade ● Suporte a utilização j.t.Clock controlados ○ Mocks ○ Fixos ○ Timezones específicos ● Testes independentes de timezone ● j.t.Clock pode ser injetado ● Trabalhar com datas e horas ficou testável
Resumo ● LocalDate 2014-05-17 ● LocalTime 15:29:33 ● LocalDateTime 2014-05-17T15:29:33 ● OffsetTime 15:29:33+01:00 ● OffsetDateTime 2014-05-17T15:29:33+01:00 ● ZonedDateTime 2014-05-17T15:29:33+01:00 America/Sao_Paulo ● Year 2014 ● YearMonth 2014-05 ● MonthDay 05-17 ● Instant 2343545656.534 epoch-seconds
Interoperabilidade Interagindo com a API antiga
java.util java.time Date Instant GregorianCalendar ZonedDateTime TimeZone ZoneId e ZoneOffset GregorianCalendar (data padrão 1970-01-01) LocalTime GregorianCalendar (hora padrão 00:00) LocalDate Interoperabilidade
Interoperabilidade ● Calendar.toInstant() ● GregorianCalendar.toZonedDateTime() ● GregorianCalendar.from(ZonedDateTime) ● Date.from(Instant) ● Date.toInstant() ● TimeZone.toZoneId()
JDBC e ORM Interagindo com o banco de dados
JDBC ● JDBC no Java 8 suporta os novos tipos sem mudanças na API pública ● getObject e setObject
ANSI SQL Java SE 8 DATE LocalDate TIME LocalTime TIMESTAMP LocalDateTime TIME WITH TIMEZONE OffsetTime TIMESTAMP WITH TIMEZONE OffsetDateTime JDBC
JPA ● Ainda sem suporte oficial aos novos tipos ○ https://java.net/jira/browse/JPA_SPEC-63 ● Necessário criação de conversores
JPA public class LocalDateConverter implements AttributeConverter<LocalDate, Date> { @Override public Date convertToDatabaseColumn(LocalDate ld) { ... } @Override public LocalDate convertToEntityAttribute(Date d) { ... } }
JPA @Override public Date convertToDatabaseColumn(LocalDate ld) { if (ld == null) { return null; } return new Date(ld.getYear() - 1900, ld.getMonthValue() - 1, ld.getDayOfMonth()); }
JPA @Override public LocalDate convertToEntityAttribute(Date d) { if (d == null) { return null; } return LocalDate.of(d.getYear() + 1900, d.getMonth() + 1, d.getDate()); }
Backport ● Suporte ao Java 7 ● Backport de funcionalidades ○ Qualidade de APIs muito superior ○ Migração para Java 8 facilitada ○ Não necessariamente de implementação ● threetenbp ○ https://github.com/ThreeTen/threetenbp
Links ● API e tutorial oficial ○ http://docs.oracle. com/javase/8/docs/api/java/time/package-summary. html ○ http://docs.oracle.com/javase/tutorial/datetime/ ● Projeto threeten-extra ○ https://github.com/ThreeTen/threeten-extra ● Demos e exemplos ○ https://github.com/mgraciano/tdc-2014
Obrigado @klausboeing @mgraciano

Finalmente java sabe trabalhar com data e hora

  • 1.
    Habēmus Java 8 FinalmenteJava sabe trabalhar com datas e horários
  • 2.
    Por que umanova API? public boolean isMesNatal(Calendar calendar){ return calendar.get(Calendar.MONTH) == 11; }
  • 3.
    public boolean isMesNatal(Calendarcalendar){ return calendar.get(Calendar.MONTH) == 11; } Por que uma nova API? Dezembro == 11
  • 4.
    Por que umanova API? Calendar dataNascimento = Calendar.getInstance(); dataNascimento.set(1983, Calendar.NOVEMBER, 15); Pessoa pessoa = new Pessoa(dataNascimento); //Afirmação válida assert pessoa.getDataNascimento() .get(Calendar.DAY_OF_MONTH) == 15;
  • 5.
    Por que umanova API? Calendar dataNascimento = Calendar.getInstance(); dataNascimento.set(1983, Calendar.NOVEMBER, 15); Pessoa pessoa = new Pessoa(dataNascimento); pessoa.getDataNascimento().add(Calendar.DAY_OF_MONTH, 10); //Afirmação inválida assert pessoa.getDataNascimento() .get(Calendar.DAY_OF_MONTH) == 15; Calendar é mutável
  • 6.
    Por que umanova API? public class Pessoa{ private Calendar dataNascimento; // encapsulada public Pessoa(Calendar dataNascimento){ this.dataNascimento = dataNascimento; } public Calendar getDataNascimento() { return (Calendar) this.dataNascimento.clone(); } }
  • 7.
    Por que umanova API? long duracao = turno.getDuracao(); // horas? minutos? milisegundos?
  • 8.
    Por que umanova API? public class Turno { /** * @return duração de um turno de * trabalho em milisegundos */ public long getDuracao(){ … } }
  • 9.
    Evolução 1996 - java.util.Date(JDK 1.0) 1997 - java.util.Calendar (JDK 1.1) 2005 - Joda-Time (third library) 2007 - JSR-310
  • 10.
    JSR 310 ● Iníciooficial em 30/01/2007 ● Líderes ○ Stephen Colebourne ○ Michael Nascimento Santos ○ Roger Riggs ● Baseada fortemente no Joda Time ○ http://blog.joda.org/2009/11/why-jsr-310-isn-joda- time_4941.html
  • 11.
  • 12.
    Princípios fundamentais ● Imutável ●Modelo rico, compreensível e fluente ● Separação de cronologias
  • 13.
    Rico modelo de dados Explorandoalguns dos novos tipos de dados disponíveis
  • 14.
    Datas ● LocalDate ○ Datasconsistêm em dia, mês e ano ○ Data de nascimento, feriado, emissão de NF LocalDate.of(2014, Month.MAY, 17);
  • 15.
    Horas ● LocalTime ○ Horáriosconsitêm em hora, minutos e segundos ○ Horário de início do expediente, horário do despertador LocalTime.of(13, 10);
  • 16.
    Datas e horas ●LocalDateTime ○ Composto por data e horas ○ Data e hora de um atendimento médico, entrada de log, marcação de ponto LocalDateTime.of(2014, Month.MAY, 17, 13, 10);
  • 17.
    Mais modelos ● YearMonth ○ano e mês de alistamento militar ● MonthDay ○ mês e dia de nascimento ● Year ○ ano de fabricação de um automóvel ● Instant ○ um ponto na linha do tempo ○ remete à classe j.u.Date
  • 18.
    Mais modelos ● DayOfWeek ○enum com os dias da semana, SUNDAY, MONDAY.. ● Month ○ enum com os meses do ano JANUARY, FEBRUARY ● ZonedDateTime ○ Time-zones são tratadas separadamente ○ Data e hora em um determinado time-zone ■ Remete à classe java.util.Calendar
  • 19.
    A partir doJava 8 será muito importante a escolha correta do tipo de dado baseado na necessidade de cada aplicação.
  • 20.
    Formatação e Parsing ●LocalDate.now().format(...) ● LocalDate.parse(...) ● Resolve o problema de thread-safety da API atual
  • 21.
    Períodose durações ● Period ○Montante de tempo em termos de dias, meses e anos ■ 2 anos, 5 meses e 7 dias ● Duration ○ Montante de tempo em termos de tempo ■ 36 segundos ■ 5 horas ■ Porém suporta o conceito de dias com 24 horas
  • 22.
    Adjusters ● Usado paraalterações complexas ○ ajustar uma data para o último dia do mês ○ ajustar uma data para o proximo dia útil public interface TemporalAdjuster { Temporal adjustInto(Temporal entrada); } LocalDate dataAjustada = data.with(ultimoDiaDoMes()); LocalDate dataAjustada = data.with(proximoDiaUtil());
  • 23.
    Adjusters // 2000-10-15, domingo LocalDatedate = LocalDate.of(2000, Month.OCTOBER, 15); // primeiro dia do mês: 2000-10-01 date.with(TemporalAdjusters.firstDayOfMonth()); // Primeira segunda do mês: 2000-10-02 date.with(TemporalAdjusters.firstInMonth( DayOfWeek.MONDAY)); // último dia do mês: 2000-10-31 date.with(TemporalAdjusters.lastDayOfMonth());
  • 24.
    Adjusters // primeiro diado próximo mês: 2000-11-01 date.with(TemporalAdjusters.firstDayOfNextMonth()); // primeiro dia do próximo ano: 2001-01-01 date.with(TemporalAdjusters.firstDayOfNextYear()); // primeiro dia do ano: 2000-01-01 date.with(TemporalAdjusters.firstDayOfYear());
  • 25.
    Testabilidade ● Suporte autilização j.t.Clock controlados ○ Mocks ○ Fixos ○ Timezones específicos ● Testes independentes de timezone ● j.t.Clock pode ser injetado ● Trabalhar com datas e horas ficou testável
  • 26.
    Resumo ● LocalDate 2014-05-17 ●LocalTime 15:29:33 ● LocalDateTime 2014-05-17T15:29:33 ● OffsetTime 15:29:33+01:00 ● OffsetDateTime 2014-05-17T15:29:33+01:00 ● ZonedDateTime 2014-05-17T15:29:33+01:00 America/Sao_Paulo ● Year 2014 ● YearMonth 2014-05 ● MonthDay 05-17 ● Instant 2343545656.534 epoch-seconds
  • 27.
  • 28.
    java.util java.time Date Instant GregorianCalendarZonedDateTime TimeZone ZoneId e ZoneOffset GregorianCalendar (data padrão 1970-01-01) LocalTime GregorianCalendar (hora padrão 00:00) LocalDate Interoperabilidade
  • 29.
    Interoperabilidade ● Calendar.toInstant() ● GregorianCalendar.toZonedDateTime() ●GregorianCalendar.from(ZonedDateTime) ● Date.from(Instant) ● Date.toInstant() ● TimeZone.toZoneId()
  • 30.
    JDBC e ORM Interagindocom o banco de dados
  • 31.
    JDBC ● JDBC noJava 8 suporta os novos tipos sem mudanças na API pública ● getObject e setObject
  • 32.
    ANSI SQL JavaSE 8 DATE LocalDate TIME LocalTime TIMESTAMP LocalDateTime TIME WITH TIMEZONE OffsetTime TIMESTAMP WITH TIMEZONE OffsetDateTime JDBC
  • 33.
    JPA ● Ainda semsuporte oficial aos novos tipos ○ https://java.net/jira/browse/JPA_SPEC-63 ● Necessário criação de conversores
  • 34.
    JPA public class LocalDateConverter implementsAttributeConverter<LocalDate, Date> { @Override public Date convertToDatabaseColumn(LocalDate ld) { ... } @Override public LocalDate convertToEntityAttribute(Date d) { ... } }
  • 35.
    JPA @Override public Date convertToDatabaseColumn(LocalDateld) { if (ld == null) { return null; } return new Date(ld.getYear() - 1900, ld.getMonthValue() - 1, ld.getDayOfMonth()); }
  • 36.
    JPA @Override public LocalDate convertToEntityAttribute(Dated) { if (d == null) { return null; } return LocalDate.of(d.getYear() + 1900, d.getMonth() + 1, d.getDate()); }
  • 37.
    Backport ● Suporte aoJava 7 ● Backport de funcionalidades ○ Qualidade de APIs muito superior ○ Migração para Java 8 facilitada ○ Não necessariamente de implementação ● threetenbp ○ https://github.com/ThreeTen/threetenbp
  • 38.
    Links ● API etutorial oficial ○ http://docs.oracle. com/javase/8/docs/api/java/time/package-summary. html ○ http://docs.oracle.com/javase/tutorial/datetime/ ● Projeto threeten-extra ○ https://github.com/ThreeTen/threeten-extra ● Demos e exemplos ○ https://github.com/mgraciano/tdc-2014
  • 39.