Get the week start and end date given a current date and week start

后端 未结 4 1995
无人及你
无人及你 2020-11-27 08:59

If possible I would prefer a joda or non-joda solution for the scenario below

Lets say if my week starts on 02/05/2012 and the given current date is 02/22/2011. I ne

相关标签:
4条回答
  • 2020-11-27 09:11

    Try this (pseudo-code):

    // How many days gone after reference date (a known week-start date)
    daysGone  = today - referenceDate;
    
    // A new week starts after each 7 days
    dayOfWeek = daysGone % 7;
    
    // Now, we know today is which day of the week.
    // We can find start & end days of this week with ease
    weekStart = today - dayOfWeek;
    weekEnd   = weekStart + 6;
    

    Now, we can shorten all of this to two lines:

    weekStart = today - ((today - referenceDate) % 7);
    weekEnd   = weekStart + 6;
    

    Note that we subtracted date values like integers to show algorithm. You have to write your java code properly.

    0 讨论(0)
  • 2020-11-27 09:16
     DateTime sDateTime = new DateTime(startDate); // My calendar start date
     DateTime eDateTime = new DateTime(date); // the date for the week to be determined
    
     Interval interval = new Interval(sDateTime, sDateTime.plusWeeks(1));
     while(!interval.contains(eDateTime))
     {
        interval = new Interval(interval.getEnd(), interval.getEnd().plusWeeks(1));
     }
     return interval;
    
    0 讨论(0)
  • 2020-11-27 09:23

    Defining A Week

    If you are using date-time objects, you should define a week as up to but not including the first moment of the day after the end of week. As seen in this diagram.

    Timeline showing ( >= start of day 1 ) and ( < start of day 8 )

    This approach is known as Half-Open. This approach is commonly used for working with spans of time.

    The reason is because, logically, that last moment of the day before the new day is infinitely divisible as a fraction of a second. You may think that using ".999" would handle that for milliseconds, but then you'd mistaken when writing for the new java.time.* classes in Java 8 that have nanosecond resolution rather than millisecond. You may think think that using ".999999999" would handle that case, but then you’d be mistaken when handling date-time values from many databases such as Postgres that use microsecond resolution, ".999999".

    In the third-party open-source Joda-Time library, this Half-Open logic is how its Interval class works. The beginning is inclusive and the ending is exclusive. This works out nicely. Similarly, calling plusWeeks(1) on a DateTime to add a week to the first moment of a day gives you the first moment of the 8th day later (see example below).

    Time Zone

    The question and other answers ignores the issue of time zone. If you do not specify, you'll be getting the default time zone. Usually better to specify a time zone, using a proper time zone name (not 3-letter code).

    Joda-Time

    Avoid the java.util.Date & Calendar classes bundled with Java. They are notoriously troublesome.

    Here is some example code using Joda-Time 2.3.

    CAVEAT: I have not tested of of the below code thoroughly. Just my first take, a rough draft. May well be flawed.

    Standard Week (Monday-Sunday)

    The Joda-Time library is built around the ISO 8601 standard. That standard defines the first day of the week as Monday, last day as Sunday.

    If that meets your definition of a week, then getting the beginning and ending is easy.

    UPDATE As an alternative to the discussion below, see this very clever and very simple one-liner solution by SpaceTrucker.

    Simply forcing the day-of-week works because Joda-Time assumes you want:

    • Monday to be before (or same as) today.
    • Sunday to be after (or same as) today.
    DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
    DateTime now = new DateTime( timeZone );
    
    DateTime weekStart = now.withDayOfWeek( DateTimeConstants.MONDAY ).withTimeAtStartOfDay();
    DateTime weekEnd = now.withDayOfWeek(DateTimeConstants.SUNDAY).plusDays( 1 ).withTimeAtStartOfDay();
    Interval week = new Interval( weekStart, weekEnd );
    

    Dump to console…

    System.out.println( "now: " + now );
    System.out.println( "weekStart: " + weekStart );
    System.out.println( "weekEnd: " + weekEnd );
    System.out.println( "week: " + week );
    

    When run…

    now: 2014-01-24T06:29:23.043+01:00
    weekStart: 2014-01-20T00:00:00.000+01:00
    weekEnd: 2014-01-27T00:00:00.000+01:00
    week: 2014-01-20T00:00:00.000+01:00/2014-01-27T00:00:00.000+01:00
    

    To see if a date-time lands inside that interval, call the contains method.

    boolean weekContainsDate = week.contains( now );
    

    Non-Standard Week

    If that does not meet your definition of a week, you a twist on that code.

    DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
    DateTime now = new DateTime( timeZone );
    
    DateTime weekStart = now.withDayOfWeek( DateTimeConstants.SUNDAY ).withTimeAtStartOfDay();
    if ( now.isBefore( weekStart )) {
        // If we got next Sunday, go back one week to last Sunday.
        weekStart = weekStart.minusWeeks( 1 );
    }
    DateTime weekEnd = weekStart.plusWeeks( 1 );
    Interval week = new Interval( weekStart, weekEnd );
    

    Dump to console…

    System.out.println( "now: " + now );
    System.out.println( "weekStart: " + weekStart );
    System.out.println( "weekEnd: " + weekEnd );
    System.out.println( "week: " + week );
    

    When run…

    now: 2014-01-24T00:54:27.092-05:00
    weekStart: 2014-01-19T00:00:00.000-05:00
    weekEnd: 2014-01-26T00:00:00.000-05:00
    week: 2014-01-19T00:00:00.000-05:00/2014-01-26T00:00:00.000-05:00
    
    0 讨论(0)
  • 2020-11-27 09:28

    First day of week depends on the country. What makes the calculation fragile, is that one may break the year boundary, and the week number (Calendar.WEEK_OF_YEAR). The following would do:

        Calendar currentDate = Calendar.getInstance(Locale.US);
        int firstDayOfWeek = currentDate.getFirstDayOfWeek();
    
        Calendar startDate = Calendar.getInstance(Locale.US);
        startDate.setTime(currentDate.getTime());
        //while (startDate.get(Calendar.DAY_OF_WEEK) != firstDayOfWeek) {
        //    startDate.add(Calendar.DATE, -1);
        //}
        int days = (startDate.get(Calendar.DAY_OF_WEEK) + 7 - firstDayOfWeek) % 7;
        startDate.add(Calendar.DATE, -days);
    
        Calendar endDate = Calendar.getInstance(Locale.US);
        endDate.setTime(startDate.getTime());
        endDate.add(Calendar.DATE, 6);
    

    One bug in Calendar breaks your code, clone, seems to simply give the identical object, hence at the end you have identical dates. (Java 7 at least).

    0 讨论(0)
提交回复
热议问题