View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.time;
18  
19  import java.util.Date;
20  import java.util.Objects;
21  import java.util.TimeZone;
22  
23  /**
24   * Custom time zone that contains offset from GMT.
25   *
26   * @since 3.7
27   */
28  final class GmtTimeZone extends TimeZone {
29  
30      private static final int MILLISECONDS_PER_MINUTE = 60 * 1000;
31      private static final int MINUTES_PER_HOUR = 60;
32      private static final int HOURS_PER_DAY = 24;
33  
34      // Serializable!
35      static final long serialVersionUID = 1L;
36  
37      private static StringBuilder twoDigits(final StringBuilder sb, final int n) {
38          return sb.append((char) ('0' + n / 10)).append((char) ('0' + n % 10));
39      }
40      private final int offset;
41  
42      private final String zoneId;
43  
44      GmtTimeZone(final boolean negate, final int hours, final int minutes) {
45          if (hours >= HOURS_PER_DAY) {
46              throw new IllegalArgumentException(hours + " hours out of range");
47          }
48          if (minutes >= MINUTES_PER_HOUR) {
49              throw new IllegalArgumentException(minutes + " minutes out of range");
50          }
51          final int milliseconds = (minutes + hours * MINUTES_PER_HOUR) * MILLISECONDS_PER_MINUTE;
52          offset = negate ? -milliseconds : milliseconds;
53          // @formatter:off
54          zoneId = twoDigits(twoDigits(new StringBuilder(9)
55              .append(TimeZones.GMT_ID)
56              .append(negate ? '-' : '+'), hours)
57              .append(':'), minutes)
58              .toString();
59          // @formatter:on
60      }
61  
62      @Override
63      public boolean equals(final Object obj) {
64          if (this == obj) {
65              return true;
66          }
67          if (!(obj instanceof GmtTimeZone)) {
68              return false;
69          }
70          final GmtTimeZone other = (GmtTimeZone) obj;
71          return offset == other.offset && Objects.equals(zoneId, other.zoneId);
72      }
73  
74      @Override
75      public String getID() {
76          return zoneId;
77      }
78  
79      @Override
80      public int getOffset(final int era, final int year, final int month, final int day, final int dayOfWeek, final int milliseconds) {
81          return offset;
82      }
83  
84      @Override
85      public int getRawOffset() {
86          return offset;
87      }
88  
89      @Override
90      public int hashCode() {
91          return Objects.hash(offset, zoneId);
92      }
93  
94      @Override
95      public boolean inDaylightTime(final Date date) {
96          return false;
97      }
98  
99      @Override
100     public void setRawOffset(final int offsetMillis) {
101         throw new UnsupportedOperationException();
102     }
103 
104     @Override
105     public String toString() {
106         return "[GmtTimeZone id=\"" + zoneId + "\",offset=" + offset + ']';
107     }
108 
109     @Override
110     public boolean useDaylightTime() {
111         return false;
112     }
113 }