Week view in Java 8 Time API

I would like the class to represent a specific week of the year - for example, today is November 29, which is exactly week number 48 of the year 2014. Thus, one example implementation would be the following:

import java.time.Year; public class WorkingWeek { private int weekNumber; private Year year; } 

Another concept is to have only a Monday week in the WorkingWeek class, but I feel this is less intuitive and I will often use the number per year.

Is there a class in the Java 8 Time API that meets my requirements? Or, if not, what would be recommended?

+5
source share
3 answers

You need to indicate your definition of the week.

Year-week string representation

One option is strings. ISO 8601 defines a week from Monday to Sunday, with the first week of the year being the first to contain Thursday, resulting in 52 or 53 weeks per year.

The standard also defines the line presentation for this weekly period in the format YYYY-Www (or omitting hypen, YYYYWww ), for example 2014-W07 . The day during the week is represented by the number, where Monday is 1 and Sunday is 7, in the format YYYY-Www-D (or omitting the hyphen, YYYYWwwD ), for example, 2014-W07-2 (Tuesday on the 7th week of the year). W is important to disambiguate the year, for example, 2014-07 , which is July 2014.


Joda time

The Joda-Time library offers Interval to represent a time span as a pair of specific moments in time on the timeline of the Universe. Every moment is represented by the DateTime class.

Half open

Joda-Time uses the Half-Open [) method to determine time intervals. The beginning is included, while the ending is exclusive. This is usually the best way to work at such intervals. Find StackOverflow for many examples and discussions.

ISO 8601 at Joda-Time

Joda-Time uses the definition of weekly ISO 8601 values. In addition, Joda-Time uses ISO 8601 as the default parameters for parsing and generating string representations of date and time values.

 DateTimeZone zone = DateTimeZone( "America/Montreal" ); // Get first moment of a Monday. Inclusive. DateTime start = new DateTime( 2014, 11, 24, 0, 0, 0, zone ); // Handle exception thrown if occurring during a Daylight Saving Time gap. DateTime stop = start.plusWeeks( 1 ); // First moment of following Monday. Exclusive. Interval week = new Interval ( start, stop ); 

First monday

Search StackOverflow for many questions and answers on finding the first Monday of the week.

LocalDate (date only)

While you might be tempted to use LocalDate objects (only date, not time of day) to build Interval . That would be reasonable and helpful. Unfortunately, the Interval implementation only supports DateTime objects, not LocalDate .


java.time

The java.time package, built into Java 8 and later, is inspired by Joda-Time, but completely redesigned. See Tutorial .

In java.time, Instant is a moment on the timeline in UTC. Apply the time zone ( ZoneId ) to get the ZonedDateTime . Use LocalDate to get the value only for a date with no time of day and no time zone.

Note that defining the first moment of the day in java.time requires an extra step compared to Joda-Time: we must go through the LocalDate class to call its atStartOfDay method.

 ZoneId zoneId = ZoneId.of ( "America/Montreal" ); ZonedDateTime now = ZonedDateTime.now ( zoneId ); LocalDate firstDayOfThisWeek = now.toLocalDate ().with ( DayOfWeek.MONDAY ); LocalDate firstDayOfNextWeek = firstDayOfThisWeek.plusWeeks ( 1 ); ZonedDateTime thisWeekStart = firstDayOfThisWeek.atStartOfDay ( zoneId ); ZonedDateTime nextWeekStart = firstDayOfNextWeek.atStartOfDay ( zoneId ); 

Unfortunately, java.time does not have the equivalent of Joda-Time Interval .

Fortunately, we are ThreeTen Extra , a project extending java.time (310, which is the JSR number that defines java.time ). This library includes the Interval class, which integrates with java.time. This Interval class is more limited than Joda-Time, since it only supports Instant objects without time zones (always in UTC).

Note: the ThreeTen-Extra project reserves the right to change its interfaces and / or implementations. Although it is intended to be used as is, it also serves as an experimental proving ground for classes that can subsequently be included in java.time. I am happy to use ThreeTen-Extra, but you have to make your own risk decision.

 // This next line requires adding the `ThreeTen Extra` library to your project. Interval interval = Interval.of ( thisWeekStart.toInstant () , nextWeekStart.toInstant () ); // "Interval" is part of ThreeTen-Extra project, not built into Java 8. 

Dump for the console.

 System.out.println ( "now: " + now + " thisWeekStart: " + thisWeekStart + " nextWeekStart: " + nextWeekStart + " interval: " + interval ); 

Now: 2016-01-15T18: 10: 48.143-05: 00 [America / Montreal] thisWeekStart: 2016-01-11T00: 00-05: 00 [America / Montreal] nextWeekStart: 2016-01-18T00: 00 -05: 00 [America / Montreal] interval: 2016-01-11T05: 00: 00Z / 2016-01-18T05: 00: 00Z

You can define the week of the week as defined by ISO 8601. Note the "weekly" conditions. At the beginning or end of the year, the date will be within one calendar year, and its ISO 8601 week may be ± 1.

 ZoneId zoneId = ZoneId.of ( "America/Montreal" ); ZonedDateTime now = ZonedDateTime.now ( zoneId ); int weekOfYear = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR ); int weekBasedYear = now.get ( IsoFields.WEEK_BASED_YEAR ); System.out.println ( "weekOfYear: " + weekOfYear + " of weekBasedYear: " + weekBasedYear ); 

weekOfYear: 2 weeksBase year: 2016

+10
source

YearWeek Class

The ThreeTen-Extra project has a class for YearQuarter . The initial question looks like it is requesting the YearWeek class. Work has been done to add such a class to ThreeTen-Extra.

+4
source

Another possibility is to use the CalendarWeek class in my Time4J library. Example:

 CalendarWeek now = SystemClock.inLocalView().now(CalendarWeek.chronology()); int actual = now.getWeek(); // 35 on 2016-08-29 int max = now.getMaximum(CalendarWeek.WEEK_OF_YEAR); // 52 in year 2016 

This class is also modeled as a date range and can be converted to a common DateInterval (Monday through Sunday), offering stream support through its toFlexInterval() method.

+1
source

Source: https://habr.com/ru/post/1207942/


All Articles