
001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.model.primitive; 021 022import java.util.Calendar; 023import java.util.Date; 024import java.util.TimeZone; 025 026import ca.uhn.fhir.model.api.TemporalPrecisionEnum; 027import ca.uhn.fhir.model.api.annotation.DatatypeDef; 028import ca.uhn.fhir.model.api.annotation.SimpleSetter; 029import ca.uhn.fhir.parser.DataFormatException; 030 031/** 032 * Represents a FHIR instant datatype. Valid precisions values for this type are: 033 * <ul> 034 * <li>{@link TemporalPrecisionEnum#SECOND} 035 * <li>{@link TemporalPrecisionEnum#MILLI} 036 * </ul> 037 */ 038@DatatypeDef(name = "instant") 039public class InstantDt extends BaseDateTimeDt { 040 041 /** 042 * The default precision for this type 043 */ 044 public static final TemporalPrecisionEnum DEFAULT_PRECISION = TemporalPrecisionEnum.MILLI; 045 046 /** 047 * Constructor which creates an InstantDt with <b>no timne value</b>. Note 048 * that unlike the default constructor for the Java {@link Date} or 049 * {@link Calendar} objects, this constructor does not initialize the object 050 * with the current time. 051 * 052 * @see #withCurrentTime() to create a new object that has been initialized 053 * with the current time. 054 */ 055 public InstantDt() { 056 super(); 057 } 058 059 /** 060 * Create a new DateTimeDt 061 */ 062 public InstantDt(Calendar theCalendar) { 063 super(theCalendar.getTime(), DEFAULT_PRECISION, theCalendar.getTimeZone()); 064 } 065 066 /** 067 * Create a new instance using the given date, precision level, and time zone 068 * 069 * @throws DataFormatException 070 * If the specified precision is not allowed for this type 071 */ 072 public InstantDt(Date theDate, TemporalPrecisionEnum thePrecision, TimeZone theTimezone) { 073 super(theDate, thePrecision, theTimezone); 074 } 075 076 077 /** 078 * Create a new DateTimeDt using an existing value. <b>Use this constructor with caution</b>, 079 * as it may create more precision than warranted (since for example it is possible to pass in 080 * a DateTime with only a year, and this constructor will convert to an InstantDt with 081 * milliseconds precision). 082 */ 083 public InstantDt(BaseDateTimeDt theDateTime) { 084 // Do not call super(foo) here, we don't want to trigger a DataFormatException 085 setValue(theDateTime.getValue()); 086 setPrecision(DEFAULT_PRECISION); 087 setTimeZone(theDateTime.getTimeZone()); 088 } 089 090 /** 091 * Create a new DateTimeDt with the given date/time and {@link TemporalPrecisionEnum#MILLI} precision 092 */ 093 @SimpleSetter(suffix = "WithMillisPrecision") 094 public InstantDt(@SimpleSetter.Parameter(name = "theDate") Date theDate) { 095 super(theDate, DEFAULT_PRECISION, TimeZone.getDefault()); 096 } 097 098 /** 099 * Constructor which accepts a date value and a precision value. Valid 100 * precisions values for this type are: 101 * <ul> 102 * <li>{@link TemporalPrecisionEnum#SECOND} 103 * <li>{@link TemporalPrecisionEnum#MILLI} 104 * </ul> 105 */ 106 @SimpleSetter 107 public InstantDt(@SimpleSetter.Parameter(name = "theDate") Date theDate, @SimpleSetter.Parameter(name = "thePrecision") TemporalPrecisionEnum thePrecision) { 108 setValue(theDate); 109 setPrecision(thePrecision); 110 setTimeZone(TimeZone.getDefault()); 111 } 112 113 /** 114 * Create a new InstantDt from a string value 115 * 116 * @param theString 117 * The string representation of the string. Must be in a valid 118 * format according to the FHIR specification 119 * @throws DataFormatException 120 */ 121 public InstantDt(String theString) { 122 super(theString); 123 } 124 125 /** 126 * Invokes {@link Date#after(Date)} on the contained Date against the given 127 * date 128 * 129 * @throws NullPointerException 130 * If the {@link #getValue() contained Date} is null 131 */ 132 public boolean after(Date theDate) { 133 return getValue().after(theDate); 134 } 135 136 /** 137 * Invokes {@link Date#before(Date)} on the contained Date against the given 138 * date 139 * 140 * @throws NullPointerException 141 * If the {@link #getValue() contained Date} is null 142 */ 143 public boolean before(Date theDate) { 144 return getValue().before(theDate); 145 } 146 147 /** 148 * Sets the value of this instant to the current time (from the system 149 * clock) and the local/default timezone (as retrieved using 150 * {@link TimeZone#getDefault()}. This TimeZone is generally obtained from 151 * the underlying OS. 152 */ 153 public void setToCurrentTimeInLocalTimeZone() { 154 setValue(new Date()); 155 setTimeZone(TimeZone.getDefault()); 156 } 157 158 @Override 159 protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) { 160 switch (thePrecision) { 161 case SECOND: 162 case MILLI: 163 return true; 164 default: 165 return false; 166 } 167 } 168 169 /** 170 * Factory method which creates a new InstantDt with millisecond precision and initializes it with the 171 * current time and the system local timezone. 172 */ 173 public static InstantDt withCurrentTime() { 174 return new InstantDt(new Date(), TemporalPrecisionEnum.MILLI, TimeZone.getDefault()); 175 } 176 177 /** 178 * Returns the default precision for this datatype 179 * 180 * @see #DEFAULT_PRECISION 181 */ 182 @Override 183 protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() { 184 return DEFAULT_PRECISION; 185 } 186 187}