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.time.LocalDateTime; 021import java.time.OffsetDateTime; 022import java.time.ZoneId; 023import java.time.ZonedDateTime; 024import java.util.Calendar; 025import java.util.Locale; 026import java.util.Locale.Category; 027import java.util.Map; 028import java.util.Objects; 029 030/** 031 * Helps use {@link Calendar}s. 032 * 033 * @since 3.10 034 */ 035public class CalendarUtils { 036 037 /** 038 * 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 039 * default time zone with the default {@link Category#FORMAT} locale. 040 * 041 * @see CalendarUtils#getInstance() 042 */ 043 public static final CalendarUtils INSTANCE = getInstance(); 044 045 /** 046 * Creates a new instance based on the current time in the default time zone with the default {@link Category#FORMAT} locale. 047 * 048 * @return a new instance. 049 * @since 3.14.0 050 */ 051 public static CalendarUtils getInstance() { 052 return new CalendarUtils(Calendar.getInstance()); 053 } 054 055 /** 056 * Gets a CalendarUtils using the default time zone and specified locale. The {@code CalendarUtils} returned is based on the current time in the 057 * default time zone with the given locale. 058 * 059 * @param locale the locale for the week data 060 * @return a Calendar. 061 */ 062 static CalendarUtils getInstance(final Locale locale) { 063 return new CalendarUtils(Calendar.getInstance(locale), locale); 064 } 065 066 /** 067 * Converts a Calendar to a LocalDateTime. 068 * 069 * @param calendar the Calendar to convert. 070 * @return a LocalDateTime. 071 * @since 3.17.0 072 */ 073 public static LocalDateTime toLocalDateTime(final Calendar calendar) { 074 return LocalDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar)); 075 } 076 077 /** 078 * Converts a Calendar to a OffsetDateTime. 079 * 080 * @param calendar the Calendar to convert. 081 * @return a OffsetDateTime. 082 * @since 3.17.0 083 */ 084 public static OffsetDateTime toOffsetDateTime(final Calendar calendar) { 085 return OffsetDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar)); 086 } 087 088 /** 089 * Converts a Calendar to a ZonedDateTime. 090 * 091 * @param calendar the Calendar to convert. 092 * @return a ZonedDateTime. 093 * @since 3.17.0 094 */ 095 public static ZonedDateTime toZonedDateTime(final Calendar calendar) { 096 return ZonedDateTime.ofInstant(calendar.toInstant(), toZoneId(calendar)); 097 } 098 099 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}