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 * https://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
18 package org.apache.commons.lang3.time;
19
20 import java.time.LocalDate;
21 import java.time.LocalDateTime;
22 import java.time.OffsetDateTime;
23 import java.time.ZoneId;
24 import java.time.ZonedDateTime;
25 import java.util.Calendar;
26 import java.util.Locale;
27 import java.util.Locale.Category;
28 import java.util.Map;
29 import java.util.Objects;
30
31 /**
32 * Helps use {@link Calendar}s.
33 *
34 * @since 3.10
35 */
36 public class CalendarUtils {
37
38 /**
39 * The singleton instance for {@link Calendar#getInstance()}. The instance is created when the class is initialized and is based on the current time in the
40 * default time zone with the default {@link Category#FORMAT} locale.
41 *
42 * @see CalendarUtils#getInstance()
43 */
44 public static final CalendarUtils INSTANCE = getInstance();
45
46 /**
47 * Creates a new instance based on the current time in the default time zone with the default {@link Category#FORMAT} locale.
48 *
49 * @return a new instance.
50 * @since 3.14.0
51 */
52 public static CalendarUtils getInstance() {
53 return new CalendarUtils(Calendar.getInstance());
54 }
55
56 /**
57 * Gets a CalendarUtils using the default time zone and specified locale. The {@code CalendarUtils} returned is based on the current time in the
58 * default time zone with the given locale.
59 *
60 * @param locale the locale for the week data
61 * @return a Calendar.
62 */
63 static CalendarUtils getInstance(final Locale locale) {
64 return new CalendarUtils(Calendar.getInstance(locale), locale);
65 }
66
67 /**
68 * Converts a Calendar to a LocalDateTime.
69 *
70 * @param calendar the Calendar to convert.
71 * @return a LocalDateTime.
72 * @since 3.17.0
73 */
74 public static LocalDateTime toLocalDateTime(final Calendar calendar) {
75 return LocalDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar));
76 }
77
78 /**
79 * Converts a Calendar to a OffsetDateTime.
80 *
81 * @param calendar the Calendar to convert.
82 * @return a OffsetDateTime.
83 * @since 3.17.0
84 */
85 public static OffsetDateTime toOffsetDateTime(final Calendar calendar) {
86 return OffsetDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar));
87 }
88
89 /**
90 * Converts a Calendar to a ZonedDateTime.
91 *
92 * @param calendar the Calendar to convert.
93 * @return a ZonedDateTime.
94 * @since 3.17.0
95 */
96 public static ZonedDateTime toZonedDateTime(final Calendar calendar) {
97 return ZonedDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar));
98 }
99
100 private static ZoneId toZoneId(final Calendar calendar) {
101 return calendar.getTimeZone().toZoneId();
102 }
103
104 private final Calendar calendar;
105
106 private final Locale locale;
107
108 /**
109 * Creates an instance for the given Calendar.
110 *
111 * @param calendar A Calendar.
112 */
113 public CalendarUtils(final Calendar calendar) {
114 this(calendar, Locale.getDefault());
115 }
116 /**
117 * Creates an instance for the given Calendar.
118 *
119 * @param calendar A Calendar.
120 * @param locale A Locale.
121 */
122 CalendarUtils(final Calendar calendar, final Locale locale) {
123 this.calendar = Objects.requireNonNull(calendar, "calendar");
124 this.locale = Objects.requireNonNull(locale, "locale");
125 }
126
127 /**
128 * Gets the current day of month.
129 *
130 * @return the current day of month.
131 */
132 public int getDayOfMonth() {
133 return calendar.get(Calendar.DAY_OF_MONTH);
134 }
135
136 /**
137 * Gets the current day of year.
138 *
139 * @return the current day of year.
140 * @since 3.13.0
141 */
142 public int getDayOfYear() {
143 return calendar.get(Calendar.DAY_OF_YEAR);
144 }
145
146 /**
147 * Gets the current month.
148 *
149 * @return the current month.
150 */
151 public int getMonth() {
152 return calendar.get(Calendar.MONTH);
153 }
154
155 /**
156 * Gets month names in the requested style.
157 * @param style Must be a valid {@link Calendar#getDisplayNames(int, int, Locale)} month style.
158 * @return Styled names of months
159 */
160 String[] getMonthDisplayNames(final int style) {
161 // Unfortunately standalone month names are not available in DateFormatSymbols,
162 // so we have to extract them.
163 final Map<String, Integer> displayNames = calendar.getDisplayNames(Calendar.MONTH, style, locale);
164 if (displayNames == null) {
165 return null;
166 }
167 final String[] monthNames = new String[displayNames.size()];
168 displayNames.forEach((k, v) -> monthNames[v] = k);
169 return monthNames;
170 }
171
172 /**
173 * Gets full standalone month names as used in "LLLL" date formatting.
174 * @return Long names of months
175 */
176 String[] getStandaloneLongMonthNames() {
177 return getMonthDisplayNames(Calendar.LONG_STANDALONE);
178 }
179
180 /**
181 * Gets short standalone month names as used in "LLLL" date formatting.
182 * @return Short names of months
183 */
184 String[] getStandaloneShortMonthNames() {
185 return getMonthDisplayNames(Calendar.SHORT_STANDALONE);
186 }
187
188 /**
189 * Gets the current year.
190 *
191 * @return the current year.
192 */
193 public int getYear() {
194 return calendar.get(Calendar.YEAR);
195 }
196
197 /**
198 * Converts this instance to a {@link LocalDate}.
199 *
200 * @return a LocalDate.
201 * @since 3.18.0
202 */
203 public LocalDate toLocalDate() {
204 return toLocalDateTime().toLocalDate();
205 }
206
207 /**
208 * Converts this instance to a {@link LocalDateTime}.
209 *
210 * @return a LocalDateTime.
211 * @since 3.17.0
212 */
213 public LocalDateTime toLocalDateTime() {
214 return toLocalDateTime(calendar);
215 }
216
217 /**
218 * Converts this instance to a {@link OffsetDateTime}.
219 *
220 * @return a OffsetDateTime.
221 * @since 3.17.0
222 */
223 public OffsetDateTime toOffsetDateTime() {
224 return toOffsetDateTime(calendar);
225 }
226
227 /**
228 * Converts this instance to a {@link ZonedDateTime}.
229 *
230 * @return a ZonedDateTime.
231 * @since 3.17.0
232 */
233 public ZonedDateTime toZonedDateTime() {
234 return toZonedDateTime(calendar);
235 }
236
237 }