public class Main {
public static void main(String[] args) {
String date = "June 11, 2018";
System.out.println(date);
}
}
Mas esta abordagem tem muitas desvantagens. A classe String
foi criada para trabalhar com texto e possui métodos apropriados. Se precisarmos gerenciar a data de alguma forma (adicionar 2 horas, por exemplo), String
não funcionará aqui. Ou, por exemplo, exiba a data e hora atuais no momento em que o programa foi compilado no console. Aqui String
também não vai adiantar: enquanto você escreve o código e o executa, o tempo mudará e o irrelevante será exibido no console. Portanto, em Java, seus criadores disponibilizaram diversas classes para trabalhar com datas e horas. O primeiro é a aulajava.util.Date
Classe de data Java
Demos a ele o nome completo porque também existe uma classe em outro pacote em Javajava.sql.Date
. Não se confunda! A primeira coisa que você precisa saber é que ele armazena em milissegundos a data que se passou desde 1º de janeiro de 1970. Existe até um nome separado para esta data - “Hora Unix”. Uma forma bastante interessante, não concorda? :) A segunda coisa a lembrar: se você criar um objeto Date
com um construtor vazio, o resultado será a data e hora atuais no momento em que o objeto foi criado . String
Você se lembra de como escrevemos que tal tarefa seria problemática para um formato de data ? A turma Date
resolve isso facilmente.
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
}
Execute este código várias vezes e você verá como o tempo vai mudar a cada vez :) Isso é possível justamente porque ele é armazenado em milissegundos: são a menor unidade de tempo, por isso os resultados são tão precisos. Existe outro construtor para Date
: você pode especificar o número exato de milissegundos que se passaram desde 00:00 de 1º de janeiro de 1970 até a data necessária, e ele será criado:
public class Main {
public static void main(String[] args) {
Date date = new Date(1212121212121L);
System.out.println(date);
}
}
Saída do console:
Fri May 30 08:20:12 MSD 2008
Recebemos em 30 de maio de 2008. “Sex” significa o dia da semana - “sexta-feira” (sexta-feira) e MSD - “horário de verão de Moscou” (horário de verão de Moscou). Milissegundos são transmitidos no formato long
, já que seu número geralmente não cabe int
. Então, que tipo de operações de data podemos precisar em nosso trabalho? Bem, a coisa mais óbvia, claro, é a comparação . Determine se uma data foi posterior ou anterior a outra. Isso pode ser feito de diferentes maneiras. Por exemplo, você pode chamar o método . Date.getTime()
, que retornará o número de milissegundos que se passaram desde a meia-noite de 1º de janeiro de 1970. Vamos apenas chamá-lo em dois objetos Date e compará-los entre si:
public class Main {
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println((date1.getTime() > date2.getTime())?
"date1 is later than date2" : "date1 is earlier than date2");
}
}
Conclusão:
date1 раньше date2
Mas existe uma maneira mais conveniente, a saber, usar métodos especiais da classe Date
: before()
e . Todos eles retornam o resultado em . O método verifica se nossa data é anterior àquela que passamos como argumento: after()
equals()
boolean
before()
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);//pause the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.before(date2));
}
}
Saída do console:
true
O método funciona de maneira semelhante after()
; ele verifica se nossa data foi posterior àquela que passamos como argumento:
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);//pause the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.after(date2));
}
}
Saída do console:
false
Em nossos exemplos, colocamos o programa em hibernação por 2 segundos para que as duas datas sejam garantidamente diferentes. Em computadores rápidos, o tempo entre a criação date1
de e date2
pode ser inferior a um milissegundo; nesse caso, e before()
e after()
retornarão false
. Mas o método equals()
em tal situação retornará true
! Afinal, ele compara exatamente o número de milissegundos que se passaram desde 00h00 de 1º de janeiro de 1970 para cada data. Os objetos só serão considerados iguais se corresponderem até o milissegundo:
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println(date1.getTime());
System.out.println(date2.getTime());
System.out.println(date1.equals(date2));
}
Aqui está outra coisa que você precisa prestar atenção. Se você abrir a documentação da classe Date
no site da Oracle, verá que muitos de seus métodos e construtores foram designados como Deprecated
(“obsoletos”). Aqui, veja: Data da Classe Aqui está o que os próprios criadores de Java dizem sobre as partes das classes que se tornaram obsoletas: “Um elemento de programa anotado com @Deprecated é algo que os programadores são desencorajados de usar, geralmente porque é perigoso, ou porque isso existe uma alternativa melhor.” Isso não significa que esses métodos não possam ser usados. Além disso, se você mesmo tentar executar o código usando-os no IDEA, provavelmente funcionará. Tomemos por exemplo o método obsoleto Date.getHours()
, que retorna o número de horas do objeto Date
.
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.getHours());
}
Se no momento em que você executa o código, por exemplo, o horário for 14:21, ele exibirá o número 14. Como você pode ver, o método obsoleto está riscado, mas funciona muito bem. Esses métodos não foram removidos completamente, para não quebrar um monte de código já escrito com eles. Ou seja, esses métodos não estão “quebrados” ou “removidos”, simplesmente não são recomendados para uso devido à disponibilidade de uma alternativa mais conveniente. A propósito, está escrito sobre isso na documentação: A maioria dos métodos da classe Date foram movidos para sua versão aprimorada e estendida - a classe Calendar
. Iremos conhecê-lo melhor :)
Calendário Java
Java 1.1 introduziu uma nova classe -Calendar
. Ele tornou o trabalho com datas em Java um pouco mais fácil do que parecia antes. A única implementação da classe Calendar
com a qual trabalharemos é a classe GregorianCalendar
(ela implementa o calendário gregoriano, segundo o qual vive a maioria dos países do mundo). Sua principal comodidade é poder trabalhar com datas em um formato mais conveniente. Por exemplo, ele pode:
- Adicione um mês ou dia à data atual
- Verifique se o ano é bissexto;
- Obtenha componentes de data individuais (por exemplo, obtenha o número do mês de uma data inteira)
- E também dentro dele foi desenvolvido um sistema de constantes muito conveniente (veremos muitos deles a seguir).
Calendar
é que ela implementa uma constante Calendar.Era
: você pode definir a data para a era AC (“Antes de Cristo” - antes do nascimento de Cristo, ou seja, “antes de nossa era”) ou AC (“Depois de Cristo” - “ nossa época"). Vejamos tudo isso com exemplos. Vamos criar um calendário com a data 25 de janeiro de 2017:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
Os meses da turma Calendar
(como em Date
, aliás) começam do zero, então passamos o número 0 como segundo argumento. O principal ao trabalhar com uma turma Calendar
é entender que se trata de um calendário e não de uma data separada. Uma data é simplesmente uma série de números que representam um período específico de tempo. E um calendário é um dispositivo completo com o qual você pode fazer muitas coisas com datas :) Isso pode ser visto claramente se você tentar enviar o objeto Calendário para o console: Saída:
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Moscow",offset=10800000,dstSavings=0,useDaylight=false,transitions=79,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=1,ERA=?,YEAR=2017,MONTH=0,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
Veja quanta informação existe! O calendário possui várias propriedades que uma data normal não possui, e todas elas são enviadas para o console (é assim que funciona o método toString()
na classe Calendar
). Se, ao trabalhar, você só precisa obter uma data simples do calendário, ou seja, objeto Date
- isso é feito usando um método Calendar.getTime()
(o nome não é o mais lógico, mas nada pode ser feito):
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
Date date = calendar.getTime();
System.out.println(date);
}
Conclusão:
Wed Jan 25 00:00:00 MSK 2017
Agora “simplificamos” o calendário para uma data normal. Vamos continuar. Além dos símbolos numéricos para meses, Calendar
constantes podem ser usadas em sala de aula. Constantes são campos estáticos de uma classe Calendar
com um valor já definido que não pode ser alterado. Esta opção é realmente melhor, pois melhora a legibilidade do código.
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.JANUARY
— uma das constantes para indicar o mês. Com esta opção de nomenclatura, ninguém esquecerá, por exemplo, que o número “3” significa abril, e não o terceiro mês a que estamos habituados - março. Basta escrever Calendar.APRIL
- e pronto :) Todos os campos do calendário (dia, mês, minutos, segundos, etc.) podem ser definidos individualmente usando o método set()
. É muito conveniente, pois Calendar
cada campo possui sua própria constante na classe e o código final parecerá o mais simples possível. Por exemplo, no exemplo anterior, criamos uma data, mas não definimos a hora atual para ela. Vamos definir o horário para 19:42:12
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.YEAR, 2017);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 25);
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println(calendar.getTime());
}
Conclusão:
Wed Jan 25 19:42:12 MSK 2017
Chamamos o método set()
, passamos uma constante para ele (dependendo do campo que queremos alterar) e um novo valor para este campo. Acontece que o método set()
é uma espécie de “supersetter” que pode definir um valor não para um campo, mas para vários campos :) A adição e subtração de valores em uma classe Calendar
é realizada usando o método add()
. Você precisa passar nele o campo que deseja alterar e o número - exatamente quanto deseja adicionar/subtrair do valor atual. Por exemplo, vamos definir a data que criamos para 2 meses atrás:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.add(Calendar.MONTH, -2);//to subtract a value - a negative number must be passed to the method
System.out.println(calendar.getTime());
}
Conclusão:
Fri Nov 25 19:42:12 MSK 2016
Ótimo! Redefinimos a data para 2 meses atrás. Com isso, não só o mês, mas também o ano mudou, de 2017 para 2016. O cálculo do ano corrente na mudança de datas, claro, é feito de forma automática e não precisa ser controlado manualmente. Mas se por algum motivo você precisar desabilitar esse comportamento, você pode fazer isso. Um método especial roll()
pode adicionar e subtrair valores sem afetar outros valores. Por exemplo, assim:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
}
Fizemos exatamente o mesmo que no exemplo anterior - subtraímos 2 meses da data atual. Mas agora o código funcionou de forma diferente: o mês mudou de janeiro para novembro, mas o ano permaneceu igual a 2017! Conclusão:
Sat Nov 25 10:42:12 MSK 2017
Avançar. Como dissemos acima, todos os campos de um objeto Calendar
podem ser obtidos separadamente. O método é responsável por isso get()
:
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println("Year: " + calendar.get(Calendar.YEAR));
System.out.println("Month: " + calendar.get(Calendar.MONTH));
System.out.println("Number of the week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// serial number of the week in the month
System.out.println("Number: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("Watch: " + calendar.get(Calendar.HOUR));
System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));
}
Conclusão:
Год: 2017
Месяц: 0
Порядковый номер недели в месяце: 4
Число: 25
Часы: 10
Минуты: 42
Секунды: 12
Миллисекунды: 0
Ou seja, além do “super-setter” da turma Calendar
também existe um “super-getter” :) Outro ponto interessante é, claro, trabalhar com eras. Para criar uma data “BC” é necessário utilizar o campo Calendar.Era
Por exemplo, vamos criar uma data indicando a Batalha de Canas, na qual Aníbal derrotou o exército de Roma. Isso aconteceu em 2 de agosto de 216 AC. ex.:
public static void main(String[] args) {
GregorianCalendar cannes = new GregorianCalendar(216, Calendar.AUGUST, 2);
cannes.set(Calendar.ERA, GregorianCalendar.BC);
DateFormat df = new SimpleDateFormat("dd MMM yyy GG");
System.out.println(df.format(cannes.getTime()));
}
Aqui utilizamos a classe SimpleDateFormat
para exibir a data em um formato que nos seja mais compreensível (as letras “GG” são responsáveis por exibir a época). Conclusão:
02 авг 216 до н.э.
Calendar
Existem muitos mais métodos e constantes na classe , leia sobre eles na documentação:
Convertendo string em data
Para converter String em Data, você pode usar a classe auxiliar Java - SimpleDateFormat . Esta é a classe que você precisa para converter uma data em um formato que você definir. Por sua vez, é muito semelhante ao DateFormat . A única diferença notável entre os dois é que SimpleDateFormat pode ser usado para formatação (conversão de uma data em uma string) e análise da string em uma data com reconhecimento de localidade, enquanto DateFormat não oferece suporte a uma localidade. Além disso, DateFormat é uma classe abstrata que fornece suporte básico para formatação e análise de datas, enquanto SimpleDateFormat é uma classe concreta que estende a classe DateFormat. Este é o exemplo de criação de um objeto SimpleDateFormat e formatação de uma data:SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(1212121212121L);
System.out.println(formatter.format(date));
No exemplo acima usamos o padrão "yyyy-MM-dd HH:mm:ss" que significa:
- 4 dígitos para ano (aaaa);
- 2 dígitos para mês (MM);
- 2 dígitos para dia (dd);
- 2 dígitos para horas no formato 24 horas (HH);
- 2 dígitos para minutos (mm);
- 2 dígitos para segundos (ss).
2008-05-30 08:20:12
Existem muitos modelos de cartas para a classe SimpleDateFormat . Para que você não se confunda, reunimos em uma tabela:
Símbolo | Descrição | Exemplo |
---|---|---|
G | era (na localização em inglês - AD e BC) | DE ANÚNCIOS |
sim | ano (número de 4 dígitos) | 2020 |
aa | ano (últimos 2 dígitos) | 20 |
aaaa | ano (número de 4 dígitos) | 2020 |
M | número do mês (sem zeros à esquerda) | 8 |
MILÍMETROS | número do mês (com zeros à esquerda se o número do mês <10) | 04 |
MMM | abreviatura de três letras do mês (de acordo com a localização) | janeiro |
MMMM | nome completo do mês | Junho |
c | semana do ano (sem zeros à esquerda) | 4 |
uau | semana do ano (com zeros à esquerda) | 04 |
C | semana no mês (sem zeros à esquerda) | 3 |
Guerra Mundial | semana no mês (com zero à esquerda) | 03 |
D | dia do ano | 67 |
d | dia do mês (sem zeros à esquerda) | 9 |
dd | dia do mês (com zeros à esquerda) | 09 |
F | dia da semana no mês (sem zeros à esquerda) | 9 |
FF | dia da semana no mês (com zeros à esquerda) | 09 |
E | dia da semana (abreviatura) | C |
EEEE | dia da semana (completo) | Sexta-feira |
você | número do dia da semana (sem zeros à esquerda) | 5 |
você | número do dia da semana (com zeros à esquerda) | 05 |
a | Marcador AM/PM | SOU. |
H | horas no formato de 24 horas sem zeros à esquerda | 6 |
HH | relógio no formato de 24 horas com zero à esquerda | 06 |
k | número de horas no formato de 24 horas | 18 |
K | número de horas no formato de 12 horas | 6 |
h | hora no formato de 12 horas sem zeros à esquerda | 6 |
ah | hora no formato de 12 horas com zero à esquerda | 06 |
eu | minutos sem zeros à esquerda | 32 |
milímetros | minutos com zero à esquerda | 32 |
é | segundos sem zeros à esquerda | onze |
ss | segundos com zero à esquerda | onze |
S | milissegundos | 297 |
z | Fuso horário | EET |
Z | fuso horário no formato RFC 822 | 300 |
Amostra | Exemplo |
---|---|
dd-MM-aaaa | 11/01/2020 |
aaaa-MM-dd | 01/10/2019 |
HH:mm:ss.SSS | 23:59.59.999 |
aaaa-MM-dd HH:mm:ss | 30/11/2018 03:09:02 |
aaaa-MM-dd HH:mm:ss.SSS | 01-03-2016 01:20:47.999 |
aaaa-MM-dd HH:mm:ss.SSS Z | 13/13/2013 23:59:59.999 +0100 |
-
Crie uma linha a partir da qual você precisa definir a data:
String strDate = "Sat, April 4, 2020";
-
Criamos um novo objeto SimpleDateFormat com um modelo que corresponde ao que temos na string (caso contrário não poderemos analisá-lo):
SimpleDateFormat formatter = new SimpleDateFormat("EEE, MMMM d, yyyy", Locale.ENGLISH);
Como você pode ver, temos um argumento Locale aqui. Se o omitirmos, usaremos o Locale padrão, que nem sempre é o inglês.
Se o código do idioma não corresponder à string de entrada, os dados da string vinculados ao idioma, como o nosso Mon ou April , não serão reconhecidos e lançarão um java.text.ParseException, mesmo que o padrão corresponda.
No entanto, não precisamos especificar o formato se estivermos usando um modelo que não seja específico do idioma. Por exemplo - aaaa-MM-dd HH:mm:ss
-
Criamos uma data usando um formatador, que por sua vez a analisa a partir da string de entrada:
try { Date date = formatter.parse(strDate); System.out.println(date); } catch (ParseException e) { e.printStackTrace(); }
Saída do console:
Sat Apr 04 00:00:00 EEST 2020
Hummm... Mas o formato já não é o mesmo!
Para fazer o mesmo formato, usamos novamente o formatador:
System.out.println(formatter.format(date));
Saída do console:
Sat, April 4, 2020
SimpleDateFormat e calendário
SimpleDateFormat permite formatar todos os objetos de data e calendário criados para uso posterior. Consideremos um ponto tão interessante como trabalhar com épocas. Para criar uma data “BC”, você precisa usar o campo Calendar.Era. Por exemplo, vamos criar uma data indicando a Batalha de Canas, na qual Aníbal derrotou o exército de Roma. Isso aconteceu em 2 de agosto de 216 AC. ex.:public static void main(String[] args) {
GregorianCalendar cannes = new GregorianCalendar(216, Calendar.AUGUST, 2);
cannes.set(Calendar.ERA, GregorianCalendar.BC);
DateFormat df = new SimpleDateFormat("dd MMM yyy GG");
System.out.println(df.format(cannes.getTime()));
}
Aqui utilizamos a classe SimpleDateFormat para exibir a data em um formato que nos seja mais compreensível (conforme indicado acima, as letras “GG” são responsáveis por exibir a época). Conclusão:
02 авг 216 до н.э.
Formato de data Java
Aqui está outro caso. Suponhamos que este formato de data não nos convém:
Sat Nov 25 10:42:12 MSK 2017
Então aqui está. Usando nossos recursos no formato de data java, você pode alterá-lo para o seu próprio sem muita dificuldade:
public static void main(String[] args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, d MMMM yyyy");
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(dateFormat.format(calendar.getTime()));
}
Conclusão:
суббота, 25 Ноябрь 2017
Muito melhor, certo? :)
GO TO FULL VERSION