001/* 002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos 003 * 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions are met: 008 * 009 * * Redistributions of source code must retain the above copyright notice, 010 * this list of conditions and the following disclaimer. 011 * 012 * * Redistributions in binary form must reproduce the above copyright notice, 013 * this list of conditions and the following disclaimer in the documentation 014 * and/or other materials provided with the distribution. 015 * 016 * * Neither the name of JSR-310 nor the names of its contributors 017 * may be used to endorse or promote products derived from this software 018 * without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 */ 032package org.threeten.bp.temporal; 033 034import java.io.Serializable; 035import java.util.Arrays; 036import java.util.List; 037import java.util.Locale; 038import java.util.Objects; 039 040import org.threeten.bp.Clock; 041import org.threeten.bp.DateTimeException; 042import org.threeten.bp.LocalDate; 043import org.threeten.bp.LocalDateTime; 044import org.threeten.bp.ZoneId; 045import org.threeten.bp.ZonedDateTime; 046 047/** 048 * The ISO calendar system. 049 * <p> 050 * This chronology defines the rules of the ISO calendar system. 051 * This calendar system is based on the ISO-8601 standard, which is the 052 * <i>de facto</i> world calendar. 053 * <p> 054 * The fields are defined as follows: 055 * <p><ul> 056 * <li>era - There are two eras, 'Current Era' (CE) and 'Before Current Era' (BCE). 057 * <li>year-of-era - The year-of-era is the same as the proleptic-year for the current CE era. 058 * For the BCE era before the ISO epoch the year increases from 1 upwards as time goes backwards. 059 * <li>proleptic-year - The proleptic year is the same as the year-of-era for the 060 * current era. For the previous era, years have zero, then negative values. 061 * <li>month-of-year - There are 12 months in an ISO year, numbered from 1 to 12. 062 * <li>day-of-month - There are between 28 and 31 days in each of the ISO month, numbered from 1 to 31. 063 * Months 4, 6, 9 and 11 have 30 days, Months 1, 3, 5, 7, 8, 10 and 12 have 31 days. 064 * Month 2 has 28 days, or 29 in a leap year. 065 * <li>day-of-year - There are 365 days in a standard ISO year and 366 in a leap year. 066 * The days are numbered from 1 to 365 or 1 to 366. 067 * <li>leap-year - Leap years occur every 4 years, except where the year is divisble by 100 and not divisble by 400. 068 * </ul><p> 069 * 070 * <h3>Specification for implementors</h3> 071 * This class is immutable and thread-safe. 072 */ 073public final class ISOChrono extends Chrono<ISOChrono> implements Serializable { 074 075 /** 076 * Singleton instance of the ISO chronology. 077 */ 078 public static final ISOChrono INSTANCE = new ISOChrono(); 079 /** 080 * The singleton instance for the era BCE - 'Before Current Era'. 081 * The 'ISO' part of the name emphasizes that this differs from the BCE 082 * era in the Gregorian calendar system. 083 * This has the numeric value of {@code 0}. 084 */ 085 public static final Era<ISOChrono> ERA_BCE = ISOEra.BCE; 086 /** 087 * The singleton instance for the era CE - 'Current Era'. 088 * The 'ISO' part of the name emphasizes that this differs from the CE 089 * era in the Gregorian calendar system. 090 * This has the numeric value of {@code 1}. 091 */ 092 public static final Era<ISOChrono> ERA_CE = ISOEra.CE; 093 094 /** 095 * Serialization version. 096 */ 097 private static final long serialVersionUID = -1440403870442975015L; 098 099 /** 100 * Restricted constructor. 101 */ 102 private ISOChrono() { 103 } 104 105 /** 106 * Resolve singleton. 107 * 108 * @return the singleton instance, not null 109 */ 110 private Object readResolve() { 111 return INSTANCE; 112 } 113 114 //----------------------------------------------------------------------- 115 /** 116 * Gets the ID of the chronology - 'ISO'. 117 * <p> 118 * The ID uniquely identifies the {@code Chrono}. 119 * It can be used to lookup the {@code Chrono} using {@link #of(String)}. 120 * 121 * @return the chronology ID - 'ISO' 122 * @see #getCalendarType() 123 */ 124 @Override 125 public String getId() { 126 return "ISO"; 127 } 128 129 /** 130 * Gets the calendar type of the underlying calendar system - 'iso8601'. 131 * <p> 132 * The calendar type is an identifier defined by the 133 * <em>Unicode Locale Data Markup Language (LDML)</em> specification. 134 * It can be used to lookup the {@code Chrono} using {@link #of(String)}. 135 * It can also be used as part of a locale, accessible via 136 * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'. 137 * 138 * @return the calendar system type - 'iso8601' 139 * @see #getId() 140 */ 141 @Override 142 public String getCalendarType() { 143 return "iso8601"; 144 } 145 146 //----------------------------------------------------------------------- 147 /** 148 * Obtains an ISO local date from the era, year-of-era, month-of-year 149 * and day-of-month fields. 150 * 151 * @param era the ISO era, not null 152 * @param yearOfEra the ISO year-of-era 153 * @param month the ISO month-of-year 154 * @param dayOfMonth the ISO day-of-month 155 * @return the ISO local date, not null 156 * @throws DateTimeException if unable to create the date 157 */ 158 @Override // override with covariant return type 159 public LocalDate date(Era<ISOChrono> era, int yearOfEra, int month, int dayOfMonth) { 160 return date(prolepticYear(era, yearOfEra), month, dayOfMonth); 161 } 162 163 /** 164 * Obtains an ISO local date from the proleptic-year, month-of-year 165 * and day-of-month fields. 166 * <p> 167 * This is equivalent to {@link LocalDate#of(int, int, int)}. 168 * 169 * @param prolepticYear the ISO proleptic-year 170 * @param month the ISO month-of-year 171 * @param dayOfMonth the ISO day-of-month 172 * @return the ISO local date, not null 173 * @throws DateTimeException if unable to create the date 174 */ 175 @Override // override with covariant return type 176 public LocalDate date(int prolepticYear, int month, int dayOfMonth) { 177 return LocalDate.of(prolepticYear, month, dayOfMonth); 178 } 179 180 /** 181 * Obtains an ISO local date from the era, year-of-era and day-of-year fields. 182 * 183 * @param era the ISO era, not null 184 * @param yearOfEra the ISO year-of-era 185 * @param dayOfYear the ISO day-of-year 186 * @return the ISO local date, not null 187 * @throws DateTimeException if unable to create the date 188 */ 189 @Override // override with covariant return type 190 public LocalDate dateYearDay(Era<ISOChrono> era, int yearOfEra, int dayOfYear) { 191 return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); 192 } 193 194 /** 195 * Obtains an ISO local date from the proleptic-year and day-of-year fields. 196 * <p> 197 * This is equivalent to {@link LocalDate#ofYearDay(int, int)}. 198 * 199 * @param prolepticYear the ISO proleptic-year 200 * @param dayOfYear the ISO day-of-year 201 * @return the ISO local date, not null 202 * @throws DateTimeException if unable to create the date 203 */ 204 @Override // override with covariant return type 205 public LocalDate dateYearDay(int prolepticYear, int dayOfYear) { 206 return LocalDate.ofYearDay(prolepticYear, dayOfYear); 207 } 208 209 //----------------------------------------------------------------------- 210 /** 211 * Obtains an ISO local date from another date-time object. 212 * <p> 213 * This is equivalent to {@link LocalDate#from(TemporalAccessor)}. 214 * 215 * @param temporal the date-time object to convert, not null 216 * @return the ISO local date, not null 217 * @throws DateTimeException if unable to create the date 218 */ 219 @Override // override with covariant return type 220 public LocalDate date(TemporalAccessor temporal) { 221 return LocalDate.from(temporal); 222 } 223 224 /** 225 * Obtains an ISO local date-time from another date-time object. 226 * <p> 227 * This is equivalent to {@link LocalDateTime#from(TemporalAccessor)}. 228 * 229 * @param temporal the date-time object to convert, not null 230 * @return the ISO local date-time, not null 231 * @throws DateTimeException if unable to create the date-time 232 */ 233 @Override // override with covariant return type 234 public LocalDateTime localDateTime(TemporalAccessor temporal) { 235 return LocalDateTime.from(temporal); 236 } 237 238 /** 239 * Obtains an ISO zoned date-time from another date-time object. 240 * <p> 241 * This is equivalent to {@link ZonedDateTime#from(TemporalAccessor)}. 242 * 243 * @param temporal the date-time object to convert, not null 244 * @return the ISO zoned date-time, not null 245 * @throws DateTimeException if unable to create the date-time 246 */ 247 @Override // override with covariant return type 248 public ZonedDateTime zonedDateTime(TemporalAccessor temporal) { 249 return ZonedDateTime.from(temporal); 250 } 251 252 //----------------------------------------------------------------------- 253 /** 254 * Obtains the current ISO local date from the system clock in the default time-zone. 255 * <p> 256 * This will query the {@link Clock#systemDefaultZone() system clock} in the default 257 * time-zone to obtain the current date. 258 * <p> 259 * Using this method will prevent the ability to use an alternate clock for testing 260 * because the clock is hard-coded. 261 * 262 * @return the current ISO local date using the system clock and default time-zone, not null 263 * @throws DateTimeException if unable to create the date 264 */ 265 @Override // override with covariant return type 266 public LocalDate dateNow() { 267 return dateNow(Clock.systemDefaultZone()); 268 } 269 270 /** 271 * Obtains the current ISO local date from the system clock in the specified time-zone. 272 * <p> 273 * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date. 274 * Specifying the time-zone avoids dependence on the default time-zone. 275 * <p> 276 * Using this method will prevent the ability to use an alternate clock for testing 277 * because the clock is hard-coded. 278 * 279 * @return the current ISO local date using the system clock, not null 280 * @throws DateTimeException if unable to create the date 281 */ 282 @Override // override with covariant return type 283 public LocalDate dateNow(ZoneId zone) { 284 return dateNow(Clock.system(zone)); 285 } 286 287 /** 288 * Obtains the current ISO local date from the specified clock. 289 * <p> 290 * This will query the specified clock to obtain the current date - today. 291 * Using this method allows the use of an alternate clock for testing. 292 * The alternate clock may be introduced using {@link Clock dependency injection}. 293 * 294 * @param clock the clock to use, not null 295 * @return the current ISO local date, not null 296 * @throws DateTimeException if unable to create the date 297 */ 298 @Override // override with covariant return type 299 public LocalDate dateNow(Clock clock) { 300 Objects.requireNonNull(clock, "clock"); 301 return date(LocalDate.now(clock)); 302 } 303 304 //----------------------------------------------------------------------- 305 /** 306 * Checks if the year is a leap year, according to the ISO proleptic 307 * calendar system rules. 308 * <p> 309 * This method applies the current rules for leap years across the whole time-line. 310 * In general, a year is a leap year if it is divisible by four without 311 * remainder. However, years divisible by 100, are not leap years, with 312 * the exception of years divisible by 400 which are. 313 * <p> 314 * For example, 1904 is a leap year it is divisible by 4. 315 * 1900 was not a leap year as it is divisible by 100, however 2000 was a 316 * leap year as it is divisible by 400. 317 * <p> 318 * The calculation is proleptic - applying the same rules into the far future and far past. 319 * This is historically inaccurate, but is correct for the ISO-8601 standard. 320 * 321 * @param prolepticYear the ISO proleptic year to check 322 * @return true if the year is leap, false otherwise 323 */ 324 @Override 325 public boolean isLeapYear(long prolepticYear) { 326 return ((prolepticYear & 3) == 0) && ((prolepticYear % 100) != 0 || (prolepticYear % 400) == 0); 327 } 328 329 @Override 330 public int prolepticYear(Era<ISOChrono> era, int yearOfEra) { 331 if (era instanceof ISOEra == false) { 332 throw new DateTimeException("Era must be ISOEra"); 333 } 334 return (era == ISOEra.CE ? yearOfEra : 1 - yearOfEra); 335 } 336 337 @Override 338 public Era<ISOChrono> eraOf(int eraValue) { 339 return ISOEra.of(eraValue); 340 } 341 342 @Override 343 public List<Era<ISOChrono>> eras() { 344 return Arrays.<Era<ISOChrono>>asList(ISOEra.values()); 345 } 346 347 //----------------------------------------------------------------------- 348 @Override 349 public ValueRange range(ChronoField field) { 350 return field.range(); 351 } 352 353}