This suggestion is a change to the following rule in the SEND 3.0 (FDA).xml rule set:
<val:Regex ID=“SD1011” PublisherID=“FDAN039” Message=“Invalid ISO 8601 value for %Variable% variable” Description=“Value of Duration, Elapsed Time, and Interval variables (–DUR, --ELTM, --EVLINT) must conform to the ISO 8601 international standard.” Category=“Format” Type=“Error” Variable=“%Variables[*DUR,*ELTM,*EVLINT,*PAI,TDSTOFF]%” Test=“(-?P((([0-9]+(.[0-9]+)?Y)?([0-9]+(.[0-9]+)?M)?([0-9]+(.[0-9]+)?D)?(T([0-9]+(.[0-9]+)?H)?([0-9]+(.[0-9]+)?M)?([0-9]+S)?)?)|[0-9]+(.[0-9]+)?W))|((((([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?))/((([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?)))|(((([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?))/(((+|-)?P((((0-9?)Y)?((0-9?)M)?((0-9?)D)?)(T(((0-9?)H)?((0-9?)M)?((0-9?)((.[0-9]+)?)S)?)?)?|(((0-9?)W))))))|((((+|-)?P((((0-9?)Y)?((0-9?)M)?((0-9?)D)?)(T(((0-9?)H)?((0-9?)M)?((0-9?)((.[0-9]+)?)S)?)?)?|(((0-9?)W)))))/((([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?))))”/>
The numeric value associated with week is not permitted to have a decimal portion. I believe this was not intended. Also the definition of durations starting with a P that are used together with date/time fields to create an interval are specified with different limitations compared to one that has no date/time field. These later ones only permit decimal values with the seconds field and not the other fields. The following is a correction to these.
Here is my proposed regex for the P-intervals:
(+|-)?
P(
(
(
([0-9]+(.[0-9]+)?Y)?
([0-9]+(.[0-9]+)?M)?
([0-9]+(.[0-9]+)?D)?
)
(
T
([0-9]+(.[0-9]+)?H)?
([0-9]+(.[0-9]+)?M)?
([0-9]+(.[0-9]+)?S)?
)?
)
|
([0-9]+(.[0-9]+)?)W
)
The date-time specification appears to be correct, but doesn’t permit the obscure use of “-” for an unknown element. It also permits the use of time-zones which is not described in the SENDIG.
([0-9][0-9][0-9][0-9]) %four digit year
(
(-(([0][1-9])|([1][0-2]))) %optional month 01 through 12
(
(-(([0][1-9])|([1-2][0-9])|([3][0-1]))) %optional day: 01 through 31
(
T( %optional Time
(([0-1][0-9])|([2][0-3])) %00 through 23 for hour
(
(:([0-5][0-9])) %:00 through :59 for min
(
(
(:([0-5][0-9])) %:00 through :59 for sec
((.[0-9]+)?) %decimal second.
)?
)?
)?
(
(
((+|-) %timezone offset in hours and minutes or Z
(
([0-1][0-9])
|
([2][0-3])
)
:[0-5][0-9]
)
|
(Z)
)
)?
)
)?
)?
)?
I see that structure that you have been using is as listed here. Note: The SEND IG does not describe the use of a date-time element combined with a duration element. It might be more accurate to list the first two approaches of duration or date-time / date-time.
(duration)|(((date-time)/(date-time))|((date-time)/(duration))|((duration)/(date-time)))
Taking these regular expressions I listed earlier and placing them into a copy of the previous line, results in what I believe would be a better regex for these intervals:
(\+|-)?P((((([0-9]+(\.[0-9]+)?)Y)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)D)?)(T(([0-9]+(\.[0-9]+)?)H)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)S)?)?)|([0-9]+(\.[0-9]+)?)W)|((([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?/([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?)|(([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?/(\+|-)?P((((([0-9]+(\.[0-9]+)?)Y)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)D)?)(T(([0-9]+(\.[0-9]+)?)H)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)S)?)?)|([0-9]+(\.[0-9]+)?)W))|((\+|-)?P((((([0-9]+(\.[0-9]+)?)Y)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)D)?)(T(([0-9]+(\.[0-9]+)?)H)?(([0-9]+(\.[0-9]+)?)M)?(([0-9]+(\.[0-9]+)?)S)?)?)|([0-9]+(\.[0-9]+)?)W)/([0-9][0-9][0-9][0-9])((-(([0][1-9])|([1][0-2])))((-(([0][1-9])|([1-2][0-9])|([3][0-1])))(T((([0-1][0-9])|([2][0-3]))((:([0-5][0-9]))(((:([0-5][0-9]))((.[0-9]+)?))?)?)?((((+|-)(([0-1][0-9])|([2][0-3])):[0-5][0-9])|(Z)))?))?)?)?))