java calendar - get last 5 days of week (without w

2019-07-26 01:35发布

问题:

I'm working with some issue.

I need to get some data from database

1) get 5 records from 5 last days (one record per one day), but the days must be the days of a week (now a weekend)

2) get 20 records from the month (current or past, one record per one day)

I'm fighting with Java Calendar, but still i have no idea, how to get the dates.

Could anybody help me?

回答1:

Should work:

private Calendar workingDaysBack(final Calendar from, final int count) {
    for (int daysBack = 0; daysBack < count; ++daysBack) {
        do {
            from.add(Calendar.DAY_OF_YEAR, -1);
        } while(isWeekend(from));
    }
    return from;
}

private boolean isWeekend(Calendar cal) {
    return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
           cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
}


回答2:

You can do first part by just tweaking the day of the week parameter through each day you want to consider. Depends on what behaviour you want if running during weeks - should be current week, or last complete week? Here I've assumed current week...

Calendar cal = Calendar.getInstance();

List<Date> last5Days = new LinkedList<Date>();
List<Integer> weekDays = Arrays.asList(Calendar.MONDAY,
        Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY,
        Calendar.FRIDAY);
for (int weekDay : weekDays) {
    cal.set(Calendar.DAY_OF_WEEK, weekDay);
    last5Days.add(cal.getTime());
}
System.out.println(last5Days);

20 week days from current month. Depends what behaviour you want on weeks than span month boundaries. Here I've gone forward to first Monday, and then add on from there.

List<Date> last20Days = new LinkedList<Date>();
// find first Monday in the month
for (int i = 1; i <= 31; i++) {
    cal.set(Calendar.DAY_OF_MONTH, i);
    if (cal.get(Calendar.DAY_OF_WEEK) == weekDays.get(0)) {
        break;
    }
}
for (int i = 1; i <= 31; i++) {
    if (last20Days.size() == 20) {
        break;
    }
    if (weekDays.contains(cal.get(Calendar.DAY_OF_WEEK))) {
        last20Days.add(cal.getTime());
    }
    cal.add(Calendar.DAY_OF_MONTH, 1);
}
System.out.println(last20Days);


回答3:

tl;dr

myLocalDate.with( 
    org.threeten.extra.Temporals.previousWorkingDay() 
)

Using java.time

The other Answers use troublesome old date-time classes such as Calendar than are now legacy, supplanted by the java.time classes.

To get the last five days, you first need to get “today”.

LocalDate

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.

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 );

DayOfWeek

To get previous days, you can call minusDays to move incrementally through dates in the past.

LocalDate yesterday = today.minusDays( 1 );
LocalDate dayBeforeYesterday = yesterday.minusDays( 1 );

You can test each LocalDate object for its day-of-week by using the DayOfWeek enum. That class predefines seven objects, one for each day of the week. Note that these are real objects, not mere strings. No need to use strings at all here.

Boolean isSaturday = myLocalDate.getDayOfWeek().equals( DayOfWeek.SATURDAY );
Boolean isSunday = myLocalDate.getDayOfWeek().equals( DayOfWeek.SUNDAY );

EnumSet

A slicker and more flexible way of doing that comparison is with an EnumSet, an implementation of Set optimized for enums that is extremely fast to execute and uses very little memory.

EnumSet<DayOfWeek> weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );

Use contains to test your LocalDate object’s DayOfWeek.

Boolean isWeekend = weekend.contains( myLocalDate.getDayOfWeek() );

ThreeTen-Extra TemporalAdjuster previousWorkingDay()

The ThreeTen-Extra project extends the java.time classes with additional functionality. In particular here, we could use its previousWorkingDay implementation of the TemporalAdjuster interface.

This adjuster is hard-coded to skip over Saturday and Sunday. If you want other day-of-week values to be considered, you can write your own implementation of TemporalAdjuster.

The java.time classes use immutable objects. So rather than change the values (“mutate”) on an object, we generate a fresh object with values based on the original. So here we call LocalDate::with, pass a TemporalAdjuster, and generate a fresh LocalDate that represents a prior date while skipping over Saturday/Sunday.

LocalDate previousWorkingDay = 
    myLocalDate.with( 
        org.threeten.extra.Temporals.previousWorkingDay() 
    ) 
;

Full example

So let's put this all together.

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

Integer countDaysPrior = 5;
List<LocalDate> priorWeekdays = new ArrayList<> ( countDaysPrior ); // Set initial capacity to number of days to be collected.
LocalDate localDate = today; // Initialize to today. Exclusive, we want only prior days.
for ( int i = 1 ; i <= countDaysPrior ; i ++ ) {
    localDate = localDate.with ( org.threeten.extra.Temporals.previousWorkingDay () );  // Decrement each day into the past, skipping over Saturday/Sunday.
    priorWeekdays.add ( localDate );
}

System.out.println ( "Weekdays prior to " + today + " are: " + priorWeekdays );

Weekdays prior to 2017-02-27 are: [2017-02-24, 2017-02-23, 2017-02-22, 2017-02-21, 2017-02-20]

I suppose you could make that code even shorter using Lambdas and Streams.


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?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.



回答4:

Just a kick start

Calendar cal = Calendar.getInstance();//initilized with current date & time
Date date = cal.getTime();//returned the current date & time that cal holds
boolean isMonday = Calendar.MONDAY == cal.get(Calendar.DAY_OF_WEEK);//it will return an integer 

See API Doc for more



标签: java calendar