Antonio Costa
Antonio Costa

Reputation: 313

Get the next date by specifying the day of week

I need to use calendar to do this approach, basicly i get the specific day of week (1,2,3) each int represents a day of week(Monday,Tuesday) not in this order, but the logic is this.

What i need is to get the date of the next day of week, imagine today is Monday, and the user select Wednsesday, i need to get the date of the next Wednesday.

My logic is this at the moment:

calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                calendar.set(Calendar.HOUR_OF_DAY, hour);
                calendar.set(Calendar.MINUTE, minute);
                dateMatch = calendar.getTime();

day of week is passed from a slidePicker, and represents the specific day of week, this DAY_OF_WEEK doesn't work, if i put Wednseday he gives me 6

Upvotes: 6

Views: 6754

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 340108

tl;dr

To get the next Wednesday after today, or stick with today’s date if already a Wednesday.

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    .with( TemporalAdjusters.nextOrSame( DayOfWeek.WEDNESDAY )  )

java.time

Use modern java.time classes that supplanted the troublesome old legacy date-time classes such as Calendar.

Use DayOfWeek enum objects to represent Monday-Sunday. Use smart objects rather than dumb integers to represent your day-of-week intention. Makes your code more self-documenting, ensures valid values, and provides type-safety.

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

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Use a TemporalAdjuster implementation such as TemporalAdjusters.nextOrSame to move to another date.

TemporalAdjuster ta = TemporalAdjusters.nextOrSame( DayOfWeek.WEDNESDAY ) ;
LocalDate nextOrSameWednesday = today.with( ta ) ;

If working with moments, use ZonedDateTime class rather than the awful Calendar class. Some idea as above, let the TemporalAdjuster do the heavy-lifting. But keep in mind that the time-of-day may be altered if that time-of-day is invalid for that new date such as during a Daylight Saving Time (DST) cut-over.

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
TemporalAdjuster ta = TemporalAdjusters.nextOrSame( DayOfWeek.WEDNESDAY ) ;
ZonedDateTime zdtSameOrNextWednesday = zdt.with( ta ) ;

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.

Upvotes: 8

Andreas
Andreas

Reputation: 159215

Although your question text only says to find next dayOfWeek, your code also includes a time of day, in the form of hour and minute.

Assuming you want the first future occurrence of that combination, i.e. dayOfWeek, hour, and minute, that means that if today is that dayOfWeek, you either want today if time of day is later than now, or next week if time of day is earlier than now.

You can do that like this:

int dayOfWeek = Calendar.WEDNESDAY;
int hour      = 10; // 10 AM
int minute    = 0;

Calendar cal = Calendar.getInstance(); // Today, now
if (cal.get(Calendar.DAY_OF_WEEK) != dayOfWeek) {
    cal.add(Calendar.DAY_OF_MONTH, (dayOfWeek + 7 - cal.get(Calendar.DAY_OF_WEEK)) % 7);
} else {
    int minOfDay = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE);
    if (minOfDay >= hour * 60 + minute)
        cal.add(Calendar.DAY_OF_MONTH, 7); // Bump to next week
}
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

System.out.println(cal.getTime()); // Prints: Wed May 10 10:00:00 EDT 2017

Upvotes: 6

Related Questions