001package ezvcard.property; 002 003import java.time.Instant; 004import java.time.LocalDate; 005import java.time.LocalDateTime; 006import java.time.OffsetDateTime; 007import java.time.temporal.Temporal; 008import java.util.LinkedHashMap; 009import java.util.List; 010import java.util.Map; 011import java.util.Objects; 012 013import ezvcard.VCard; 014import ezvcard.VCardVersion; 015import ezvcard.ValidationWarning; 016import ezvcard.parameter.Calscale; 017import ezvcard.parameter.VCardParameters; 018import ezvcard.util.PartialDate; 019 020/* 021 Copyright (c) 2012-2023, Michael Angstadt 022 All rights reserved. 023 024 Redistribution and use in source and binary forms, with or without 025 modification, are permitted provided that the following conditions are met: 026 027 1. Redistributions of source code must retain the above copyright notice, this 028 list of conditions and the following disclaimer. 029 2. Redistributions in binary form must reproduce the above copyright notice, 030 this list of conditions and the following disclaimer in the documentation 031 and/or other materials provided with the distribution. 032 033 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 034 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 035 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 036 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 037 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 038 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 039 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 040 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 041 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 042 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 043 044 The views and conclusions contained in the software and documentation are those 045 of the authors and should not be interpreted as representing official policies, 046 either expressed or implied, of the FreeBSD Project. 047 */ 048 049/** 050 * Represents a property that typically contains a date/time value, but can also 051 * contain a partial date or free-text value. 052 * @author Michael Angstadt 053 */ 054public class DateOrTimeProperty extends VCardProperty implements HasAltId { 055 private String text; 056 private Temporal date; 057 private PartialDate partialDate; 058 059 /** 060 * Creates a date-and-or-time property. 061 * @param date the date value (should be one of the following: 062 * {@link LocalDate}, {@link LocalDateTime}, {@link OffsetDateTime}, 063 * {@link Instant}) 064 */ 065 public DateOrTimeProperty(Temporal date) { 066 this.date = date; 067 } 068 069 /** 070 * Creates a date-and-or-time property. 071 * @param partialDate the partial date value (vCard 4.0 only) 072 */ 073 public DateOrTimeProperty(PartialDate partialDate) { 074 setPartialDate(partialDate); 075 } 076 077 /** 078 * Creates a date-and-or-time property. 079 * @param text the text value (vCard 4.0 only) 080 */ 081 public DateOrTimeProperty(String text) { 082 setText(text); 083 } 084 085 /** 086 * Copy constructor. 087 * @param original the property to make a copy of 088 */ 089 public DateOrTimeProperty(DateOrTimeProperty original) { 090 super(original); 091 text = original.text; 092 date = original.date; 093 partialDate = original.partialDate; 094 } 095 096 /** 097 * Gets the date value. It should be an instance of one of the following 098 * classes: {@link LocalDate}, {@link LocalDateTime}, 099 * {@link OffsetDateTime}, {@link Instant}. 100 * @return the date value or null if not set 101 */ 102 public Temporal getDate() { 103 return date; 104 } 105 106 /** 107 * Sets the value of this property to a date. It should be an instance of 108 * one of the following classes: {@link LocalDate}, {@link LocalDateTime}, 109 * {@link OffsetDateTime}, {@link Instant}. 110 * @param date the date 111 */ 112 public void setDate(Temporal date) { 113 this.date = date; 114 text = null; 115 partialDate = null; 116 } 117 118 /** 119 * Gets the reduced accuracy or truncated date. This is only supported by 120 * vCard 4.0. 121 * @return the reduced accuracy or truncated date or null if not set 122 * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 p.12-14</a> 123 */ 124 public PartialDate getPartialDate() { 125 return partialDate; 126 } 127 128 /** 129 * <p> 130 * Sets the value of this property to a reduced accuracy or truncated date. 131 * This is only supported by vCard 4.0. 132 * </p> 133 * 134 * <pre class="brush:java"> 135 * Birthday bday = new Birthday(); 136 * bday.setPartialDate(PartialDate.date(null, 4, 20)); //April 20 137 * </pre> 138 * 139 * @param partialDate the reduced accuracy or truncated date 140 * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 p.12-14</a> 141 */ 142 public void setPartialDate(PartialDate partialDate) { 143 this.partialDate = partialDate; 144 text = null; 145 date = null; 146 } 147 148 /** 149 * Gets the text value of this type. This is only supported by vCard 4.0. 150 * @return the text value or null if not set 151 */ 152 public String getText() { 153 return text; 154 } 155 156 /** 157 * Sets the value of this property to a text string. This is only supported 158 * by vCard 4.0. 159 * @param text the text value or null if not set 160 */ 161 public void setText(String text) { 162 this.text = text; 163 date = null; 164 partialDate = null; 165 } 166 167 /** 168 * <p> 169 * Gets the type of calendar that is used for a date or date-time property 170 * value. 171 * </p> 172 * <p> 173 * <b>Supported versions:</b> {@code 4.0} 174 * </p> 175 * @return the type of calendar or null if not found 176 * @see VCardParameters#getCalscale 177 */ 178 public Calscale getCalscale() { 179 return parameters.getCalscale(); 180 } 181 182 /** 183 * <p> 184 * Sets the type of calendar that is used for a date or date-time property 185 * value. 186 * </p> 187 * <p> 188 * <b>Supported versions:</b> {@code 4.0} 189 * </p> 190 * @param calscale the type of calendar or null to remove 191 * @see VCardParameters#setCalscale 192 */ 193 public void setCalscale(Calscale calscale) { 194 parameters.setCalscale(calscale); 195 } 196 197 @Override 198 public String getLanguage() { 199 return super.getLanguage(); 200 } 201 202 @Override 203 public void setLanguage(String language) { 204 super.setLanguage(language); 205 } 206 207 //@Override 208 public String getAltId() { 209 return parameters.getAltId(); 210 } 211 212 //@Override 213 public void setAltId(String altId) { 214 parameters.setAltId(altId); 215 } 216 217 @Override 218 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 219 if (date == null && partialDate == null && text == null) { 220 warnings.add(new ValidationWarning(8)); 221 } 222 223 if (version == VCardVersion.V2_1 || version == VCardVersion.V3_0) { 224 if (text != null) { 225 warnings.add(new ValidationWarning(11)); 226 } 227 if (partialDate != null) { 228 warnings.add(new ValidationWarning(12)); 229 } 230 } 231 } 232 233 @Override 234 protected Map<String, Object> toStringValues() { 235 Map<String, Object> values = new LinkedHashMap<>(); 236 values.put("text", text); 237 values.put("date", date); 238 values.put("partialDate", partialDate); 239 return values; 240 } 241 242 @Override 243 public int hashCode() { 244 final int prime = 31; 245 int result = super.hashCode(); 246 result = prime * result + Objects.hash(date, partialDate, text); 247 return result; 248 } 249 250 @Override 251 public boolean equals(Object obj) { 252 if (this == obj) return true; 253 if (!super.equals(obj)) return false; 254 if (getClass() != obj.getClass()) return false; 255 DateOrTimeProperty other = (DateOrTimeProperty) obj; 256 return Objects.equals(date, other.date) && Objects.equals(partialDate, other.partialDate) && Objects.equals(text, other.text); 257 } 258}