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
030package org.hl7.fhir.dstu2.model;
031
032/*-
033 * #%L
034 * org.hl7.fhir.dstu2
035 * %%
036 * Copyright (C) 2014 - 2019 Health Level 7
037 * %%
038 * Licensed under the Apache License, Version 2.0 (the "License");
039 * you may not use this file except in compliance with the License.
040 * You may obtain a copy of the License at
041 * 
042 *      http://www.apache.org/licenses/LICENSE-2.0
043 * 
044 * Unless required by applicable law or agreed to in writing, software
045 * distributed under the License is distributed on an "AS IS" BASIS,
046 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
047 * See the License for the specific language governing permissions and
048 * limitations under the License.
049 * #L%
050 */
051
052
053import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
054import ca.uhn.fhir.model.api.annotation.DatatypeDef;
055import org.apache.commons.lang3.time.DateUtils;
056
057import java.util.Calendar;
058import java.util.Date;
059import java.util.TimeZone;
060import java.util.zip.DataFormatException;
061
062/**
063 * Represents a FHIR dateTime datatype. Valid precisions values for this type are:
064 * <ul>
065 * <li>{@link TemporalPrecisionEnum#YEAR}
066 * <li>{@link TemporalPrecisionEnum#MONTH}
067 * <li>{@link TemporalPrecisionEnum#DAY}
068 * <li>{@link TemporalPrecisionEnum#SECOND}
069 * <li>{@link TemporalPrecisionEnum#MILLI}
070 * </ul>
071 */
072@DatatypeDef(name = "dateTime")
073public class DateTimeType extends BaseDateTimeType {
074
075        private static final long serialVersionUID = 3L;
076        
077        /**
078         * The default precision for this type
079         */
080        public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.SECOND;
081
082        /**
083         * Constructor
084         */
085        public DateTimeType() {
086                super();
087        }
088
089        /**
090         * Create a new DateTimeDt with seconds precision and the local time zone
091         */
092        public DateTimeType(Date theDate) {
093                super(theDate, DEFAULT_PRECISION, TimeZone.getDefault());
094        }
095
096        /**
097         * Constructor which accepts a date value and a precision value. Valid precisions values for this type are:
098         * <ul>
099         * <li>{@link TemporalPrecisionEnum#YEAR}
100         * <li>{@link TemporalPrecisionEnum#MONTH}
101         * <li>{@link TemporalPrecisionEnum#DAY}
102         * <li>{@link TemporalPrecisionEnum#SECOND}
103         * <li>{@link TemporalPrecisionEnum#MILLI}
104         * </ul>
105         * 
106         * @throws DataFormatException
107         *             If the specified precision is not allowed for this type
108         */
109        public DateTimeType(Date theDate, TemporalPrecisionEnum thePrecision) {
110                super(theDate, thePrecision, TimeZone.getDefault());
111        }
112
113        /**
114         * Create a new instance using a string date/time
115         * 
116         * @throws DataFormatException
117         *             If the specified precision is not allowed for this type
118         */
119        public DateTimeType(String theValue) {
120                super(theValue);
121        }
122
123        /**
124         * Constructor which accepts a date value, precision value, and time zone. Valid precisions values for this type
125         * are:
126         * <ul>
127         * <li>{@link TemporalPrecisionEnum#YEAR}
128         * <li>{@link TemporalPrecisionEnum#MONTH}
129         * <li>{@link TemporalPrecisionEnum#DAY}
130         * <li>{@link TemporalPrecisionEnum#SECOND}
131         * <li>{@link TemporalPrecisionEnum#MILLI}
132         * </ul>
133         */
134        public DateTimeType(Date theDate, TemporalPrecisionEnum thePrecision, TimeZone theTimezone) {
135                super(theDate, thePrecision, theTimezone);
136        }
137
138        /**
139         * Constructor
140         */
141        public DateTimeType(Calendar theCalendar) {
142                if (theCalendar != null) {
143                        setValue(theCalendar.getTime());
144                        setPrecision(DEFAULT_PRECISION);
145                        setTimeZone(theCalendar.getTimeZone());
146                }
147        }
148
149        @Override
150        boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
151                switch (thePrecision) {
152                case YEAR:
153                case MONTH:
154                case DAY:
155                case SECOND:
156                case MILLI:
157                        return true;
158                default:
159                        return false;
160                }
161        }
162
163        /**
164         * Returns a new instance of DateTimeType with the current system time and SECOND precision and the system local time
165         * zone
166         */
167        public static DateTimeType now() {
168                return new DateTimeType(new Date(), TemporalPrecisionEnum.SECOND, TimeZone.getDefault());
169        }
170
171        /**
172         * Returns the default precision for this datatype
173         * 
174         * @see #DEFAULT_PRECISION
175         */
176        @Override
177        protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
178                return DEFAULT_PRECISION;
179        }
180
181        @Override
182        public DateTimeType copy() {
183                return new DateTimeType(getValueAsString());
184        }
185
186        /**
187         * Creates a new instance by parsing an HL7 v3 format date time string
188         */
189        public static DateTimeType parseV3(String theV3String) {
190                DateTimeType retVal = new DateTimeType();
191                retVal.setValueAsV3String(theV3String);
192                return retVal;
193        }
194
195        public static DateTimeType today() {
196                DateTimeType retVal = now();
197                retVal.setPrecision(TemporalPrecisionEnum.DAY);
198                return retVal;
199        }
200
201        public boolean getTzSign() {
202                return getTimeZone().getRawOffset() >= 0;
203        }
204
205        public int getTzHour() {
206                return (int) (getTimeZone().getRawOffset() / DateUtils.MILLIS_PER_MINUTE) / 60;
207        }
208
209        public int getTzMin() {
210                return (int) (getTimeZone().getRawOffset() / DateUtils.MILLIS_PER_MINUTE) % 60;
211        }
212
213        
214        public String fhirType() {
215                return "dateTime";              
216        }
217}