tl;dr
ZonedDateTime.now() // Capture the current moment as seen through the lens of the wall-clock time used by the people of a particular region (time zone).
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) // Get the week number, with stable results per the ISO 8601 definition of a week that starts on a Monday and considers week # 1 to have the first Thursday of the calendar-year.
Locale
In the Calendar
class, the meaning of a “week” changes by locale. If at runtime the JVM’s current default Locale
differs, the result of calculating weeks may differ.
For example, in the United States the first day of a week is Sunday. But in much of Europe, and by ISO 8601 standard, the first day of the week is Monday.
That Calendar
class is troublesome and confusing. And fortunately, now legacy, supplanted by the industry-leading java.time classes.
java.time
Capture the current moment in UTC.
Instant instant = Instant.now() ;
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.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
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" ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Apply that ZoneId
to get a ZonedDateTime
object.
ZonedDateTime zdt = instant.atZone( z ) ;
Now get interrogate for the week-based year and week. The IsoFields
class provides objects through which we can get the week numbers per the ISO 8601 standard:
- Week # 1 holds the first Thursday of the calendar-year
- Monday is the first day of the year
- A year has either 52 or 53 weeks.
- The last/first few days of a year may lie in the previous/next week-based year.
Example.
int yearIso = zdt.get( IsoFields.WEEK_BASED_YEAR ) ;
int weekIso = zdt.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
TIP: Consider adding the ThreeTen-Extra library to your project to gain access to the YearWeek
class.
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.