All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.geotab.model.serialization.DurationSerializationUtil Maven / Gradle / Ivy

/*
 *
 * 2020 Copyright (C) Geotab Inc. All rights reserved.
 */

package com.geotab.model.serialization;

import java.time.Duration;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;

/**
 * Serialization helper used to convert {@link Duration} to and from {@link String}.
 *
 * 

Expected {@link Duration} pattern is [-][d.]hh:mm:ss[.fffffff] , as explained in * https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-timespan-format-strings . */ @UtilityClass public class DurationSerializationUtil { public static Duration durationFromString(String durationString) { if (StringUtils.isEmpty(durationString)) { return null; } Duration duration = Duration.ZERO; boolean isNegated = false; if (durationString.startsWith("-")) { durationString = durationString.substring(1); isNegated = true; } // 1.00:00:00 (1 days) int dotIndex = durationString.indexOf('.'); if (dotIndex > -1 && dotIndex < 4) { String[] dayParts = durationString.split("\\."); duration = addDays(duration, dayParts[0]); durationString = durationString.substring(dotIndex + 1); } String[] parts = durationString.split(":"); if (parts.length != 3) { throw new IllegalArgumentException( "Unexpected duration pattern for value " + durationString + " . Expected pattern is [-][d.]hh:mm:ss[.fffffff]"); } duration = addHoursAndMinutes(duration, parts); duration = addSecondsAndNanos(duration, parts[2]); return isNegated ? duration.negated() : duration; } public static String durationToString(Duration duration) { if (duration == null) { return null; } String format = "HH:mm:ss"; if (duration.toDays() != 0) { format = "d.".concat(format); } if (duration.isNegative()) { duration = duration.negated(); format = "-".concat(format); } if (duration.toNanos() % 1_000_000_000 > 0) { // 1 sec = 1_000_000_000 nanos long ticks = duration.getNano() / 100; // if ticks are in the hundred thousand's range or less,then prepend with zeros up to 7 digits format = format.concat(".'" + String.format("%07d", ticks) + "'"); } return DurationFormatUtils.formatDuration(duration.toMillis(), format, true); } private static Duration addDays(Duration duration, String daysPart) { int days = Integer.parseInt(daysPart); return duration.plusDays(days); } private static Duration addHoursAndMinutes(Duration duration, String[] parts) { int hours = Integer.parseInt(parts[0]); int minutes = Integer.parseInt(parts[1]); return duration.plusHours(hours).plusMinutes(minutes); } private static Duration addSecondsAndNanos(Duration duration, String secondsAndTicks) { int seconds; long ticks = 0; // 00:14:44.0630001 (with ticks) if (secondsAndTicks.contains(".")) { String[] secondsParts = secondsAndTicks.split("\\."); seconds = Integer.parseInt(secondsParts[0]); // in case there are less the 7 digits for ticks, then append zeros up to 7 digits ticks = Long.parseLong(String.format("%0$-7s", secondsParts[1])); } else { seconds = Integer.parseInt(secondsAndTicks); } return duration.plusSeconds(seconds).plusNanos(ticks * 100); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy