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.r4.model; 033 034import ca.uhn.fhir.model.api.TemporalPrecisionEnum; 035import ca.uhn.fhir.model.api.annotation.DatatypeDef; 036 037import java.util.Calendar; 038import java.util.Date; 039import java.util.TimeZone; 040import java.util.zip.DataFormatException; 041 042/** 043 * Represents a FHIR instant datatype. Valid precisions values for this type are: 044 * <ul> 045 * <li>{@link TemporalPrecisionEnum#SECOND} 046 * <li>{@link TemporalPrecisionEnum#MILLI} 047 * </ul> 048 */ 049@DatatypeDef(name = "instant") 050public class InstantType extends BaseDateTimeType { 051 052 /** 053 * The default precision for this type 054 */ 055 public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.MILLI; 056 private static final long serialVersionUID = 3L; 057 058 /** 059 * Constructor which creates an InstantDt with <b>no timne value</b>. Note 060 * that unlike the default constructor for the Java {@link Date} or 061 * {@link Calendar} objects, this constructor does not initialize the object 062 * with the current time. 063 * 064 * @see #withCurrentTime() to create a new object that has been initialized 065 * with the current time. 066 */ 067 public InstantType() { 068 super(); 069 } 070 071 /** 072 * Create a new DateTimeDt 073 */ 074 public InstantType(Calendar theCalendar) { 075 super(theCalendar.getTime(), DEFAULT_PRECISION, theCalendar.getTimeZone()); 076 } 077 078 /** 079 * Create a new instance using the given date, precision level, and time zone 080 * 081 * @throws DataFormatException If the specified precision is not allowed for this type 082 */ 083 public InstantType(Date theDate, TemporalPrecisionEnum thePrecision, TimeZone theTimezone) { 084 super(theDate, thePrecision, theTimezone); 085 } 086 087 088 /** 089 * Create a new DateTimeDt using an existing value. <b>Use this constructor with caution</b>, 090 * as it may create more precision than warranted (since for example it is possible to pass in 091 * a DateTime with only a year, and this constructor will convert to an InstantDt with 092 * milliseconds precision). 093 */ 094 public InstantType(BaseDateTimeType theDateTime) { 095 // Do not call super(foo) here, we don't want to trigger a DataFormatException 096 setValue(theDateTime.getValue()); 097 setPrecision(DEFAULT_PRECISION); 098 setTimeZone(theDateTime.getTimeZone()); 099 } 100 101 /** 102 * Create a new DateTimeDt with the given date/time and {@link TemporalPrecisionEnum#MILLI} precision 103 */ 104 public InstantType(Date theDate) { 105 super(theDate, DEFAULT_PRECISION, TimeZone.getDefault()); 106 } 107 108 /** 109 * Constructor which accepts a date value and a precision value. Valid 110 * precisions values for this type are: 111 * <ul> 112 * <li>{@link TemporalPrecisionEnum#SECOND} 113 * <li>{@link TemporalPrecisionEnum#MILLI} 114 * </ul> 115 */ 116 public InstantType(Date theDate, TemporalPrecisionEnum thePrecision) { 117 setValue(theDate); 118 setPrecision(thePrecision); 119 setTimeZone(TimeZone.getDefault()); 120 } 121 122 /** 123 * Create a new InstantDt from a string value 124 * 125 * @param theString The string representation of the string. Must be in a valid 126 * format according to the FHIR specification 127 * @throws DataFormatException 128 */ 129 public InstantType(String theString) { 130 super(theString); 131 } 132 133 /** 134 * Invokes {@link Date#after(Date)} on the contained Date against the given 135 * date 136 * 137 * @throws NullPointerException If the {@link #getValue() contained Date} is null 138 */ 139 public boolean after(Date theDate) { 140 return getValue().after(theDate); 141 } 142 143 /** 144 * Invokes {@link Date#before(Date)} on the contained Date against the given 145 * date 146 * 147 * @throws NullPointerException If the {@link #getValue() contained Date} is null 148 */ 149 public boolean before(Date theDate) { 150 return getValue().before(theDate); 151 } 152 153 @Override 154 public InstantType copy() { 155 return new InstantType(getValueAsString()); 156 } 157 158 public String fhirType() { 159 return "instant"; 160 } 161 162 /** 163 * Returns the default precision for this datatype 164 * 165 * @see #DEFAULT_PRECISION 166 */ 167 @Override 168 protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() { 169 return DEFAULT_PRECISION; 170 } 171 172 @Override 173 boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) { 174 switch (thePrecision) { 175 case SECOND: 176 case MILLI: 177 return true; 178 default: 179 return false; 180 } 181 } 182 183 /** 184 * Sets the value of this instant to the current time (from the system 185 * clock) and the local/default timezone (as retrieved using 186 * {@link TimeZone#getDefault()}. This TimeZone is generally obtained from 187 * the underlying OS. 188 */ 189 public void setToCurrentTimeInLocalTimeZone() { 190 setValue(new Date()); 191 setTimeZone(TimeZone.getDefault()); 192 } 193 194 /** 195 * Returns a new instance of DateTimeType with the current system time and MILLI precision and the system local time 196 * zone 197 */ 198 public static InstantType now() { 199 return new InstantType(new Date(), TemporalPrecisionEnum.MILLI, TimeZone.getDefault()); 200 } 201 202 /** 203 * Creates a new instance by parsing an HL7 v3 format date time string 204 */ 205 public static InstantType parseV3(String theV3String) { 206 InstantType retVal = new InstantType(); 207 retVal.setValueAsV3String(theV3String); 208 return retVal; 209 } 210 211 /** 212 * Factory method which creates a new InstantDt with millisecond precision and initializes it with the 213 * current time and the system local timezone. 214 */ 215 public static InstantType withCurrentTime() { 216 return new InstantType(new Date(), TemporalPrecisionEnum.MILLI, TimeZone.getDefault()); 217 } 218}