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