How to store time spent or total duration in Java?

馋奶兔 提交于 2021-02-08 16:42:56

问题


I am automating a excel report using the POI API for Java. I will have few reports in my disposal which I read using POI, process them, and create a new excel report.

One of columns from an excel file has total time spent, that is, it could in following format, 46:23:12 - this reads as 46 hours, 23 minutes and 12 seconds.

I understand how to read date and time values and I usually store them in java.util.Date. The problem here is this is a time duration, the hours spent could be more than 24. Which datatype could be suitable for this? And how do I read this using POI?


回答1:


In Java 8, an amount of time is represented by the class java.time.Duration.

I'm not sure if Apache POI has methods to deal directly with a Duration, so I believe that the best approach is to get the value as String, then parse this String to get the values and add those values to the Duration:

String s = "46:23:12";
String[] values = s.split(":");
// get the hours, minutes and seconds value and add it to the duration
Duration duration = Duration.ofHours(Integer.parseInt(values[0]));
duration = duration.plusMinutes(Integer.parseInt(values[1]));
duration = duration.plusSeconds(Integer.parseInt(values[2]));

The duration object will contain the amount equivalent to the input (in this case: 46 hours, 23 minutes and 12 seconds). If you call duration.toString(), it returns this duration in ISO 8601 format:

PT46H23M12S


Of course this code assumes that the input String always contains the three fields (hours, minutes and seconds). But you could check for values.length before parsing the values (and also call the plus methods only if the respective value is not zero).


If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.




回答2:


There is a Period class which you can use in Java 8.

LocalDate startDate = LocalDate.of(year, month, day );
LocalDate endDate = new LocalDate(year, month, day);

Period diff = Period.between(startDate , endDate);

Of course, I missed how this was about hours, minutes and seconds.

For this, there is Duration.

Duration timeDiff = Duration.ofMillis( startTime.getTime() , endTime.getTime() );



回答3:


Data types supported by Apache POI are listed here.

I would recommend using 0x15, "h:mm:ss" among all.

You can use the following two code blocks to read and write. But after reading you should manually parse the string.

To write total time spent into a new file:

final HSSFWorkbook workbook = new HSSFWorkbook();
final Sheet sheet = workbook.createSheet("SHEET ONE");

final CellStyle style = workbook.createCellStyle();
style.setDataFormat((short) 0x15);

final Row completeRow = sheet.createRow(0);
final Cell cell = completeRow.createCell(0);
cell.setCellValue("46:23:12");
cell.setCellStyle(style);

FileOutputStream fileOutputStream = new FileOutputStream(new File("/tmp/one.xls"));
workbook.write(fileOutputStream);
fileOutputStream.close();

To read total time spent from existing file:

FileInputStream fileInputStream = new FileInputStream("/tmp/one.xls");
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet sheet = workbook.getSheet("SHEET ONE");

for (Row row : sheet) {
    for (Cell cell : row) {
        final String stringCellValue = cell.getStringCellValue();

        System.out.println("stringCellValue = " + stringCellValue);
    }
}

fileInputStream.close();



回答4:


The accepted answer is correct and meets the requirements completely. This answer provides some additional details as well as an alternative way to create ISO-8601 standards string from the given string of 46:23:12.

java.time.Duration is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenience methods were introduced.

Demo:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        String iso8601DurationString = toIso8601DurationString("46:23:12");
        System.out.println(iso8601DurationString);

        Duration duration = Duration.parse(iso8601DurationString);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedDuration = String.format(
                "%02d Day %02d Hour %02d Minute %02d Second %d Millisecond %d Nanosecond", duration.toDays(),
                duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toMillis() % 1000, duration.toNanos() % 1000000000L);
        System.out.println(formattedDuration);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedDuration = String.format("%02d Day %02d Hour %02d Minute %02d Second %d Millisecond %d Nanosecond",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toMillisPart(), duration.toNanosPart());
        System.out.println(formattedDuration);
        // ##############################################################################
    }

    static String toIso8601DurationString(String duration) {
        char[] symbols = "HMS".toCharArray();
        String[] durationParts = duration.split(":");
        StringBuilder sb = new StringBuilder("PT");
        for (int i = 0; i < durationParts.length; i++) {
            sb.append(durationParts[i]).append(symbols[i]);
        }
        return sb.toString();
    }
}

Output:

PT46H23M12S
PT46H23M12S
01 Day 22 Hour 23 Minute 12 Second 0 Millisecond 0 Nanosecond
01 Day 22 Hour 23 Minute 12 Second 0 Millisecond 0 Nanosecond

Learn about the modern date-time API from Trail: Date Time.

  • For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
  • If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.


来源:https://stackoverflow.com/questions/45192499/how-to-store-time-spent-or-total-duration-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!