Estou trabalhando em um projeto. Lá eu deveria encontrar o total de semanas de um ano. Tentei com o código a seguir, mas recebo a resposta errada: 2020 tem 53 semanas, mas esse código fornece 52 semanas.
Onde eu errei neste código?
package com.hib.mapping;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.joda.time.DateTime;
public class TestWeek {
public static void main(String args[]) {
System.out.println(getWeeks());
}
public static int getWeeks() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2020);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
GregorianCalendar gregorianCalendar = new GregorianCalendar();
int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (gregorianCalendar.isLeapYear(2020)) {
if (weekDay == Calendar.THURSDAY || weekDay == Calendar.WEDNESDAY)
return 53;
else
return 52;
} else {
if (weekDay == Calendar.THURSDAY)
return 53;
else
return 52;
}
}
}
Resultado:
52
java
date
java-8
week-number
Kumaresan Perumal
fonte
fonte
Date
eCalendar
. Usejava.time
, em vez disso, é muito melhor e mais simples.Respostas:
Usando a definição da Wikipedia aqui . Um ano tem 53 semanas se 1º de janeiro é quinta-feira ou 31 de dezembro é quinta-feira, caso contrário, tem 52 semanas. Essa definição é equivalente à que você usou. Acho que essa é uma condição muito mais fácil de verificar, pois você não precisa verificar se há anos bissextos.
Usando as
java.time
APIs do Java 8 :fonte
tl; dr
Para uma semana ISO 8601 padrão, use a
YearWeek
classe da biblioteca ThreeTen-Extra com uma declaração ternária.Isso é,
YearWeek.of( 2020 , 1 ).is53WeekYear() ? 53 : 52
Definir "semana"
Você precisa definir uma semana. No seu exemplo de código, a definição de semana varia de acordo com o padrão atual da JVM
Locale
. Portanto, seus resultados podem variar em tempo de execução.Seu código também usa classes de data e hora terríveis que foram substituídas anos atrás pelas modernas classes java.time . Pare de usar o
GregorianCalendar
&Calendar
; eles foram substituídos por boas razões.Semana ISO 8601
A norma ISO 8601 padrão define uma semana como:
Essa definição significa:
Se sua definição for diferente, consulte a resposta por Ole VV .
YearWeek:is53WeekYear
Se isso corresponder à sua definição, adicione a biblioteca ThreeTen-Extra ao seu projeto para estender a funcionalidade java.time incorporada ao Java 8 e posterior. Você então tem acesso à
YearWeek
classe.Para perguntar sobre um determinado ano com base na semana, escolha arbitrariamente qualquer semana do ano. Por exemplo, para o ano 2020 baseado em semana, solicitamos a semana nº 1.
Observe como o primeiro dia do ano semanal de 2020 é a partir do ano civil de 2019.
fonte
now
. Como você deseja obter a contagem da semana para um ano específico, em vez do ano atual, basta usarYearWeek.of(yourYear, 1)
.Asia/Kolkata
, atualmente com um deslocamento de +05: 30. No código Java:ZoneId.of( "Asia/Kolkata" )
. Para mais informações e histórico, consulte Wikipedia, Hora na Índia .A solução flexível
Isso deve funcionar para qualquer esquema de numeração semanal que possa ser representado em um
WeekFields
objeto.A idéia é encontrar o número da semana da última semana do ano com base na semana. Tento primeiro com 31 de dezembro, mas isso pode ocorrer na primeira semana do ano seguinte. Se assim for, eu vou uma semana atrás.
Eu testei bastante com
WeekFields.ISO
, não tanto com outrosWeekFields
objetos, mas como eu disse, acredito que funciona.Se você sabe que sempre precisará da ISO 8601 semanas, acho que deve seguir uma das boas respostas de Sweeper e Basil Bourque . Postei isso caso você precisasse de uma solução mais flexível que também funcionasse com outros esquemas de numeração semanal.
Use java.time
O código da sua pergunta é engraçado, pois importa classes do Joda-Time e do java.time, mas usa o antigo
Calendar
e oGregorianCalendar
Java 1.1. Essas classes foram mal projetadas e agora estão desatualizadas há muito tempo, você não deve usá-las. O Joda-Time está no modo de manutenção, o java.time assumiu o controle. Qual é o que eu uso e recomendo que você use.fonte
Eu acho que isso deve funcionar muito bem também:
fonte
Depois de tentar muito no java 8. Não consegui encontrar uma solução. então preparei a dependência de data e hora de Joda. Deu-me uma boa resposta como eu esperava
código:
Dependência do Maven:
fonte