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.util.Comparator; 035 036import org.threeten.bp.DateTimeException; 037import org.threeten.bp.Instant; 038import org.threeten.bp.LocalTime; 039import org.threeten.bp.ZoneId; 040import org.threeten.bp.ZoneOffset; 041import org.threeten.bp.ZonedDateTime; 042import org.threeten.bp.format.DateTimeFormatter; 043 044/** 045 * A date-time with a time-zone in an arbitrary chronology, 046 * intended for advanced globalization use cases. 047 * <p> 048 * <b>Most applications should declare method signatures, fields and variables 049 * as {@link ZonedDateTime}, not this interface.</b> 050 * <p> 051 * A {@code ChronoZonedDateTime} is the abstract representation of an offset date-time 052 * where the {@code Chrono chronology}, or calendar system, is pluggable. 053 * The date-time is defined in terms of fields expressed by {@link TemporalField}, 054 * where most common implementations are defined in {@link ChronoField}. 055 * The chronology defines how the calendar system operates and the meaning of 056 * the standard fields. 057 * 058 * <h4>When to use this interface</h4> 059 * The design of the API encourages the use of {@code ZonedDateTime} rather than this 060 * interface, even in the case where the application needs to deal with multiple 061 * calendar systems. The rationale for this is explored in detail in {@link ChronoLocalDate}. 062 * <p> 063 * Ensure that the discussion in {@code ChronoLocalDate} has been read and understood 064 * before using this interface. 065 * 066 * <h3>Specification for implementors</h3> 067 * This interface must be implemented with care to ensure other classes operate correctly. 068 * All implementations that can be instantiated must be final, immutable and thread-safe. 069 * Subclasses should be Serializable wherever possible. 070 * 071 * @param <C> the chronology of this date-time 072 */ 073public interface ChronoZonedDateTime<C extends Chrono<C>> 074 extends Temporal, Comparable<ChronoZonedDateTime<?>> { 075 076 /** 077 * Comparator for two {@code ChronoZonedDateTime} instances ignoring the chronology. 078 * <p> 079 * This method differs from the comparison in {@link #compareTo} in that it 080 * only compares the underlying date and not the chronology. 081 * This allows dates in different calendar systems to be compared based 082 * on the time-line position. 083 * 084 * @see #isAfter 085 * @see #isBefore 086 * @see #isEqual 087 */ 088 Comparator<ChronoZonedDateTime<?>> INSTANT_COMPARATOR = new Comparator<ChronoZonedDateTime<?>>() { 089 @Override 090 public int compare(ChronoZonedDateTime<?> datetime1, ChronoZonedDateTime<?> datetime2) { 091 int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); 092 if (cmp == 0) { 093 cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay()); 094 } 095 return cmp; 096 } 097 }; 098 099 /** 100 * Gets the local date part of this date-time. 101 * <p> 102 * This returns a local date with the same year, month and day 103 * as this date-time. 104 * 105 * @return the date part of this date-time, not null 106 */ 107 ChronoLocalDate<C> getDate() ; 108 109 /** 110 * Gets the local time part of this date-time. 111 * <p> 112 * This returns a local time with the same hour, minute, second and 113 * nanosecond as this date-time. 114 * 115 * @return the time part of this date-time, not null 116 */ 117 LocalTime getTime(); 118 119 /** 120 * Gets the local date-time part of this date-time. 121 * <p> 122 * This returns a local date with the same year, month and day 123 * as this date-time. 124 * 125 * @return the local date-time part of this date-time, not null 126 */ 127 ChronoLocalDateTime<C> getDateTime(); 128 129 /** 130 * Gets the zone offset, such as '+01:00'. 131 * <p> 132 * This is the offset of the local date-time from UTC/Greenwich. 133 * 134 * @return the zone offset, not null 135 */ 136 ZoneOffset getOffset(); 137 138 /** 139 * Gets the zone ID, such as 'Europe/Paris'. 140 * <p> 141 * This returns the stored time-zone id used to determine the time-zone rules. 142 * 143 * @return the zone ID, not null 144 */ 145 ZoneId getZone(); 146 147 //----------------------------------------------------------------------- 148 /** 149 * Returns a copy of this date-time changing the zone offset to the 150 * earlier of the two valid offsets at a local time-line overlap. 151 * <p> 152 * This method only has any effect when the local time-line overlaps, such as 153 * at an autumn daylight savings cutover. In this scenario, there are two 154 * valid offsets for the local date-time. Calling this method will return 155 * a zoned date-time with the earlier of the two selected. 156 * <p> 157 * If this method is called when it is not an overlap, {@code this} 158 * is returned. 159 * <p> 160 * This instance is immutable and unaffected by this method call. 161 * 162 * @return a {@code ZoneChronoDateTime} based on this date-time with the earlier offset, not null 163 * @throws DateTimeException if no rules can be found for the zone 164 * @throws DateTimeException if no rules are valid for this date-time 165 */ 166 ChronoZonedDateTime<C> withEarlierOffsetAtOverlap(); 167 168 /** 169 * Returns a copy of this date-time changing the zone offset to the 170 * later of the two valid offsets at a local time-line overlap. 171 * <p> 172 * This method only has any effect when the local time-line overlaps, such as 173 * at an autumn daylight savings cutover. In this scenario, there are two 174 * valid offsets for the local date-time. Calling this method will return 175 * a zoned date-time with the later of the two selected. 176 * <p> 177 * If this method is called when it is not an overlap, {@code this} 178 * is returned. 179 * <p> 180 * This instance is immutable and unaffected by this method call. 181 * 182 * @return a {@code ChronoZonedDateTime} based on this date-time with the later offset, not null 183 * @throws DateTimeException if no rules can be found for the zone 184 * @throws DateTimeException if no rules are valid for this date-time 185 */ 186 ChronoZonedDateTime<C> withLaterOffsetAtOverlap(); 187 188 //----------------------------------------------------------------------- 189 /** 190 * Returns a copy of this ZonedDateTime with a different time-zone, 191 * retaining the local date-time if possible. 192 * <p> 193 * This method changes the time-zone and retains the local date-time. 194 * The local date-time is only changed if it is invalid for the new zone. 195 * <p> 196 * To change the zone and adjust the local date-time, 197 * use {@link #withZoneSameInstant(ZoneId)}. 198 * <p> 199 * This instance is immutable and unaffected by this method call. 200 * 201 * @param zoneId the time-zone to change to, not null 202 * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null 203 */ 204 ChronoZonedDateTime<C> withZoneSameLocal(ZoneId zoneId); 205 206 /** 207 * Returns a copy of this date-time with a different time-zone, 208 * retaining the instant. 209 * <p> 210 * This method changes the time-zone and retains the instant. 211 * This normally results in a change to the local date-time. 212 * <p> 213 * This method is based on retaining the same instant, thus gaps and overlaps 214 * in the local time-line have no effect on the result. 215 * <p> 216 * To change the offset while keeping the local time, 217 * use {@link #withZoneSameLocal(ZoneId)}. 218 * 219 * @param zoneId the time-zone to change to, not null 220 * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null 221 * @throws DateTimeException if the result exceeds the supported date range 222 */ 223 ChronoZonedDateTime<C> withZoneSameInstant(ZoneId zoneId); 224 225 //------------------------------------------------------------------------- 226 // override for covariant return type 227 @Override 228 ChronoZonedDateTime<C> with(TemporalAdjuster adjuster); 229 230 @Override 231 ChronoZonedDateTime<C> with(TemporalField field, long newValue); 232 233 @Override 234 ChronoZonedDateTime<C> plus(TemporalAdder adjuster); 235 236 @Override 237 ChronoZonedDateTime<C> plus(long amountToAdd, TemporalUnit unit); 238 239 @Override 240 ChronoZonedDateTime<C> minus(TemporalSubtractor adjuster); 241 242 @Override 243 ChronoZonedDateTime<C> minus(long amountToSubtract, TemporalUnit unit); 244 245 //----------------------------------------------------------------------- 246 /** 247 * Converts this date-time to an {@code Instant}. 248 * <p> 249 * This combines the {@link #getDateTime() local date-time} and 250 * {@link #getOffset() offset} to form an {@code Instant}. 251 * 252 * @return an {@code Instant} representing the same instant, not null 253 */ 254 Instant toInstant(); 255 256 /** 257 * Converts this date-time to the number of seconds from the epoch 258 * of 1970-01-01T00:00:00Z. 259 * <p> 260 * This uses the {@link #getDateTime() local date-time} and 261 * {@link #getOffset() offset} to calculate the epoch-second value, 262 * which is the number of elapsed seconds from 1970-01-01T00:00:00Z. 263 * Instants on the time-line after the epoch are positive, earlier are negative. 264 * 265 * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z 266 */ 267 long toEpochSecond(); 268 269 //----------------------------------------------------------------------- 270 /** 271 * Compares this date-time to another date-time, including the chronology. 272 * <p> 273 * The comparison is based first on the instant, then on the local date-time, 274 * then on the zone ID, then on the chronology. 275 * It is "consistent with equals", as defined by {@link Comparable}. 276 * <p> 277 * If all the date-time objects being compared are in the same chronology, then the 278 * additional chronology stage is not required. 279 * 280 * @param other the other date-time to compare to, not null 281 * @return the comparator value, negative if less, positive if greater 282 */ 283 @Override 284 int compareTo(ChronoZonedDateTime<?> other); 285 286 //----------------------------------------------------------------------- 287 /** 288 * Checks if the instant of this date-time is before that of the specified date-time. 289 * <p> 290 * This method differs from the comparison in {@link #compareTo} in that it 291 * only compares the instant of the date-time. This is equivalent to using 292 * {@code dateTime1.toInstant().isBefore(dateTime2.toInstant());}. 293 * 294 * @param other the other date-time to compare to, not null 295 * @return true if this point is before the specified date-time 296 */ 297 boolean isBefore(ChronoZonedDateTime<?> other); 298 299 /** 300 * Checks if the instant of this date-time is after that of the specified date-time. 301 * <p> 302 * This method differs from the comparison in {@link #compareTo} in that it 303 * only compares the instant of the date-time. This is equivalent to using 304 * {@code dateTime1.toInstant().isAfter(dateTime2.toInstant());}. 305 * 306 * @param other the other date-time to compare to, not null 307 * @return true if this is after the specified date-time 308 */ 309 boolean isAfter(ChronoZonedDateTime<?> other); 310 311 /** 312 * Checks if the instant of this date-time is equal to that of the specified date-time. 313 * <p> 314 * This method differs from the comparison in {@link #compareTo} and {@link #equals} 315 * in that it only compares the instant of the date-time. This is equivalent to using 316 * {@code dateTime1.toInstant().equals(dateTime2.toInstant());}. 317 * 318 * @param other the other date-time to compare to, not null 319 * @return true if the instant equals the instant of the specified date-time 320 */ 321 boolean isEqual(ChronoZonedDateTime<?> other); 322 323 //----------------------------------------------------------------------- 324 /** 325 * Checks if this date-time is equal to another date-time. 326 * <p> 327 * The comparison is based on the offset date-time and the zone. 328 * To compare for the same instant on the time-line, use {@link #compareTo}. 329 * Only objects of type {@code ChronoZoneDateTime} are compared, other types return false. 330 * 331 * @param obj the object to check, null returns false 332 * @return true if this is equal to the other date-time 333 */ 334 @Override 335 boolean equals(Object obj); 336 337 /** 338 * A hash code for this date-time. 339 * 340 * @return a suitable hash code 341 */ 342 @Override 343 int hashCode(); 344 345 //----------------------------------------------------------------------- 346 /** 347 * Outputs this date-time as a {@code String}. 348 * <p> 349 * The output will include the full zoned date-time and the chronology ID. 350 * 351 * @return a string representation of this date-time, not null 352 */ 353 @Override 354 String toString(); 355 356 /** 357 * Outputs this date-time as a {@code String} using the formatter. 358 * 359 * @param formatter the formatter to use, not null 360 * @return the formatted date-time string, not null 361 * @throws DateTimeException if an error occurs during printing 362 */ 363 String toString(DateTimeFormatter formatter) ; 364 365}