Нет, нет никакого приятного / волшебного способа сделать это по двум основным причинам:
Существуют различия и неоднозначности в форматах данных, которые делают общий анализатор очень трудным.например, 11/11/11
Вы ищете очень высокую производительность, которая исключает любые методы грубой силы.1us на дату означает всего несколько тысяч инструкций для полного разбора.
На каком-то уровне вам придется указать, какие форматы являются допустимыми и как их интерпретировать.Лучшим способом сделать это, вероятно, является одно или несколько регулярных выражений, которые извлекают соответствующие поля из всех допустимых комбинаций символов, которые могут образовывать дату, а затем значительно упрощают проверку отдельных полей.
Вотпример, который касается всех дат, которые вы перечислили:
val DateMatch = """(\d\d\d\d)[-/ ]?((?:\d\d)|(?:\w\w\w))?[-/ ]?(\d\d)?T?(\d\d)?:?(\d\d)?:?(\d\d)?[\.]*(\d+)?(.*)?""".r
date match {
case DateMatch(year, month, day, hour, min, sec, usec, timezone) =>
(year, Option(month).getOrElse("1"), Option(day).getOrElse(1), Option(hour).getOrElse(0), Option(min).getOrElse(0), Option(sec).getOrElse(0), Option(usec).getOrElse(0), Option(timezone).getOrElse(""))
case _ =>
throw InvalidDateException
}
Как вы видите, он станет очень волосатым, когда будут включены все возможные даты.Но если механизм регулярных выражений может с этим справиться, то он должен быть эффективным, поскольку регулярное выражение должно компилироваться в конечный автомат, который просматривает каждый символ один раз.