private static long parseDateAsMillisSinceEpoch(final String dateStr) {
        try {
            return Long.parseLong(dateStr);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(LogUtil.message(
                    "Unable to parse date '{}' as numeric milliseconds since epoch: {}",
                    dateStr,
                    e.getMessage()), e);
        }
    }
Takes an ISO 8601 date string and converts it into a consistent ISO 8601 format.
This is to deal with the fact that the ISO 8601 format is a bit woolly (e.g. 'Z'
and '+00:00' are both ok). This method will ensure that all dates returned are in a
predictable and consistent format. Only intended for use on dates known to be in
ISO 8601 format.
<p>
Will also normalise an epoch millis number into a date string.

<pre>{@code
"2010-01-01T23:59:59Z" => "2010-01-01T23:59:59Z" // No millis
"2010-01-01T23:59:59.123Z" => "2010-01-01T23:59:59.123Z" // Millis
"2010-01-01T23:59:59.123456Z" => "2010-01-01T23:59:59.123" // Nanos
"2010-01-01T23:59:59.123+00:00" => "2010-01-01T23:59:59.123Z" // Zulu/UTC
"2010-01-01T23:59:59.123+02" => "2010-01-01T23:59:59.123+0200" // +2hr zone offset
"2010-01-01T23:59:59+02:00" => "2010-01-01T23:59:59.000+0200" // +2hr zone offset
"2010-01-01T23:59:59+02:30" => "2010-01-01T23:59:59.000+0230" // +2hr30min zone offset
"2010-01-01T23:59:59.123-03:00" => "2010-01-01T23:59:59.123-0300" // -3hr zone offset
}</pre>

@param date         The date string to normalise.
@param ignoreErrors If true, any exception when parsing/converting the date is swallowed
                    and data is returned unchanged.
@return The date normalised to the same output as {@link DateUtil#createNormalDateTimeString(Long)}.
If date is null or blank returns it as is with no exception.
stroom-util/src/main/java/stroom/util/date/DateUtil.java