title: Regex for ISO 8601 durations
body: <p>I need a regular expression to validate durations in the <a href="https://en.wikipedia.org/wiki/ISO_8601#Durations" rel="noreferrer">ISO 8601 duration format</a> (with the exception of fractional parts which I don't need).</p>
  <blockquote>
  <p>PnYnMnDTnHnMnS</p>
  <p>PnW</p>
  </blockquote>
  <p>Here is what I have:</p>
  <pre><code>^P(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$
  </code></pre>
  <p>The only problem is that the strings <code>P</code> and <code>PT</code> are allowed with this regex as all of the parts are &quot;zero or one&quot; <code>?</code>.</p>
  <ul>
  <li>There needs to be at least one component (date or time)</li>
  <li>If there is a <code>T</code> then there needs to be a time component (H, M, or S)</li>
  <li>If there is a <code>T</code> then there may or may not be any date components (Y, M, or D)</li>
  <li>Overflow is allowed (e.g. <code>P72H</code> is mostly equivalent to <code>P3D</code>)</li>
  </ul>
  <p>Acceptable inputs:</p>
  <pre><code>P1Y        // date component only
  P2MT30M    // date and time components
  PT6H       // time component only
  P5W        // another date component
  </code></pre>
  <p>Unacceptable inputs:</p>
  <pre><code>P         // no components
  PT        // no components
  P3MT      // T specified but not time components
  </code></pre>
  <p>Right now the invalid strings are passing client-side validation but failing on the server-side because it's passed into <a href="https://php.net/manual/en/dateinterval.construct.php" rel="noreferrer"><code>DateInteval</code></a> but I'd like to fail on the client side if possible. If everyone was using Chrome 40+ I could specify <code>minlength='3'</code> on the input element to help but that isn't the case unfortunately.</p>