简体   繁体   中英

Get first next Monday after certain date?

I know there is the same question here , but I have tried the answer provided and it returned an output that I don't understand. I am confused by the answer and I don't think the output is correct.

I need help, thank you :)

GregorianCalendar date1 = new GregorianCalendar( 2014, 05, 12 ); //05 is june as month start from 0 -11

while( date1.get( Calendar.DAY_OF_WEEK ) != Calendar.MONDAY )
    date1.add( Calendar.DATE, 1 );  

System.out.println(date1);

Here is the output:

java.util.GregorianCalendar[time=1405267200000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Singapore",offset=28800000,dstSavings=0,useDaylight=false,transitions=9,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=6,WEEK_OF_YEAR=29,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=195,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=28800000,DST_OFFSET=0]

Where on the output should I extract to retrieve Monday's date?

Java 8+

LocalDate ld = LocalDate.of(2014, Month.JUNE, 12);
System.out.println(ld);
ld = ld.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(ld);

Which prints...

2014-06-12
2014-06-16

Because it's possible that the date my actually be a Monday, you could also use...

ld = ld.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));

Java <= 7

You should be using the ThreeTen Backport , which gives you the support of the Java 8 Date/Time API

Original Answer

Instead of System.out.println(date1); use System.out.println(date1.getTime());

getTime returns an instance of Date which represents the current state of the Calendar

Which will output Mon Jul 14 00:00:00 EST 2014

System.out.println(date1) is the equivlent of using System.out.println(date1.toString()) , which, in this case, is dumping a bunch of useful info about the state of the Calendar object, but not really human readable data.

System.out.println(date1.getTime()) will use the Date 's to toString method to display a date value, formatted based on the current local settings, which will provide more useful information.

Updated

Instead of using GregorianCalendar , you should use the system Calendar , for example...

Calendar date1 = Calendar.getInstance();
date1.set(2014, 06, 12);

Also, months are 0 indexed, meaning that Janurary is actually 0 not 1 , so in your example, you've specified the month as July, not June.

So, instead, using...

Calendar date1 = Calendar.getInstance();
date1.set(2014, 05, 12);

while (date1.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
    date1.add(Calendar.DATE, 1);
}

System.out.println(date1.getTime());

Which outputted...

Mon Jun 16 16:22:26 EST 2014

Which is next Monday from today...more or less ;)

tl;dr

LocalDate.of( 2014 , Month.JUNE , 12 )                    // Represent a date-only value, without time-of-day and without time zone.
         .with(                                           // Move from one date to another by passing an implementation of the `TemporalAdjuster` interface. 
             TemporalAdjusters.next( DayOfWeek.MONDAY )   // Use an existing implementation found on utility class `TemporalAdjusters` (plural versus singular).
         )                                                // Returns another fresh `LocalDate` object rather than altering the original, per immutable objects design.

Using java.time

You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.

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

LocalDate ld = LocalDate.of( 2014 , Month.JUNE , 12 ) ;

To get the following Monday, use a TemporalAdjuster implementation found in TemporalAdjusters class.

LocalDate nextMonday = ld.with( TemporalAdjusters.next( DayOfWeek.MONDAY ) ) ;

If you want to go with the original date if it is itself a Monday, then use nextOrSame adjuster.

LocalDate nextOrSameMonday = ld.with( TemporalAdjusters.nextOrSame( DayOfWeek.MONDAY ) ) ;

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 .

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 .

A minor change to your code:

    GregorianCalendar date1 = new GregorianCalendar(2014, 6, 12);

    while (date1.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
        date1.add(Calendar.DATE, 1);
    }

    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    System.out.println(sdf.format(date1.getTime()));

Yields:

 14-07-2014

EDIT: As per the JavaDoc documentation, the constructor you are using, expects a 0 based month index, so for the month of June, you will need to pass in a value of 5, not 6.

Just a suggestion - Instead of looping, you could just use the switch statement along with the Calendar.add() like this:

int weekdayNum = c.get(Calendar.DAY_OF_WEEK);

    switch (weekdayNum) {
    case 1: {
        c.add(Calendar.DAY_OF_MONTH, 1);
        break;
    }
    case 3: {
        c.add(Calendar.DAY_OF_MONTH, 6);
        break;
    }
    case 4: {
        c.add(Calendar.DAY_OF_MONTH, 5);
        break;
    }
    case 5: {
        c.add(Calendar.DAY_OF_MONTH, 4);
        break;
    }
    case 6: {
        c.add(Calendar.DAY_OF_MONTH, 3);
        break;
    }
    case 7: {
        c.add(Calendar.DAY_OF_MONTH, 2);
        break;
    }
    default:
        break;
    }

Or Just do some simple math. Since Calender.Monday equals 2, it is easy to calculate the number of days that need to be added to the current date.

Calendar date1 = Calendar.getInstance();
date1.set(2014, 05, 12);
int dayOfWeek = date1.get(Calendar.DAY_OF_WEEK);
date1.add(Calendar.DATE, (9 - dayOfWeek) % 7);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM