View Javadoc
1   package ca.uhn.fhir.model.primitive;
2   
3   import java.util.Calendar;
4   
5   /*
6    * #%L
7    * HAPI FHIR - Core Library
8    * %%
9    * Copyright (C) 2014 - 2018 University Health Network
10   * %%
11   * Licensed under the Apache License, Version 2.0 (the "License");
12   * you may not use this file except in compliance with the License.
13   * You may obtain a copy of the License at
14   * 
15   *      http://www.apache.org/licenses/LICENSE-2.0
16   * 
17   * Unless required by applicable law or agreed to in writing, software
18   * distributed under the License is distributed on an "AS IS" BASIS,
19   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   * See the License for the specific language governing permissions and
21   * limitations under the License.
22   * #L%
23   */
24  
25  import java.util.Date;
26  import java.util.GregorianCalendar;
27  import java.util.TimeZone;
28  
29  import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
30  import ca.uhn.fhir.model.api.annotation.DatatypeDef;
31  import ca.uhn.fhir.model.api.annotation.SimpleSetter;
32  import ca.uhn.fhir.parser.DataFormatException;
33  
34  /**
35   * Represents a FHIR date datatype. Valid precisions values for this type are:
36   * <ul>
37   * <li>{@link TemporalPrecisionEnum#YEAR}
38   * <li>{@link TemporalPrecisionEnum#MONTH}
39   * <li>{@link TemporalPrecisionEnum#DAY}
40   * </ul>
41   * 
42   * <p>
43   * <b>Note on using Java Date objects:</b> This type stores the date as a Java Date. Note that
44   * the Java Date has more precision (millisecond precision), and does not store a timezone. As such,
45   * it could potentially cause issues. For example, if a Date contains the number of milliseconds at
46   * midnight in a timezone across the date line from your location, it might refer to a different date than
47   * intended.
48   * </p>
49   * <p>
50   * As such, it is recommended to use the <code>Calendar<code> or <code>int,int,int</code> constructors  
51   * </p>
52   */
53  @DatatypeDef(name = "date")
54  public class DateDt extends BaseDateTimeDt {
55  
56  	/**
57  	 * The default precision for this type
58  	 */
59  	public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.DAY;
60  
61  	/**
62  	 * Constructor
63  	 */
64  	public DateDt() {
65  		super();
66  	}
67  
68  	/**
69  	 * Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
70  	 */
71  	public DateDt(Calendar theCalendar) {
72  		super(theCalendar.getTime(), DEFAULT_PRECISION);
73  		setTimeZone(theCalendar.getTimeZone());
74  	}
75  
76  	/**
77  	 * Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
78  	 * <b>Please see the note on timezones</b> on the {@link DateDt class documentation} for considerations
79  	 * when using this constructor!
80  	 */
81  	@SimpleSetter(suffix = "WithDayPrecision")
82  	public DateDt(@SimpleSetter.Parameter(name = "theDate") Date theDate) {
83  		super(theDate, DEFAULT_PRECISION);
84  	}
85  
86  	/**
87  	 * Constructor which accepts a date value and a precision value. Valid precisions values for this type are:
88  	 * <ul>
89  	 * <li>{@link TemporalPrecisionEnum#YEAR}
90  	 * <li>{@link TemporalPrecisionEnum#MONTH}
91  	 * <li>{@link TemporalPrecisionEnum#DAY}
92  	 * </ul>
93  	 * <b>Please see the note on timezones</b> on the {@link DateDt class documentation} for considerations
94  	 * when using this constructor!
95  	 * 
96  	 * @throws DataFormatException
97  	 *             If the specified precision is not allowed for this type
98  	 */
99  	@SimpleSetter
100 	public DateDt(@SimpleSetter.Parameter(name = "theDate") Date theDate, @SimpleSetter.Parameter(name = "thePrecision") TemporalPrecisionEnum thePrecision) {
101 		super(theDate, thePrecision);
102 	}
103 
104 	/**
105 	 * Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
106 	 * 
107 	 * @param theYear The year, e.g. 2015
108 	 * @param theMonth The month, e.g. 0 for January
109 	 * @param theDay The day (1 indexed) e.g. 1 for the first day of the month
110 	 */
111 	public DateDt(int theYear, int theMonth, int theDay) {
112 		this(toCalendarZulu(theYear, theMonth, theDay));
113 	}
114 
115 	/**
116 	 * Constructor which accepts a date as a string in FHIR format
117 	 * 
118 	 * @throws DataFormatException
119 	 *             If the precision in the date string is not allowed for this type
120 	 */
121 	public DateDt(String theDate) {
122 		super(theDate);
123 	}
124 
125 	/**
126 	 * Returns the default precision for this datatype
127 	 * 
128 	 * @see #DEFAULT_PRECISION
129 	 */
130 	@Override
131 	protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
132 		return DEFAULT_PRECISION;
133 	}
134 
135 	@Override
136 	protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
137 		switch (thePrecision) {
138 		case YEAR:
139 		case MONTH:
140 		case DAY:
141 			return true;
142 		default:
143 			return false;
144 		}
145 	}
146 
147 	private static GregorianCalendar toCalendarZulu(int theYear, int theMonth, int theDay) {
148 		GregorianCalendar retVal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
149 		retVal.set(Calendar.YEAR, theYear);
150 		retVal.set(Calendar.MONTH, theMonth);
151 		retVal.set(Calendar.DATE, theDay);
152 		return retVal;
153 	}
154 
155 }