001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.lang3.time;
019
020import java.util.Calendar;
021import java.util.Locale;
022import java.util.Map;
023import java.util.Objects;
024
025/**
026 * Helps use {@link Calendar}s.
027 *
028 * @since 3.10
029 */
030public class CalendarUtils {
031
032    /**
033     * The singleton instance for {@link Calendar#getInstance()}.
034     */
035    public static final CalendarUtils INSTANCE = new CalendarUtils(Calendar.getInstance());
036
037    /**
038     * Gets a CalendarUtils using the default time zone and specified locale. The <code>CalendarUtils</code> returned is based on the current time in the
039     * default time zone with the given locale.
040     *
041     * @param locale the locale for the week data
042     * @return a Calendar.
043     */
044    static CalendarUtils getInstance(final Locale locale) {
045        return new CalendarUtils(Calendar.getInstance(locale), locale);
046    }
047
048    private final Calendar calendar;
049
050    private final Locale locale;
051
052    /**
053     * Creates an instance for the given Calendar.
054     *
055     * @param calendar A Calendar.
056     */
057    public CalendarUtils(final Calendar calendar) {
058        this(calendar, Locale.getDefault());
059    }
060
061    /**
062     * Creates an instance for the given Calendar.
063     *
064     * @param calendar A Calendar.
065     * @param locale A Locale.
066     */
067    CalendarUtils(final Calendar calendar, final Locale locale) {
068        this.calendar = Objects.requireNonNull(calendar, "calendar");
069        this.locale = Objects.requireNonNull(locale, "locale");
070    }
071    /**
072     * Gets the current day of month.
073     *
074     * @return the current day of month.
075     */
076    public int getDayOfMonth() {
077        return calendar.get(Calendar.DAY_OF_MONTH);
078    }
079
080    /**
081     * Gets the current day of year.
082     *
083     * @return the current day of year.
084     * @since 3.13.0
085     */
086    public int getDayOfYear() {
087        return calendar.get(Calendar.DAY_OF_YEAR);
088    }
089
090    /**
091     * Gets the current month.
092     *
093     * @return the current month.
094     */
095    public int getMonth() {
096        return calendar.get(Calendar.MONTH);
097    }
098
099    /**
100     * Gets month names in the requested style.
101     * @param style Must be a valid {@link Calendar#getDisplayNames(int, int, Locale)} month style.
102     * @return Styled names of months
103     */
104    String[] getMonthDisplayNames(final int style) {
105        // Unfortunately standalone month names are not available in DateFormatSymbols,
106        // so we have to extract them.
107        final Map<String, Integer> displayNames = calendar.getDisplayNames(Calendar.MONTH, style, locale);
108        if (displayNames == null) {
109            return null;
110        }
111        final String[] monthNames = new String[displayNames.size()];
112        displayNames.forEach((k, v) -> monthNames[v] = k);
113        return monthNames;
114    }
115
116    /**
117     * Gets full standalone month names as used in "LLLL" date formatting.
118     * @return Long names of months
119     */
120    String[] getStandaloneLongMonthNames() {
121        return getMonthDisplayNames(Calendar.LONG_STANDALONE);
122    }
123
124    /**
125     * Gets short standalone month names as used in "LLLL" date formatting.
126     * @return Short names of months
127     */
128    String[] getStandaloneShortMonthNames() {
129        return getMonthDisplayNames(Calendar.SHORT_STANDALONE);
130    }
131
132    /**
133     * Gets the current year.
134     *
135     * @return the current year.
136     */
137    public int getYear() {
138        return calendar.get(Calendar.YEAR);
139    }
140}