tl;dr
Convert from terrible legacy classes (Calendar
, GregorianCalendar
, etc.) to modern java.time classes (ZonedDateTime
, LocalDate
, etc.). Then get object for day-of-week, and ask it to automatically localize the name of that day of the week.
(GregorianCalendar) myJavaUtilCalendar // Cast your `Calendar` to `GregorianCalendar` assuming it actually is one.
.toZonedDateTime() // Convert from legacy class to modern class.
.toLocalDate() // Extract date-only object, without time-of-day and without time zone.
.with( // Adjust to another date by calling `TemporalAdjuster` implementation such as are found in `TemporalAdjusters` class.
TemporalAdjusters.firstDayOfMonth() // Adjust to the first day of the month.
) // Returns another `LocalDate` object, for the first of the month.
.getDayOfWeek() // Obtain a `DayOfWeek` enum object, one of seven pre-defined objects representing each day of the week.
.getDisplayName( // Automatically localize.
TextStyle.FULL , // Specify how long or abbreviated.
Locale.CANADA_FRENCH // Or `Locale.US` etc. to specify the human language and cultural norms to use in localizing.
) // Returns text in a `String` such as “Monday” or “lundi”.
java.time
The java.util.Calendar/.Date and related classes are a confusing mess as you have learned the hard way.
The modern approach uses java.time classes.
Conversion
If starting with a java.util.Calendar object, convert to java.time.
An Instant
is a moment on the timeline in UTC.
Instant instant = myJavaUtilCalendarObject.toInstant();
Apply a time zone in order to get a date in order to get a day-of-week.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Note that a time zone is critical in determining a date (and therefore day-of-week). "Today" is not the same date everywhere in the world simultaneously. A new day dawns earlier, for example, in Paris than in Montréal.
First Day Of Month
Let's move to the first of the month by calling withDayOfMonth
.
ZonedDateTime zdtFirstOfMonth = zdt.withDayOfMonth(1);
Note that moving a date-time to first of month has issues. Anomalies such as Daylight Saving Time (DST) could have a surprising effect. Read the doc so you understand the behavior.
DayOfWeek
For day of week, use the well-named DayOfWeek
enum.
DayOfWeek dayOfWeek = zdtFirstOfMonth.getDayOfWeek();
I suggest passing instances of this enum rather than a magic number like 2
, 7
, etc. But if you insist, you can extract an integer.
int dayOfWeekNumber = dayOfWeek.getValue();
To get a String of the name of day-of-week, let java.time generate a localized String via the getDisplayName
method.
String output = dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.ENGLISH
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.