pvillard31 commented on code in PR #10697:
URL: https://github.com/apache/nifi/pull/10697#discussion_r2652715852
##########
nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/field/ObjectLocalDateTimeFieldConverter.java:
##########
@@ -99,39 +106,67 @@ public LocalDateTime convertField(final Object field,
final Optional<String> pat
private LocalDateTime tryParseAsNumber(final String value, final String
fieldName) {
try {
- // If decimal, treat as a double and convert to seconds and
nanoseconds.
- if (value.contains(".")) {
- final double number = Double.parseDouble(value);
- return toLocalDateTime(number);
+ final LocalDateTime localDateTime;
+
+ final int periodIndex = value.indexOf(PERIOD);
+ if (periodIndex >= 0) {
+ // Parse Double to support both decimal notation and exponent
notation
+ final double floatingPointNumber = Double.parseDouble(value);
+ localDateTime = convertDouble(floatingPointNumber);
+ } else {
+ final long number = Long.parseLong(value);
+ localDateTime = toLocalDateTime(number);
}
- // attempt to parse as a long value
- final long number = Long.parseLong(value);
- return toLocalDateTime(number);
+ return localDateTime;
} catch (final NumberFormatException e) {
throw new FieldConversionException(LocalDateTime.class, value,
fieldName, e);
}
}
- private LocalDateTime toLocalDateTime(final double secondsSinceEpoch) {
- // Determine the number of micros past the second by subtracting the
number of seconds from the decimal value and multiplying by 1 million.
- final double micros = 1_000_000 * (secondsSinceEpoch - (long)
secondsSinceEpoch);
- // Convert micros to nanos. Note that we perform this as a separate
operation, rather than multiplying by 1_000,000,000 in order to avoid
- // issues that occur with rounding at high precision.
- final long nanos = (long) micros * 1000L;
+ private LocalDateTime convertDouble(final double number) {
+ // Cast to long for integral part of the number
+ final long integral = (long) number;
+
+ // Calculate fractional part of the number for subsequent precision
evaluation
+ final double fractional = number - integral;
- return toLocalDateTime((long) secondsSinceEpoch, nanos);
+ return convertIntegralFractional(integral, fractional);
}
- private LocalDateTime toLocalDateTime(final long epochSeconds, final long
nanosPastSecond) {
- final Instant instant =
Instant.ofEpochSecond(epochSeconds).plusNanos(nanosPastSecond);
+ private LocalDateTime convertIntegralFractional(final long integral, final
double fractional) {
Review Comment:
I'd add a comment to explain the dual case logic. Could also be an in-line
comment.
```suggestion
/**
* Convert integral and fractional components to LocalDateTime.
*
* Large integral values (beyond year 10,000 in seconds) indicate the
input
* is in milliseconds, with the fractional part representing
microseconds.
* Smaller integral values are treated as seconds, with the fractional
part
* representing the fraction of a second (converted to microseconds).
*
* Example: 1765056655230.746 → 1765056655230 ms + 746 µs
* Example: 1707238288.351567 → 1707238288 s + 351567 µs
*/
private LocalDateTime convertIntegralFractional(final long integral,
final double fractional) {
```
##########
nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/field/ObjectLocalDateTimeFieldConverter.java:
##########
@@ -36,6 +37,11 @@
*/
class ObjectLocalDateTimeFieldConverter implements FieldConverter<Object,
LocalDateTime> {
private static final long YEAR_TEN_THOUSAND = 253_402_300_800_000L;
+ private static final long YEAR_TEN_THOUSAND_SECONDS = 253_402_300_800L;
+ private static final char PERIOD = '.';
+
+ private static final long MICROSECOND_MULTIPLIER = 1_000;
+ private static final long MILLISECOND_MULTIPLIER = 1_000_000;
Review Comment:
Thoughts about using something like `MICROS_TO_NANOS` and
`FRACTION_TO_MICROS_SECONDS` to be more self-explanatory?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]