简体   繁体   中英

Same day prevous year (previous year, same week and day of week)

I want to retrieve same day previous year.

eg today is 2019-03-30 that is year 2019, week 26(week of year), day 7 (day of week).

I need to construct LocalDate which is year 2018, week 26(week of year), day 7 (day of week).

I could not find from java.time package which can built LocalDate like this.

It seems like you want the previous year date with same week of year and day of week as the given date. Below code with give you that result.

LocalDate currentLocalDate = LocalDate.now();
int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
LocalDate resultLocalDate = currentLocalDate
    .minusYears(1)
    .with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
    .with(ChronoField.DAY_OF_WEEK, dayOfWeek);

Full Example ( live copy ):

import java.time.*;
import java.time.format.*;
import java.time.temporal.*;

class Example
{
    private static void showDateInfo(LocalDate ld) {
        int weekOfYear = ld.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
        int dayOfWeek = ld.getDayOfWeek().getValue();
        System.out.println(ld.format(DateTimeFormatter.ISO_LOCAL_DATE) + " is week " + weekOfYear + ", day " + dayOfWeek);
    }
    public static void main (String[] args) throws java.lang.Exception
    {
        LocalDate currentLocalDate = LocalDate.of(2019, 6, 30);
        showDateInfo(currentLocalDate);
        int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
        int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
        LocalDate resultLocalDate = currentLocalDate
            .minusYears(1)
            .with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
            .with(ChronoField.DAY_OF_WEEK, dayOfWeek);
        showDateInfo(resultLocalDate);
    }
}

Output:

2019-06-30 is week 26, day 7
2018-07-01 is week 26, day 7

I believe that the other answers are close but not quite there yet. As far as I understand, you want to use the week scheme of the default locale, which the other answers don't do. My suggestion is:

    WeekFields wf = WeekFields.of(Locale.getDefault());
    LocalDate today = LocalDate.now(ZoneId.of("Africa/Casablanca"));
    int week = today.get(wf.weekOfYear());
    int dow = today.get(wf.dayOfWeek());
    System.out.println("Today is " + today + ", "
            + today.getDayOfWeek() + " of week " + week);

    LocalDate correspondingDayLastYear = today.minusYears(1)
            .with(wf.weekOfYear(), week)
            .with(wf.dayOfWeek(), dow);
    System.out.println("Last year was " + correspondingDayLastYear + ", "
            + correspondingDayLastYear.getDayOfWeek()
            + " of week " + correspondingDayLastYear.get(wf.weekOfYear()));

When running on my computer just now the output was:

 Today is 2019-06-30, SUNDAY of week 26 Last year was 2018-07-01, SUNDAY of week 26

When I set my locale to US I get the same date, but a different week number since American weeks are defined differently:

 Today is 2019-06-30, SUNDAY of week 27 Last year was 2018-07-01, SUNDAY of week 27

I believe that there will also be cases where different locales will give you different dates.

wf.dayOfWeek() gives you a field that numbers the days from 1 to 7 according to the first day of week in that particular locale. It's important not just to use withDayOfWeek or equivalent, or you would risk sliding into a different week if not using ISO weeks.

Still my answer will not work always! If today is within week 53 of the year, it may very well be that last year didn't have a week 53. Not much we can do about that. Another problem we can't solve: In American weeks week 1 starts on January 1. If this is a Sunday, it is the first day for the week, but then week 1 of the previous year started on a Friday or Saturday, so week 1 didn't have any Sunday.

If you're looking for an ISO week-year compatible function, this is working for me - so far =].

public class FiscalDateUtil {
    
    private static Logger log = LoggerFactory.getLogger(FiscalDateUtil.class);

    static public LocalDate previousYearComparisonDate(LocalDate date) {
    
        final int weekYear = date.get(IsoFields.WEEK_BASED_YEAR);
        final int weekLastYear = weekYear-1;
        
        final DayOfWeek dayOfWeek = date.getDayOfWeek();
        final int weekOfYear = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
        final LocalDate adjustedLastYear = date
                .with(IsoFields.WEEK_BASED_YEAR, weekLastYear)
                .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekOfYear)
                .with(TemporalAdjusters.nextOrSame(dayOfWeek));

        if (log.isTraceEnabled()) {
            log.trace("starting date {}", date.toString());
            log.trace("starting date dow {}", date.getDayOfWeek());
            log.trace("lastYear {}", weekLastYear);
            log.trace("lastYear dow {}", dayOfWeek);
            log.trace("adjustedLastYear {}", adjustedLastYear.toString());
            log.trace("adjustedLastYear dow {}", adjustedLastYear.getDayOfWeek());  
        }
        return adjustedLastYear;
    }

}

You can add the number of days since beginning of year of the current date to the beginning of the year before.

This should do the trick:

String dateStr = "2019-03-30";
LocalDate date = LocalDate.parse(dateStr);
LocalDate newDate = LocalDate.parse(date.getYear() + "-01-01").plusDays(date.getDayOfYear());
System.out.println(newDate);

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