Validate timestamp in HL7 Schema?

HL7, HealthShare

I see the TS and DT data types in the default 2.3 schema:

<DataType name='TS' description='time stamp'>
    <DataSubType piece='1' description='time of an event' datatype='ST'/>
    <DataSubType piece='2' description='degree of precision' datatype='ST'/>
</DataType>

<DataType name='DT' description='Date (2.8.13)'>
    <DataSubType piece='1' description='Date (2.8.13)'/>
</DataType>

but it doesn't appear that it would actually validate the format. Is this possible? We had an instance recently where a customer was sending a timestamp with a missing digit (20160503120 for example). I would like to validate this with the schema if I can.

  • + 1
  • 0
  • 640
  • 5
  • 2

Answers

Hello Scott,

You can change the validation type in your Business Process to account for this. If you include 'y' as a validation type (in the Basic Settings tab of the Business Process), you can enforce data types, which will prevent you from sending a time stamp with missing or additional digits. You can then send these invalid messages to a Bad Message Handler and view the errors in the Event Log. 

 

I actually have it set to e-x which should include data type validation, right?

My question really is, how does that "DT" definition define a date? There's no regex or anything.  How does it know if it should be YYYYMMDD HHMMSS or mm/dd/yy hh:mm:ss?

 

<DataType name='DT' description='Date (2.8.13)'> <DataSubType piece='1' description='Date (2.8.13)'/> </DataType> doesn't really mean anything... does it?

All data structure formatting definitions can be found in the ValidateElementaryDT method of the EnsLib.HL7.Util.Validator class. Here you will see a case statement containing all of the possible data types and their respective formatting.  The "?" syntax in ObjectScript performs pattern matching, and, in this case, works to ensure that the value in the field is of the correct format. Otherwise, an error is thrown and the message does not pass validation. 

Thanks for the info!  I found the statement, I believe, but I'm having trouble understanding.

 

Quit $Case(pDT
, "DT":$S(pVal?1(4N,6N,8N)
&&($E(pVal,1,4)>1700)&&($E(pVal,1,4)<2200)&&(""=$E(pVal,5,6)||($E(pVal,5,6)>0&&($E(pVal,5,6)<=12)))&&(""=$E(pVal,7,8)||($E(pVal,7,8)>0&&($E(pVal,7,8)<=$Case($E(pVal,5,6),2:29,4:30,6:30,9:30,11:30,:31)))):$$$OK
, 1:$$$ERROR($$$EnsErrGeneral,"Invalid date value '"_pVal_"' found for type '"_pDT_"' in segment "_$S($get(info("SegNum"))'="":info("SegNum")_":",1:"")_info("SegName")_", field "_info("fieldNum")_", repetition "_info("rep")_", component "_info("comp")_", subcomponent "_info("subComp")_"."))
, "DTM":$S(pVal?1(4N,6N,8N,10N,12N,14N,14N1".".4N)&&(tZ?.1(1(1"+",1"-")4N))
&&($E(pVal,1,4)>1700)&&($E(pVal,1,4)<2200)&&(""=$E(pVal,5,6)||($E(pVal,5,6)>0&&($E(pVal,5,6)<=12)))&&(""=$E(pVal,7,8)||($E(pVal,7,8)>0&&($E(pVal,7,8)<=$Case($E(pVal,5,6),2:29,4:30,6:30,9:30,11:30,:31))))
&&(""=$E(pVal,9,10)||($E(pVal,9,10)>=0&&($E(pVal,9,10)<24)))&&(""=$E(pVal,11,12)||($E(pVal,11,12)>=0&&($E(pVal,11,12)<60)))&&(""=$E(pVal,13,14)||($E(pVal,13,14)>=0&&($E(pVal,13,14)<60))):$$$OK
, 1:$$$ERROR($$$EnsErrGeneral,"Invalid date/time value '"_pVal_"' found for type '"_pDT_"' in segment "_$S($get(info("SegNum"))'="":info("SegNum")_":",1:"")_info("SegName")_", field "_info("fieldNum")_", repetition "_info("rep")_", component "_info("comp")_", subcomponent "_info("subComp")_"."))

It looks like both `DT` and `DTM` require a format similar to "20161010" but what is up with the $Case($E(pVal,5,6),2:29,4:30,6:30,9:30,11:30,:31), this makes no sense to me. And why is it part of "DT" which seems to be date without time?

That case statement determines how many days are in the given month (the month specified in pVal). So "4:30" indicates that there are 30 days in the month of April. This, combined with the "<=" operator located just before the case statement, is used to evaluate if the day of the month is valid within pVal. If it is not valid, the error "Invalid date value ..." is thrown. Because this is checking the day of the month, the case statement is found in both DT (date value) and DTM (date/time value). 

Ahhh, thanks.

What about the date format? Can you confirm that it's only looking for YYYYMMDD?

pVal?1(4N,6N,8N)

indicates that pVal can either be YYYY, YYYYMM, or YYYYMMDD. Any of these formats should work.