Stack Overflow em Português Asked by Rafael Silva on November 30, 2021
tenho essa função que me traz o dia da semana:
public static String getWeek(String date){ //ex 07/03/2017
String dayWeek = "---";
GregorianCalendar gc = new GregorianCalendar();
try {
gc.setTime(new SimpleDateFormat("MM/dd/yyyy", BRAZIL).parse(date));
switch (gc.get(Calendar.DAY_OF_WEEK)) {
case Calendar.SUNDAY:
dayWeek = "DOM";
break;
case Calendar.MONDAY:
dayWeek = "SEG";
break;
case Calendar.TUESDAY:
dayWeek = "TER";
break;
case Calendar.WEDNESDAY:
dayWeek = "QUA";
break;
case Calendar.THURSDAY:
dayWeek = "QUI";
break;
case Calendar.FRIDAY:
dayWeek = "SEX";
break;
case Calendar.SATURDAY:
dayWeek = "SAB";
}
} catch (ParseException e) {
e.printStackTrace();
}
return dayWeek;
}
Mas ela esta me trazendo o dia da semana anterior, ex: 07/03/2017 terça-feira ele traz como segunda-feira.
A partir do Java 8, você pode usar a API java.time
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;
public static String getDayOfWeek(String data) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu");
DayOfWeek dow = DayOfWeek.from(parser.parse(data));
return dow.getDisplayName(TextStyle.SHORT, new Locale("pt", "BR")).toUpperCase();
}
System.out.println(getDayOfWeek("07/03/2017")); // TER
Eu também poderia fazer LocalDate.parse(data, parser).getDayOfWeek()
para obter o DayOfWeeek
, mas se você só quer o dia da semana, não precisa criar um LocalDate
à toa.
E mudei o nome do método, pois getWeek
dá a impressão de que vai retornar toda a semana, mas você só quer um dia da semana, então deixei como getDayOfWeek
.
Outro detalhe é que no seu método você está capturando a exceção (ParseException
caso a data seja inválida), imprimindo o stack trace e depois retornando "---"
. Sem entrar no mérito de não estar tratando o erro, uma forma de ter o mesmo comportamento é:
public static String getDayOfWeek(String data) {
try {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
DayOfWeek dow = DayOfWeek.from(parser.parse(data));
return dow.getDisplayName(TextStyle.SHORT, new Locale("pt", "BR")).toUpperCase();
} catch (DateTimeException e) {
e.printStackTrace();
}
return "---";
}
System.out.println(getDayOfWeek("31/02/2017")); // ---
O ResolverStyle
, conforme explicado aqui, serve para garantir que datas como 29 de fevereiro em anos não-bissextos e 31 de abril sejam consideradas inválidas - tem uma explicação mais detalhada nesta resposta, na seção "Modos de parsing".
Mas este método não é muito eficiente, pois toda vez que for chamado, cria duas instâncias de DateTimeFormatter
: uma explicitamente, e outra implicitamente, dentro de getDisplayName
(veja no código fonte).
Sendo assim, uma alternativa é guardar essas instâncias em variáveis estáticas, assim eles são criados apenas uma vez:
public static DateTimeFormatter DOW_FMT = DateTimeFormatter.ofPattern("E", new Locale("pt", "BR"));
public static DateTimeFormatter PARSER = DateTimeFormatter.ofPattern("dd/MM/uuuu").withResolverStyle(ResolverStyle.STRICT);
public static String getDayOfWeek(String data) {
try {
return DOW_FMT.format(PARSER.parse(data)).toUpperCase();
} catch (DateTimeException e) {
e.printStackTrace();
}
return "---";
}
Repare que assim você nem precisa criar o DayOfWeek
, pois o resultado do parsing é passado diretamente para o formatador, que já pega o dia da semana e formata.
Se quiser continuar usando SimpleDateFormat
, há um detalhe importante: por padrão, esta classe aceita datas inválidas como "33/22/2017", fazendo alguns ajustes bem estranhos:
// 33/22/2017 vira 2 de novembro de 2018
System.out.println(new SimpleDateFormat("dd/MM/yyyy").parse("33/22/2017")); // Fri Nov 02 00:00:00 BRT 2018
Para evitar esse problema, basta setá-lo como não-leniente:
public static String getWeek(String date) { // ex 07/03/2017
String dayWeek = "---";
GregorianCalendar gc = new GregorianCalendar();
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
parser.setLenient(false); // <- setar como não-leniente, assim não aceita datas inválidas
try {
gc.setTime(parser.parse(date));
switch (gc.get(Calendar.DAY_OF_WEEK)) {
etc...
Uma outra resposta sugeriu usar DateFormatSymbols
, mas foi usado getWeekdays
, que retorna os nomes completos ("Domingo", "Segunda-feira", etc). Sem contar que se você criá-la sem especificar um Locale
, como foi sugerido, ela usará o default que está configurado na JVM (por exemplo, se a JVM estiver configurada com algum locale em inglês, serão retornados os nomes neste idioma - "Sunday", "Monday", etc).
Então se quiser usar aquela solução, você precisa especificar o locale para que use o português, e usar getShortWeekdays
para ter os nomes abreviados. E como esse array é fixo e será usado sempre que o método for chamado, pode criá-lo apenas uma vez também:
public static String[] WEEKDAYS = new DateFormatSymbols(new Locale("pt", "BR")).getShortWeekdays();
public static String getDayOfWeek(String data) {
try {
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
parser.setLenient(false);
Calendar cal = Calendar.getInstance();
cal.setTime(parser.parse(data));
return WEEKDAYS[cal.get(Calendar.DAY_OF_WEEK)].toUpperCase();
} catch (ParseException e) {
e.printStackTrace();
}
return "---";
}
Ou, se quiser otimizar mais ainda, já deixe o array com os nomes em maiúsculas, assim você não precisa chamar toUpperCase
:
public static String[] WEEKDAYS;
static {
WEEKDAYS = new DateFormatSymbols(new Locale("pt", "BR")).getShortWeekdays();
for (int i = 0; i < WEEKDAYS.length; i++) {
WEEKDAYS[i] = WEEKDAYS[i].toUpperCase();
}
}
public static String getDayOfWeek(String data) {
try {
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
parser.setLenient(false);
Calendar cal = Calendar.getInstance();
cal.setTime(parser.parse(data));
return WEEKDAYS[cal.get(Calendar.DAY_OF_WEEK)];
} catch (ParseException e) {
e.printStackTrace();
}
return "---";
}
E claro que também tem a opção de usar um array com os valores fixos:
public static String[] WEEKDAYS = {"DOM", "SEG", "TER", "QUA", "QUI", "SEX", "SAB"};
public static String getDayOfWeek(String data) {
try {
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
parser.setLenient(false);
Calendar cal = Calendar.getInstance();
cal.setTime(parser.parse(data));
return WEEKDAYS[cal.get(Calendar.DAY_OF_WEEK) - 1];
} catch (ParseException e) {
e.printStackTrace();
}
return "---";
}
O detalhe é que arrays começam do índice zero, mas os valores de DAY_OF_WEEK
vão de 1 a 7 (Domingo a Sábado), então preciso subtrair 1 para obter o valor correto (no caso de getShortWeekdays
não é necessário porque ele retorna um array cuja primeira posição é uma string vazia).
Answered by hkotsubo on November 30, 2021
Costumo usar o componente DateChooser na interface. O componente DateChooser retorna um java.util.Calendar. Com isso, você poderá usar métodos como estes:
public String diaDaSemana(Calendar calendar) {
return new DateFormatSymbols().getWeekdays()[calendar.get(Calendar.DAY_OF_WEEK)];
}
public String nomeDoMes(Calendar calendar) {
return new DateFormatSymbols().getMonths()[calendar.get(Calendar.MONTH)];
}
Answered by Hilton Cesar on November 30, 2021
A sua máscara está errada, como o Articuno respondeu.
Você também pode encurtar o seu código para:
public static String getWeek(String date){ //ex 07/03/2017
String dayWeek = "---";
GregorianCalendar gc = new GregorianCalendar();
try {
gc.setTime(new SimpleDateFormat("dd/MM/yyyy", new Locale("pt", "BR")).parse(date));
return new SimpleDateFormat("EEE", new Locale("pt", "BR")).format(gc.getTime()).toUpperCase();
} catch (ParseException e) {
e.printStackTrace();
}
return dayWeek;
}
Answered by mari on November 30, 2021
Sua máscara de formatação de data está errada. Você está usando o formato MM/dd/yyyy
quando sua string recebe um formato dd/MM/yyyy
. Apenas altere a máscara:
public static String getWeek(String date){ //ex 07/03/2017
String dayWeek = "---";
GregorianCalendar gc = new GregorianCalendar();
try {
gc.setTime(new SimpleDateFormat("dd/MM/yyyy").parse(date));
switch (gc.get(Calendar.DAY_OF_WEEK)) {
case Calendar.SUNDAY:
dayWeek = "DOM";
break;
case Calendar.MONDAY:
dayWeek = "SEG";
break;
case Calendar.TUESDAY:
dayWeek = "TER";
break;
case Calendar.WEDNESDAY:
dayWeek = "QUA";
break;
case Calendar.THURSDAY:
dayWeek = "QUI";
break;
case Calendar.FRIDAY:
dayWeek = "SEX";
break;
case Calendar.SATURDAY:
dayWeek = "SAB";
}
} catch (ParseException e) {
e.printStackTrace();
}
return dayWeek;
}
Bastou esta alteração e funcionou corretamente, veja: https://ideone.com/LLcvyr
Answered by user28595 on November 30, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP