Skip to content

Commit

Permalink
Merge pull request #8856 from CDCgov/engagement/bgreen/check-default-…
Browse files Browse the repository at this point in the history
…time-before-conversion

Engagement/bgreen/check default time before conversion
  • Loading branch information
GilmoreA6 committed Mar 27, 2023
2 parents dfe9ad8 + a922ab6 commit 6d01e7f
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions prime-router/src/main/kotlin/common/DateUtilities.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
import java.time.temporal.ChronoField
import java.time.temporal.TemporalAccessor
import java.util.Locale
import kotlin.math.abs
Expand All @@ -26,14 +27,19 @@ import kotlin.math.floor
object DateUtilities {
/** the default date pattern yyyyMMdd */
const val datePattern = "yyyyMMdd"

/** an alternate date pattern MMddyyyy */
const val alternateDatePattern = "[yyyy-MM-dd][yyyy-dd-MM][MMdduuuu][uuuuMMdd]"

/** a local date time pattern to use when formatting in local date time instead */
const val localDateTimePattern = "yyyyMMddHHmmss"

/** our standard offset date time pattern */
const val datetimePattern = "yyyyMMddHHmmssxx"

/** includes seconds and milliseconds in the offset for higher precision */
const val highPrecisionDateTimePattern = "yyyyMMddHHmmss.SSSSxx"

/** wraps around all the possible variations of a date for finding something that matches */
const val variableDateTimePattern = "[yyyyMMdd]" +
"[yyyyMMdd[HHmm][ss][.S][Z]]" +
Expand All @@ -50,6 +56,7 @@ object DateUtilities {
"[yyyyMMdd[ H:mm:ss[.S[S][S]]]]" +
"[M/d/yyyy[ H:mm[:ss[.S[S][S]]]]]" +
"[yyyy/M/d[ H:mm[:ss[.S[S][S]]]]]"

/**
* A list of accepted date formats to try and parse to, one by one. In some instances it is
* better to try and parse a date with a single pattern instead of the large variable date time
Expand All @@ -72,15 +79,19 @@ object DateUtilities {

/** A simple date formatter */
val dateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern(datePattern, Locale.ENGLISH)

/** A default formatter for date and time */
val datetimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern(datetimePattern, Locale.ENGLISH)

/** a higher precision date time formatter that includes seconds, and can be used */
val highPrecisionDateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern(
highPrecisionDateTimePattern,
Locale.ENGLISH
)

/** A formatter for local date times */
val localDateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern(localDateTimePattern, Locale.ENGLISH)

/** The zone ID for UTC */
val utcZone = ZoneId.of("UTC")

Expand Down Expand Up @@ -129,8 +140,9 @@ object DateUtilities {
*/
fun parseDate(dateValue: String): TemporalAccessor {
// check to see if the value has something in it
if (dateValue.trimToNull() == null)
if (dateValue.trimToNull() == null) {
throw DateTimeException("Invalid value passed in for date value. Received $dateValue")
}
// parse out the date
return try {
DateTimeFormatter.ofPattern(variableDateTimePattern)
Expand All @@ -147,8 +159,9 @@ object DateUtilities {
// work, throw an error
if (dateValue.indexOf('Z', ignoreCase = true) > -1) {
val isoDate = tryParseIsoDate(dateValue)
if (isoDate != null)
if (isoDate != null) {
return isoDate.toOffsetDateTime(utcZone)
}
}
allowedDateFormats.forEach { format ->
val parsedDate = parseDate(dateValue, format)
Expand All @@ -168,7 +181,7 @@ object DateUtilities {
ZonedDateTime::from,
LocalDateTime::from,
LocalDate::from,
Instant::from,
Instant::from
)
} catch (_: Throwable) {
null
Expand Down Expand Up @@ -214,6 +227,14 @@ object DateUtilities {
}
}

fun isTimeGreaterThanZero(temporalAccessor: TemporalAccessor): Boolean {
val hour = temporalAccessor.get(ChronoField.HOUR_OF_DAY)
val minute = temporalAccessor.get(ChronoField.MINUTE_OF_HOUR)
val second = temporalAccessor.get(ChronoField.SECOND_OF_MINUTE)

return hour > 0 || minute > 0 || second > 0
}

/**
* this looks to see if there is an "all zero offset" preceded by a plus sign on the
* date time value. if there is, then we're going to flip this bit over to be
Expand Down Expand Up @@ -475,7 +496,7 @@ object DateUtilities {
}
}
is OffsetDateTime, is Instant -> {
if (zoneId != null) {
if (zoneId != null && isTimeGreaterThanZero(this)) {
ZonedDateTime.from(this).withZoneSameInstant(zoneId)
} else {
ZonedDateTime.from(this)
Expand All @@ -498,6 +519,7 @@ object DateUtilities {
**/
fun TemporalAccessor.formatDateTimeForReceiver(report: Report? = null): String {
val hl7Config = report?.destination?.translation as? Hl7Configuration

return formatDateForReceiver(
this,
report?.getTimeZoneForReport() ?: ZoneId.of("UTC"),
Expand Down

0 comments on commit 6d01e7f

Please sign in to comment.