From Java 8, you can use 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
I could also do LocalDate.parse(data, parser).getDayOfWeek()
to obtain the DayOfWeeek
, but if you just want the day of the week, you don’t have to create a LocalDate
for nothing.
And I changed the name of the method because getWeek
gives the impression that will return all week, but you just want a day of the week, so I left as getDayOfWeek
.
Another detail is that in your method you are capturing the exception (ParseException
if the date is invalid), by printing the stack trace and then returning "---"
. Without getting into the merit of not treating error, one way to have the same behavior is:
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")); // ---
The ResolverStyle
, as explained here, serves to ensure that dates such as February 29 in non-leap years and April 31 are considered invalid - has a more detailed explanation in this answer, in the section "Modes of Parsing".
But this method is not very efficient, because every time it is called, it creates two instances of DateTimeFormatter
: one explicitly, and another implicitly, within getDisplayName
(see in the source code).
Therefore, an alternative is to store these instances in static variables, so they are created only once:
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 "---";
}
Notice that so you don’t even have to create the DayOfWeek
, because the result of Parsing is passed directly to the formatter, who already takes the day of the week and formats.
If you want to keep using SimpleDateFormat
, there is one important detail: by default, this class accepts invalid dates like "33/22/2017", making some very strange adjustments:
// 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
To avoid this problem, just set it as nonlenient:
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...
One another answer suggested using DateFormatSymbols
, but it was used getWeekdays
, which returns the full names ("Sunday", "Monday", etc). Not to mention that if you create it without specifying a Locale
, as suggested, she will use the default that is configured in the JVM (for example, if the JVM is configured with some locale in English, names will be returned in this language - "Sunday", "Monday", etc).
So if you want to use that solution, you need to specify the locale to use Portuguese, and to use getShortWeekdays
to have the names abbreviated. And since this array is fixed and will be used whenever the method is called, you can create it only once as well:
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 "---";
}
Or, if you want to optimize further, leave the array with the names uppercase, so you don’t have to call 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 "---";
}
And of course you also have the option to use an array with the fixed values:
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 "---";
}
The detail is that arrays start from zero index, but the values of DAY_OF_WEEK
from 1 to 7 (Sunday to Saturday), so I need to subtract 1 to get the correct value (in the case of getShortWeekdays
is not needed because it returns an array whose first position is an empty string).
Interesting alternative, +1 :)
– user28595