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