001package org.hl7.fhir.dstu3.model;
002
003import java.util.Calendar;
004import java.util.Date;
005import java.util.TimeZone;
006import java.util.zip.DataFormatException;
007
008import org.apache.commons.lang3.time.DateUtils;
009
010/*
011  Copyright (c) 2011+, HL7, Inc.
012  All rights reserved.
013  
014  Redistribution and use in source and binary forms, with or without modification, 
015  are permitted provided that the following conditions are met:
016    
017   * Redistributions of source code must retain the above copyright notice, this 
018     list of conditions and the following disclaimer.
019   * Redistributions in binary form must reproduce the above copyright notice, 
020     this list of conditions and the following disclaimer in the documentation 
021     and/or other materials provided with the distribution.
022   * Neither the name of HL7 nor the names of its contributors may be used to 
023     endorse or promote products derived from this software without specific 
024     prior written permission.
025  
026  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
027  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
028  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
029  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
030  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
031  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
032  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
033  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
034  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
035  POSSIBILITY OF SUCH DAMAGE.
036  
037 */
038
039
040
041import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
042import ca.uhn.fhir.model.api.annotation.DatatypeDef;
043
044/**
045 * Represents a FHIR dateTime datatype. Valid precisions values for this type are:
046 * <ul>
047 * <li>{@link TemporalPrecisionEnum#YEAR}
048 * <li>{@link TemporalPrecisionEnum#MONTH}
049 * <li>{@link TemporalPrecisionEnum#DAY}
050 * <li>{@link TemporalPrecisionEnum#SECOND}
051 * <li>{@link TemporalPrecisionEnum#MILLI}
052 * </ul>
053 */
054@DatatypeDef(name = "dateTime")
055public class DateTimeType extends BaseDateTimeType {
056
057        private static final long serialVersionUID = 3L;
058        
059        /**
060         * The default precision for this type
061         */
062        public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.SECOND;
063
064        /**
065         * Constructor
066         */
067        public DateTimeType() {
068                super();
069        }
070
071        /**
072         * Create a new DateTimeDt with seconds precision and the local time zone
073         */
074        public DateTimeType(Date theDate) {
075                super(theDate, DEFAULT_PRECISION, TimeZone.getDefault());
076        }
077
078        /**
079         * Constructor which accepts a date value and a precision value. Valid precisions values for this type are:
080         * <ul>
081         * <li>{@link TemporalPrecisionEnum#YEAR}
082         * <li>{@link TemporalPrecisionEnum#MONTH}
083         * <li>{@link TemporalPrecisionEnum#DAY}
084         * <li>{@link TemporalPrecisionEnum#SECOND}
085         * <li>{@link TemporalPrecisionEnum#MILLI}
086         * </ul>
087         * 
088         * @throws DataFormatException
089         *             If the specified precision is not allowed for this type
090         */
091        public DateTimeType(Date theDate, TemporalPrecisionEnum thePrecision) {
092                super(theDate, thePrecision, TimeZone.getDefault());
093        }
094
095        /**
096         * Create a new instance using a string date/time
097         * 
098         * @throws DataFormatException
099         *             If the specified precision is not allowed for this type
100         */
101        public DateTimeType(String theValue) {
102                super(theValue);
103        }
104
105        /**
106         * Constructor which accepts a date value, precision value, and time zone. Valid precisions values for this type
107         * are:
108         * <ul>
109         * <li>{@link TemporalPrecisionEnum#YEAR}
110         * <li>{@link TemporalPrecisionEnum#MONTH}
111         * <li>{@link TemporalPrecisionEnum#DAY}
112         * <li>{@link TemporalPrecisionEnum#SECOND}
113         * <li>{@link TemporalPrecisionEnum#MILLI}
114         * </ul>
115         */
116        public DateTimeType(Date theDate, TemporalPrecisionEnum thePrecision, TimeZone theTimezone) {
117                super(theDate, thePrecision, theTimezone);
118        }
119
120        /**
121         * Constructor
122         */
123        public DateTimeType(Calendar theCalendar) {
124                if (theCalendar != null) {
125                        setValue(theCalendar.getTime());
126                        setPrecision(DEFAULT_PRECISION);
127                        setTimeZone(theCalendar.getTimeZone());
128                }
129        }
130
131        @Override
132        boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
133                switch (thePrecision) {
134                case YEAR:
135                case MONTH:
136                case DAY:
137                case SECOND:
138                case MILLI:
139                        return true;
140                default:
141                        return false;
142                }
143        }
144
145        /**
146         * Returns a new instance of DateTimeType with the current system time and SECOND precision and the system local time
147         * zone
148         */
149        public static DateTimeType now() {
150                return new DateTimeType(new Date(), TemporalPrecisionEnum.SECOND, TimeZone.getDefault());
151        }
152
153        /**
154         * Returns the default precision for this datatype
155         * 
156         * @see #DEFAULT_PRECISION
157         */
158        @Override
159        protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
160                return DEFAULT_PRECISION;
161        }
162
163        @Override
164        public DateTimeType copy() {
165                return new DateTimeType(getValueAsString());
166        }
167
168        /**
169         * Creates a new instance by parsing an HL7 v3 format date time string
170         */
171        public static DateTimeType parseV3(String theV3String) {
172                DateTimeType retVal = new DateTimeType();
173                retVal.setValueAsV3String(theV3String);
174                return retVal;
175        }
176
177        public static DateTimeType today() {
178                DateTimeType retVal = now();
179                retVal.setPrecision(TemporalPrecisionEnum.DAY);
180                return retVal;
181        }
182
183        public boolean getTzSign() {
184                return getTimeZone().getRawOffset() >= 0;
185        }
186
187        public int getTzHour() {
188                return (int) (getTimeZone().getRawOffset() / DateUtils.MILLIS_PER_MINUTE) / 60;
189        }
190
191        public int getTzMin() {
192                return (int) (getTimeZone().getRawOffset() / DateUtils.MILLIS_PER_MINUTE) % 60;
193        }
194
195        
196        public String fhirType() {
197                return "dateTime";              
198        }
199}