0

In Java I can get the first day of the month by this way:

GregorianCalendar date;
// Some code
int first = new GregorianCalendar(date.get(Calendar.YEAR),
            date.get(Calendar.MONTH), 1).get(Calendar.DAY_OF_WEEK);

I'm wondering if there a function to do that directly, because I can't find a function that grabs this vital information.

Something similar to what I'm trying to do here:

 for (int i = 1; i < days_in_month + first; i++) {
     // Some code
     if (i - first + 1 == date.get(Calendar.DAY_OF_MONTH)) {
         // Do something
     }
 }
10
  • Why the first day of the month is an integer?? Commented Jan 17, 2018 at 20:19
  • 3
    To makes things clearer, you should explain what date variable is. It appears to be Calendar type, not a Date type. And mention whether you can use the newer java.time API or not, because if you can, you should.
    – Andreas
    Commented Jan 17, 2018 at 20:27
  • 2
    Just curious, why are you struggling with the old and long outdated GregorianCalendar class? java.time, the modern Java date and time API, is so much nicer to work with. On top of that, its LocalDate class makes your job simple: originalLocalDate.withDayOfMonth(1).getDayOfWeek().
    – Anonymous
    Commented Jan 18, 2018 at 5:44
  • 1
    Another quite similar question: Get first date of current month in java. Use your search engine to find still more. And next time please search before asking.
    – Anonymous
    Commented Jan 18, 2018 at 5:54
  • @OleV.V. I'm afraid that you didn't understand the question.
    – user6490462
    Commented Jan 18, 2018 at 12:28

3 Answers 3

4

You can convert GregorianCalendar object to the LocalDate object and use it's convenient API:

LocalDate getWithFirstDayOfMonth(GregorianCalendar c) {
    LocalDate date = c.toZonedDateTime().toLocalDate();
    return date.withDayOfMonth(1);
}

GregorianCalendar calendar = GregorianCalendar.from(ZonedDateTime.now());
LocalDate first = getWithFirstDayOfMonth(calendar);
System.out.println(first.getDayOfMonth());
1
  • 2
    c.getTime().toInstant().atZone(ZoneId.systemDefault()) is a very long-winded way of saying c.toZonedDateTime().
    – Andreas
    Commented Jan 17, 2018 at 20:57
1

Simply put, no. This is the correct way to get something like this.

This is literally the functionality they put in Java for making calculations like this possible. Any sort of "direct function" would simply do this internally (which I suggest you do.)

8
  • Pretty much short answer "NO".
    – user6490462
    Commented Jan 17, 2018 at 20:27
  • Right. However, if possible, consider using the java.time package recommended by logger (before he deleted his answer... someLocalDate.with(TemporalAdjusters.firstDayOfMonth()) might be better for you - but if you have to replace the entire date api in your app, it might not be worth it.
    – corsiKa
    Commented Jan 17, 2018 at 20:29
  • I'm preferring my current solution instead of the java.time API. Thanks.
    – user6490462
    Commented Jan 17, 2018 at 20:35
  • 2
    Strictly speaking this answer is incorrect. The function is there, in java.time, even a couple of functions for obtaining the same.
    – Anonymous
    Commented Jan 18, 2018 at 6:02
  • 2
    Thanks for your comment, @corsiKa. I’m fine with different interpretations of the question. :-) Only the OP can tell what he meant. He has said already that he prefers his current (very hard to read IMHO) solution. The answers are here for future readers too.
    – Anonymous
    Commented Jan 18, 2018 at 15:24
1

tl;dr

To get an integer number representing the day-of-week (1-7 for Monday-Sunday), for the first day of a moment’s year-month:

myGregCal                                        // Avoid troublesome legacy date-time classes such as `GregorianCalendar`.
    .toZonedDateTime()                           // Convert from legacy class to modern java.time class, a `ZonedDateTime` object.
    .toLocalDate()                               // Extract a date-only object.        
    .with( TemporalAdjusters.firstDayOfMonth() ) // Adjust into first day of the same year-month.
    .getDayOfWeek()                              // Extract a `DayOfWeek` enum object for Monday, Tuesday, etc. Consider using this object directly rather than taking the next step to extract a `int` number.
    .getValue()                                  // Extract an `int` integer number, 1-7 for Monday-Sunday.

… yields a number 1-7 for Monday-Sunday.

Tip: Better to skip the last step, and use DayOfWeek object instead of int:

myGregCal.toZonedDateTime().toLocalDate().with( TemporalAdjusters.firstDayOfMonth() ).getDayOfWeek()  // Render a `DayOfWeek` enum object.

java.time

The Answer by Oleksandr may be correct, and wins points for using the modern java.time classes rather than the legacy date-time classes. But there is a simpler take on such code. Also, the Question appears to want to go a step further, to get the day-of-week for the first-of-month.

Per the comment by Andreas, you could call GregorianCalendar::toZonedDateTime as a easy way to convert from the old legacy class GregorianCalendar to the modern ZonedDateTime class. The old classes gained new methods to facilitate converting between the legacy classes and the modern java.time classes.

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;  // Convert from legacy class to modern class.

From there extract a LocalDate object. The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate ld = zdt.toLocalDate() ;

Adjust the value to the first day of the same month. Use a TemporalAdjuster implementation found in the TemporalAdjusters class.

LocalDate firstOfMonth = ld.with( TemporalAdjusters.firstDayOfMonth() ) ;

Determine the day-of-week for that first-of-month date via a DayOfWeek enum object. That enum pre-defines 7 objects, one for each day of the week: MONDAY, TUESDAY, etc.

DayOfWeek dow = firstOfMonth.getDayOfWeek() ;

Consider using that DayOfWeek enum object instead of a mere clumsy int number to represent your day-of-week. Using objects rather than a int primitive makes your code more self-documenting, provides type-safety, and ensures valid values.

But if you insist, you may extract an int 1-7 for Monday-Sunday per the ISO 8601 standard.

int dowNumber = dow.getValue() ;

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, GregorianCalendar, & 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.

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.

1
  • Good answer. I still think (and I know you agree) that one should prefer to avoid using GregorianCalendar in the first place if possible.
    – Anonymous
    Commented Jan 20, 2018 at 9:47