001/*
002Copyright (c) 2011+, HL7, Inc
003All rights reserved.
004
005Redistribution and use in source and binary forms, with or without modification, 
006are permitted provided that the following conditions are met:
007
008 * Redistributions of source code must retain the above copyright notice, this 
009   list of conditions and the following disclaimer.
010 * Redistributions in binary form must reproduce the above copyright notice, 
011   this list of conditions and the following disclaimer in the documentation 
012   and/or other materials provided with the distribution.
013 * Neither the name of HL7 nor the names of its contributors may be used to 
014   endorse or promote products derived from this software without specific 
015   prior written permission.
016
017THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
018ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
019WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
020IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
021INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
022NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
023PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
024WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
025ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
026POSSIBILITY OF SUCH DAMAGE.
027
028*/
029/**
030 * 
031 */
032package org.hl7.fhir.dstu2.model;
033
034/*-
035 * #%L
036 * org.hl7.fhir.dstu2
037 * %%
038 * Copyright (C) 2014 - 2019 Health Level 7
039 * %%
040 * Licensed under the Apache License, Version 2.0 (the "License");
041 * you may not use this file except in compliance with the License.
042 * You may obtain a copy of the License at
043 * 
044 *      http://www.apache.org/licenses/LICENSE-2.0
045 * 
046 * Unless required by applicable law or agreed to in writing, software
047 * distributed under the License is distributed on an "AS IS" BASIS,
048 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
049 * See the License for the specific language governing permissions and
050 * limitations under the License.
051 * #L%
052 */
053
054
055import java.util.Calendar;
056import java.util.Date;
057import java.util.TimeZone;
058import java.util.zip.DataFormatException;
059
060import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
061import ca.uhn.fhir.model.api.annotation.DatatypeDef;
062
063/**
064 * Represents a FHIR instant datatype. Valid precisions values for this type are:
065 * <ul>
066 * <li>{@link TemporalPrecisionEnum#SECOND}
067 * <li>{@link TemporalPrecisionEnum#MILLI}
068 * </ul>
069 */
070@DatatypeDef(name="instant")
071public class InstantType extends BaseDateTimeType {
072
073        private static final long serialVersionUID = 3L;
074        
075        /**
076         * The default precision for this type
077         */
078        public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.MILLI;
079
080        /**
081         * Constructor which creates an InstantDt with <b>no timne value</b>. Note
082         * that unlike the default constructor for the Java {@link Date} or
083         * {@link Calendar} objects, this constructor does not initialize the object
084         * with the current time.
085         * 
086         * @see #withCurrentTime() to create a new object that has been initialized
087         *      with the current time.
088         */
089        public InstantType() {
090                super();
091        }
092
093        /**
094         * Create a new DateTimeDt
095         */
096        public InstantType(Calendar theCalendar) {
097                super(theCalendar.getTime(), DEFAULT_PRECISION, theCalendar.getTimeZone());
098        }
099
100        /**
101         * Create a new instance using the given date, precision level, and time zone
102         * 
103         * @throws DataFormatException
104         *             If the specified precision is not allowed for this type
105         */
106        public InstantType(Date theDate, TemporalPrecisionEnum thePrecision, TimeZone theTimezone) {
107                super(theDate, thePrecision, theTimezone);
108        }
109
110
111        /**
112         * Create a new DateTimeDt using an existing value. <b>Use this constructor with caution</b>,
113         * as it may create more precision than warranted (since for example it is possible to pass in
114         * a DateTime with only a year, and this constructor will convert to an InstantDt with 
115         * milliseconds precision).
116         */
117        public InstantType(BaseDateTimeType theDateTime) {
118                // Do not call super(foo) here, we don't want to trigger a DataFormatException
119                setValue(theDateTime.getValue());
120                setPrecision(DEFAULT_PRECISION);
121                setTimeZone(theDateTime.getTimeZone());
122        }
123
124        /**
125         * Create a new DateTimeDt with the given date/time and {@link TemporalPrecisionEnum#MILLI} precision
126         */
127        public InstantType(Date theDate) {
128                super(theDate, DEFAULT_PRECISION, TimeZone.getDefault());
129        }
130
131        /**
132         * Constructor which accepts a date value and a precision value. Valid
133         * precisions values for this type are:
134         * <ul>
135         * <li>{@link TemporalPrecisionEnum#SECOND}
136         * <li>{@link TemporalPrecisionEnum#MILLI}
137         * </ul>
138         */
139        public InstantType(Date theDate, TemporalPrecisionEnum thePrecision) {
140                setValue(theDate);
141                setPrecision(thePrecision);
142                setTimeZone(TimeZone.getDefault());
143        }
144
145        /**
146         * Create a new InstantDt from a string value
147         * 
148         * @param theString
149         *            The string representation of the string. Must be in a valid
150         *            format according to the FHIR specification
151         * @throws DataFormatException
152         */
153        public InstantType(String theString) {
154                super(theString);
155        }
156
157        /**
158         * Invokes {@link Date#after(Date)} on the contained Date against the given
159         * date
160         * 
161         * @throws NullPointerException
162         *             If the {@link #getValue() contained Date} is null
163         */
164        public boolean after(Date theDate) {
165                return getValue().after(theDate);
166        }
167
168        /**
169         * Invokes {@link Date#before(Date)} on the contained Date against the given
170         * date
171         * 
172         * @throws NullPointerException
173         *             If the {@link #getValue() contained Date} is null
174         */
175        public boolean before(Date theDate) {
176                return getValue().before(theDate);
177        }
178
179        /**
180         * Sets the value of this instant to the current time (from the system
181         * clock) and the local/default timezone (as retrieved using
182         * {@link TimeZone#getDefault()}. This TimeZone is generally obtained from
183         * the underlying OS.
184         */
185        public void setToCurrentTimeInLocalTimeZone() {
186                setValue(new Date());
187                setTimeZone(TimeZone.getDefault());
188        }
189
190        @Override
191        boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
192                switch (thePrecision) {
193                case SECOND:
194                case MILLI:
195                        return true;
196                default:
197                        return false;
198                }
199        }
200
201        /**
202         * Factory method which creates a new InstantDt with millisecond precision and initializes it with the
203         * current time and the system local timezone.
204         */
205        public static InstantType withCurrentTime() {
206                return new InstantType(new Date(), TemporalPrecisionEnum.MILLI, TimeZone.getDefault());
207        }
208
209        /**
210         * Returns the default precision for this datatype
211         * 
212         * @see #DEFAULT_PRECISION
213         */
214        @Override
215        protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
216                return DEFAULT_PRECISION;
217        }
218
219
220        @Override
221        public InstantType copy() {
222    InstantType ret = new InstantType();
223    ret.setValueAsString(getValueAsString());
224    return ret;
225        }
226
227        /**
228         * Returns a new instance of DateTimeType with the current system time and MILLI precision and the system local time
229         * zone
230         */
231        public static InstantType now() {
232                return new InstantType(new Date(), TemporalPrecisionEnum.MILLI, TimeZone.getDefault());
233        }
234
235        /**
236         * Creates a new instance by parsing an HL7 v3 format date time string
237         */
238        public static InstantType parseV3(String theV3String) {
239                InstantType retVal = new InstantType();
240                retVal.setValueAsV3String(theV3String);
241                return retVal;
242        }
243
244        public String fhirType() {
245                return "instant";
246        }
247}