Como comparar duas contas java

Apenas para complementar as respostas anteriores, a partir do Java 8 você pode usar a API java.time.

Há alguns detalhes a se considerar ao trabalhar com a API antiga (java.util.Date) e a nova simultaneamente, pois alguns conceitos são diferentes. Segue então uma breve explicação sobre Date, para que possamos entender a conversão desta para as classes do java.time.

Sobre java.util.Date

java.util.Date, apesar do nome, não é exatamente uma data propriamente dita, pois ela não representa um único valor de dia, mês e ano. Ela representa na verdade um timestamp: um número gigante (do tipo long) contendo a quantidade de milissegundos desde o Unix Epoch (1970-01-01T00:00Z, ou "1 de janeiro de 1970, à meia noite, em UTC").

O timestamp é um valor, digamos, "universal". Neste exato momento, em qualquer lugar do mundo, o timestamp é o mesmo. Em Java, basta chamar System.currentTimeMillis() e você terá o timestamp correspondente ao instante atual. Eu rodei agora e o valor retornado foi 1534249967760. E este valor é o mesmo no mundo todo: qualquer computador, em qualquer fuso horário do mundo, obteria este mesmo número se chamasse System.currentTimeMillis() no mesmo instante que eu.

Só que este valor (1534249967760) pode representar uma data/hora diferente em cada fuso horário. Em São Paulo, este timestamp equivale a 14 de agosto de 2018, às 09:32:47.760 da manhã. Em Londres, equivale ao mesmo dia (14 de agosto), mas neste mesmo instante o horário lá é 13:32 (1 da tarde). E em Samoa já são 01:32 (1 da manhã) do dia 15.

Podemos ver melhor isso imprimindo o Date (com System.out.println ou com qualquer API de log). Ao imprimí-lo, este é convertido para o timezone default da JVM, por isso o resultado contém uma data e hora específicas. Mas o valor do Date não muda. No código abaixo eu uso a classe java.util.TimeZone para mudar o timezone default:

// código rodado quando o timestamp atual é 1534249967760 Date date = new Date(); TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo")); System.out.println(date.getTime() + "=" + date); TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(date.getTime() + "=" + date); TimeZone.setDefault(TimeZone.getTimeZone("Pacific/Apia")); System.out.println(date.getTime() + "=" + date);

Eu mudei o timezone default 3 vezes, para São Paulo, Londres e Apia (que é o timezone de Samoa) e imprimi o Date e o valor de getTime() (que retorna o valor do timestamp). O resultado é:

1534249967760=Tue Aug 14 09:32:47 BRT 2018 1534249967760=Tue Aug 14 13:32:47 BST 2018 1534249967760=Wed Aug 15 01:32:47 WSST 2018

Repare que o timestamp não muda, mas a data e hora sim. Isso acontece porque ao imprimir o Date, ele converte o timestamp para o timezone default, resultando em uma data e hora diferentes em cada caso. Mas estes valores de data e hora não fazem parte do Date, somente o timestamp.

Por isso, para converter um Date para uma data (um dia, mês e ano específicos), você deve escolher um fuso horário (que a API chama de timezone). O que acontece com Calendar é que internamente ele usa o timezone default da JVM e já calcula os valores para o dia, mês, ano, horas, minutos, segundos etc.

Mas no java.time isso não acontece automaticamente e você deve especificar qual timezone deve ser usado.

Com isso, podemos prosseguir para a conversão de Date para as classes do java.time.

Converter Date para uma data e hora específicas

Primeiro convertemos o Date para java.time.Instant, que é a classe que representa um timestamp. Para isso foi adicionado o método toInstant() (disponível a partir do Java 8):

Date data = new Date(); // criar Instant (com o mesmo valor do timestamp de Date) Instant instant = data.toInstant();

A partir do Instant, podemos convertê-lo para um timezone qualquer, usando a classe java.time.ZoneId (que representa um timezone). O resultado será um java.time.ZonedDateTime (uma classe que representa uma data e hora em um timezone específico). Exemplo:

Date data = new Date(); ZonedDateTime zdt = data.toInstant() // converter o Instant para um timezone .atZone(ZoneId.of("America/Sao_Paulo"));

O nome do timezone (America/Sao_Paulo) segue a nomenclatura da IANA, que é a base de dados usada pela JVM para obter informações do timezone (como início e fim do horário de verão, por exemplo, assim ela consegue saber exatamente a data e hora correspondente ao timestamp).

Se você quiser usar o timezone default da JVM (e assim simular o que Calendar faz), pode usar ZoneId.systemDefault(). Fica a seu critério.

Para obter a data atual, basta usar o método now():

ZonedDateTime agora = ZonedDateTime.now();

Isso cria um ZonedDateTime contendo a data e hora atual, no timezone default da JVM. Se quiser usar um timezone específico, basta passar o ZoneId:

ZonedDateTime agora = ZonedDateTime.now(ZoneId.of("America/Sao_Paulo"));

Com isso você obtém os valores corretos para a data e hora no timezone que quiser, sem depender da configuração da JVM (que pode mudar sem você saber, pois qualquer parte do código pode chamar TimeZone.setDefault, afetando todas as aplicações que rodam na mesma JVM).

Para fazer as comparações necessárias, basta usar o método equals (para verificar igualdade) e isAfter (para saber se um determinado instante ocorre depois de outro).

A primeira comparação leva em conta apenas a data (ignorando a hora), então você deve usar o método toLocalDate(), que retorna um java.time.LocalDate (uma classe que só possui dia, mês e ano), assim a comparação é feita ignorando o horário.

Depois, para a segunda comparação, basta usar o método toLocalTime(), que retorna um java.time.LocalTime (uma classe que só possui hora, minuto, segundo e frações de segundo). Em seguida comparamos com outro java.time.Localtime cujo valor é 11:00.

Aliás, esta é outra característica do java.time: várias classes especializadas para cada situação (uma que só representa data, outra só para as horas, outra para data e hora com timezone, etc).

Enfim, o código ficaria assim (assumindo que você quer usar o timezone default da JVM):

public boolean possoProcessarPedido(Date dataPedido) { ZonedDateTime pedido = dataPedido.toInstant().atZone(ZoneId.systemDefault()); ZonedDateTime dataAtual = ZonedDateTime.now(); // comparar somente a data (ignora o horário) if (! dataAtual.toLocalDate().equals(pedido.toLocalDate())) { // data do pedido e data atual são diferentes - pode processar return true; } // se não entrou no if acima é porque as datas são iguais // verificar se já passou das 11:00 if (dataAtual.toLocalTime().isAfter(LocalTime.of(11, 0))) { // passou das 11:00 - não pode processar return false; } // não passou das 11:00 - pode processar return true; }

Se ao invés do timezone default, você quiser usar um timezone específico, basta usar o ZoneId correspondente, conforme já explicado anteriormente.

Java 6 e 7

Para Java 6 e 7, você pode usar o ThreeTen Backport, um backport do java.time. Basicamente, possui as mesmas classes (Instant, LocalDate, ZoneId, etc) e métodos do Java 8, com uma diferença: no Java 8 as classes estão no pacote java.time, e no backport elas ficam em org.threeten.bp.

Outra diferença é que no Java 6 e 7 a classe Date não possui o método toInstant() e a conversão deve ser feita pela classe org.threeten.bp.DateTimeUtils:

Date date = new Date(); Instant instant = DateTimeUtils.toInstant(date);

O restante do código ficaria igual.

Java <= 5

Para Java <= 5, é possível usar o Joda-Time. Esta API é o "predecessor" do java.time, e muitos conceitos são parecidos (até alguns nomes de classes são os mesmos), embora ela não seja 100% igual.

O código fica bem parecido: ao invés de ZonedDateTime, usamos a classe org.joda.time.DateTime - aliás, todas as classes abaixo (LocalDate, Localtime, etc), embora tenham os mesmos nomes do java.time, estão no pacote org.joda.time:

public boolean possoProcessarPedido(Date dataPedido) { DateTime pedido = new DateTime(dataPedido); DateTime dataAtual = new DateTime(); // comparar somente a data if (!dataAtual.toLocalDate().equals(pedido.toLocalDate())) { // data do pedido e data atual são diferentes - pode processar return true; } // se não entrou no if acima é porque as datas são iguais // verificar se já passou das 11:00 if (dataAtual.toLocalTime().isAfter(new LocalTime(11, 0))) { // passou das 11:00 - não pode processar return false; } // não passou das 11:00 - pode processar return true; }

Este código usa o timezone default da JVM para converter o Date para DateTime. Se quiser usar um timezone específico, use a classe org.joda.time.DateTimeZone:

DateTimeZone timezone = DateTimeZone.forID("America/Sao_Paulo"); DateTime pedido = new DateTime(dataPedido, timezone); DateTime dataAtual = new DateTime(timezone);

O método forID recebe o nome do timezone, também seguindo a nomenclatura da IANA.

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

Pessoal,

Integer a = new Integer(“2”);
Integer b = new Integer(“2”);

Preciso saber se a == b. Como faço?

if (a.equals(b)) …

e outra, nao usa new Integer(“2”) usa new Integer(2) mesmo

Se você usar o operador “==” vai estar comparando se as duas variáveis referência apontam para o mesmo endereço na memória… E o método equals compara os atributos destes objetos, no casos os valores inteiros armazenados neles.

Rafael

Na verdade tudo isso funciona da mesma forma.

[code]public class Test {
static Integer i2 = 5;

public static void main(String[] args) { Integer i = 5; System.out.println(i==i2); System.out.println(i.intValue()==i2); System.out.println(i.intValue()==i2.intValue()); System.out.println(i.equals(i2)); }

} [/code]

Isso é intrigante… mas… se alguem souber explicar
System.out.println(i==i2);

[quote=volnei]Na verdade tudo isso funciona da mesma forma.

[code]public class Test {
static Integer i2 = 5;

public static void main(String[] args) { Integer i = 5; System.out.println(i==i2); System.out.println(i.intValue()==i2); System.out.println(i.intValue()==i2.intValue()); System.out.println(i.equals(i2)); }

} [/code]

Isso é intrigante… mas… se alguem souber explicar
System.out.println(i==i2);[/quote]

Olá… voce não pode usar desta forma:

Integer i = 5;

Pois o tipo referência Integer não é equivalente a um tipo int primitivo literal 5

[quote=Gregoryan]Olá… voce não pode usar desta forma:

Integer i = 5;

Pois o tipo referência Integer não é equivalente a um tipo int primitivo literal 5[/quote]

Quem disse que não?

Como o cv disse num outro tópico (http://www.guj.com.br/posts/list/25152.java):

Isso eh o autoboxing do Java 5. O que o compilador ta fazendo pra vc eh soh te deixar nao digitar o new Integer(x);, mas ele continua la.

Pra dificultar um pouco, entao. Pq == funciona nesse caso?

[code]public class WhatTheFuck {
public static final String FOO = “foo”;

public static void main(String[] args) { String foo = “foo”; System.out.println(“foo” == “foo”); System.out.println(“foo” == FOO); System.out.println(“foo” == foo); System.out.println(foo == FOO); }

}[/code]

:mrgreen:

A maldição da tabela de strings imutáveis do java :shock:

1 curtida

Porque a JVM tem um tipo de ‘container de Strings’(pool de strings?) sei lá o nome desse patuá, em que quando já há uma String criada na memória(dentro deste pool), ao se criar outra igual ele permanece a que já existe, e aponta a variávelde referência para o mesmo objeto. Isso tem lógica para acontecer porque Strings são imutáveis.

1 curtida

hmmm, legal! Agora eu tenho uma noção vaga, gostaria de saber o porque mesmo de que temos esses objetos (Integer, Double, …) que encapsulam os tipos primitivos.

Valeu pessoar!

Como comparar duas contas java

Nos temos tipos primitivos em Java pq abstracoes, no fim das contas, falham - especialmente quando se precisa de performance.

Na epoca, os caras achavam que o unico jeito de tornar Java algo performatico seria usar tipos primitivos, mesmo que isso comprometesse a linguagem de algumas maneiras.

Os wrapper objects, (Integer, Long, Double, Character, Boolean, Short, Byte e Float) existem pra que voce possa adicionar um int numa ArrayList sem grilo, por exemplo. Ou seja, eh uma macumba pra fazer com que qualquer metodo que aceite como paramertos ou retorne Object possa tambem trabalhar com tipos primitivos. No Java 5, a necessidade de se trabalhar diretamente com eles foi reduzida bastante por causa do novo recurso de autoboxing, mas ainda assim, tem varios pontos cegos que eh bom prestar atencao - por exemplo, se vc tiver dois metodos sobrecarregados, um que aceita Object e outro int, e passar um 5 como parametro, qual deles eh chamado? Pq?

Como comparar duas contas java

Bem, tentando responder a uma pergunta da “Avaliação de Java básico, por CV”. hehehehe

É chamado o que aceita int, pois a constante 5 é considerado um tipo primitivo int. Por questão de performance mesmo né?!

To certo?!

Valeuuu

Tenho uma dúvida … como verificar se um valor inteiro esta contido em uma lista?
Atualmente trabalho com Delphi, porém estou migrando minhas aplicações para o Java, no Delphi usa-se:

var valor: int; begin if (valor in [0, 1, 2]) then // True

end;

Eis a situação …

Agradeço desde já!

[quote=volnei]Na verdade tudo isso funciona da mesma forma.

[code]public class Test {
static Integer i2 = 5;

public static void main(String[] args) { Integer i = 5; System.out.println(i==i2); }

} [/code]

Isso é intrigante… mas… se alguem souber explicar
System.out.println(i==i2);[/quote]

Já que ressucitaram o tópico… No caso de Short e Integer eles retornam true desde que o valor esteja entre -128 até 127. Para confirmar isso pode-se declaram mais duas variáveis diferentes com o valor 128…retornará false ao invés de true.

Procure sobre Boxing.