1 /*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
358 * @param minutes the time-zone offset in minutes, from 0 to ±59
359 * @param seconds the time-zone offset in seconds, from 0 to ±59
360 * @throws DateTimeException if the offset is not in the required range
361 */
362 private static void validate(int hours, int minutes, int seconds) {
363 if (hours < -18 || hours > 18) {
364 throw new DateTimeException("Zone offset hours not in valid range: value " + hours +
365 " is not in the range -18 to 18");
366 }
367 if (hours > 0) {
368 if (minutes < 0 || seconds < 0) {
369 throw new DateTimeException("Zone offset minutes and seconds must be positive because hours is positive");
370 }
371 } else if (hours < 0) {
372 if (minutes > 0 || seconds > 0) {
373 throw new DateTimeException("Zone offset minutes and seconds must be negative because hours is negative");
374 }
375 } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
376 throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
377 }
378 if (Math.abs(minutes) > 59) {
379 throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " +
380 Math.abs(minutes) + " is not in the range 0 to 59");
381 }
382 if (Math.abs(seconds) > 59) {
383 throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " +
384 Math.abs(seconds) + " is not in the range 0 to 59");
385 }
386 if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
387 throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
388 }
389 }
390
391 /**
392 * Calculates the total offset in seconds.
393 *
394 * @param hours the time-zone offset in hours, from -18 to +18
395 * @param minutes the time-zone offset in minutes, from 0 to ±59, sign matches hours and seconds
396 * @param seconds the time-zone offset in seconds, from 0 to ±59, sign matches hours and minutes
397 * @return the total in seconds
398 */
399 private static int totalSeconds(int hours, int minutes, int seconds) {
400 return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
401 }
402
403 //-----------------------------------------------------------------------
404 /**
405 * Obtains an instance of {@code ZoneOffset} specifying the total offset in seconds
406 * <p>
407 * The offset must be in the range {@code -18:00} to {@code +18:00}, which corresponds to -64800 to +64800.
408 *
409 * @param totalSeconds the total time-zone offset in seconds, from -64800 to +64800
410 * @return the ZoneOffset, not null
411 * @throws DateTimeException if the offset is not in the required range
412 */
413 public static ZoneOffset ofTotalSeconds(int totalSeconds) {
414 if (Math.abs(totalSeconds) > MAX_SECONDS) {
415 throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
416 }
417 if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
418 Integer totalSecs = totalSeconds;
419 ZoneOffset result = SECONDS_CACHE.get(totalSecs);
420 if (result == null) {
421 result = new ZoneOffset(totalSeconds);
422 SECONDS_CACHE.putIfAbsent(totalSecs, result);
423 result = SECONDS_CACHE.get(totalSecs);
424 ID_CACHE.putIfAbsent(result.getId(), result);
425 }
426 return result;
427 } else {
428 return new ZoneOffset(totalSeconds);
429 }
430 }
431
432 //-----------------------------------------------------------------------
433 /**
434 * Constructor.
679 * @return the adjusted object, not null
680 * @throws DateTimeException if unable to make the adjustment
681 * @throws ArithmeticException if numeric overflow occurs
682 */
683 @Override
684 public Temporal adjustInto(Temporal temporal) {
685 return temporal.with(OFFSET_SECONDS, totalSeconds);
686 }
687
688 //-----------------------------------------------------------------------
689 /**
690 * Compares this offset to another offset in descending order.
691 * <p>
692 * The offsets are compared in the order that they occur for the same time
693 * of day around the world. Thus, an offset of {@code +10:00} comes before an
694 * offset of {@code +09:00} and so on down to {@code -18:00}.
695 * <p>
696 * The comparison is "consistent with equals", as defined by {@link Comparable}.
697 *
698 * @param other the other date to compare to, not null
699 * @return the comparator value, negative if less, postive if greater
700 * @throws NullPointerException if {@code other} is null
701 */
702 @Override
703 public int compareTo(ZoneOffset other) {
704 return other.totalSeconds - totalSeconds;
705 }
706
707 //-----------------------------------------------------------------------
708 /**
709 * Checks if this offset is equal to another offset.
710 * <p>
711 * The comparison is based on the amount of the offset in seconds.
712 * This is equivalent to a comparison by ID.
713 *
714 * @param obj the object to check, null returns false
715 * @return true if this is equal to the other offset
716 */
717 @Override
718 public boolean equals(Object obj) {
719 if (this == obj) {
720 return true;
721 }
722 if (obj instanceof ZoneOffset) {
723 return totalSeconds == ((ZoneOffset) obj).totalSeconds;
724 }
|
1 /*
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
358 * @param minutes the time-zone offset in minutes, from 0 to ±59
359 * @param seconds the time-zone offset in seconds, from 0 to ±59
360 * @throws DateTimeException if the offset is not in the required range
361 */
362 private static void validate(int hours, int minutes, int seconds) {
363 if (hours < -18 || hours > 18) {
364 throw new DateTimeException("Zone offset hours not in valid range: value " + hours +
365 " is not in the range -18 to 18");
366 }
367 if (hours > 0) {
368 if (minutes < 0 || seconds < 0) {
369 throw new DateTimeException("Zone offset minutes and seconds must be positive because hours is positive");
370 }
371 } else if (hours < 0) {
372 if (minutes > 0 || seconds > 0) {
373 throw new DateTimeException("Zone offset minutes and seconds must be negative because hours is negative");
374 }
375 } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
376 throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
377 }
378 if (minutes < -59 || minutes > 59) {
379 throw new DateTimeException("Zone offset minutes not in valid range: value " +
380 minutes + " is not in the range -59 to 59");
381 }
382 if (seconds < -59 || seconds > 59) {
383 throw new DateTimeException("Zone offset seconds not in valid range: value " +
384 seconds + " is not in the range -59 to 59");
385 }
386 if (Math.abs(hours) == 18 && (minutes | seconds) != 0) {
387 throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
388 }
389 }
390
391 /**
392 * Calculates the total offset in seconds.
393 *
394 * @param hours the time-zone offset in hours, from -18 to +18
395 * @param minutes the time-zone offset in minutes, from 0 to ±59, sign matches hours and seconds
396 * @param seconds the time-zone offset in seconds, from 0 to ±59, sign matches hours and minutes
397 * @return the total in seconds
398 */
399 private static int totalSeconds(int hours, int minutes, int seconds) {
400 return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
401 }
402
403 //-----------------------------------------------------------------------
404 /**
405 * Obtains an instance of {@code ZoneOffset} specifying the total offset in seconds
406 * <p>
407 * The offset must be in the range {@code -18:00} to {@code +18:00}, which corresponds to -64800 to +64800.
408 *
409 * @param totalSeconds the total time-zone offset in seconds, from -64800 to +64800
410 * @return the ZoneOffset, not null
411 * @throws DateTimeException if the offset is not in the required range
412 */
413 public static ZoneOffset ofTotalSeconds(int totalSeconds) {
414 if (totalSeconds < -MAX_SECONDS || totalSeconds > MAX_SECONDS) {
415 throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
416 }
417 if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
418 Integer totalSecs = totalSeconds;
419 ZoneOffset result = SECONDS_CACHE.get(totalSecs);
420 if (result == null) {
421 result = new ZoneOffset(totalSeconds);
422 SECONDS_CACHE.putIfAbsent(totalSecs, result);
423 result = SECONDS_CACHE.get(totalSecs);
424 ID_CACHE.putIfAbsent(result.getId(), result);
425 }
426 return result;
427 } else {
428 return new ZoneOffset(totalSeconds);
429 }
430 }
431
432 //-----------------------------------------------------------------------
433 /**
434 * Constructor.
679 * @return the adjusted object, not null
680 * @throws DateTimeException if unable to make the adjustment
681 * @throws ArithmeticException if numeric overflow occurs
682 */
683 @Override
684 public Temporal adjustInto(Temporal temporal) {
685 return temporal.with(OFFSET_SECONDS, totalSeconds);
686 }
687
688 //-----------------------------------------------------------------------
689 /**
690 * Compares this offset to another offset in descending order.
691 * <p>
692 * The offsets are compared in the order that they occur for the same time
693 * of day around the world. Thus, an offset of {@code +10:00} comes before an
694 * offset of {@code +09:00} and so on down to {@code -18:00}.
695 * <p>
696 * The comparison is "consistent with equals", as defined by {@link Comparable}.
697 *
698 * @param other the other date to compare to, not null
699 * @return the comparator value, negative if less, positive if greater
700 * @throws NullPointerException if {@code other} is null
701 */
702 @Override
703 public int compareTo(ZoneOffset other) {
704 return Integer.compare(other.totalSeconds, totalSeconds);
705 }
706
707 //-----------------------------------------------------------------------
708 /**
709 * Checks if this offset is equal to another offset.
710 * <p>
711 * The comparison is based on the amount of the offset in seconds.
712 * This is equivalent to a comparison by ID.
713 *
714 * @param obj the object to check, null returns false
715 * @return true if this is equal to the other offset
716 */
717 @Override
718 public boolean equals(Object obj) {
719 if (this == obj) {
720 return true;
721 }
722 if (obj instanceof ZoneOffset) {
723 return totalSeconds == ((ZoneOffset) obj).totalSeconds;
724 }
|