如何在Java中存储花费的时间或总持续时间?

时间:2017-07-19 13:45:02

标签: java time apache-poi duration

我使用POI API for Java自动化excel报告。我将处理的报告很少,我使用POI阅读,处理它们,并创建一个新的Excel报告。

excel文件中的一列已经花费了总时间,也就是说,它可以采用以下格式46:23:12 - 读为46 hours, 23 minutes and 12 seconds

我了解如何阅读日期和时间值,我通常会将它们存储在java.util.Date中。这里的问题是这是一个持续时间,花费的时间可能超过24.哪种数据类型适合这个?我如何使用POI阅读此内容?

4 个答案:

答案 0 :(得分:5)

在Java 8中,一段时间由class java.time.Duration表示。

我不确定Apache POI是否有直接处理Duration的方法,所以我认为最好的方法是将值设为String, 然后解析此String以获取值并将这些值添加到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]));

duration对象将包含与输入相当的金额(在这种情况下:46小时,23分钟和12秒)。如果您致电duration.toString(),则会在ISO 8601 format中返回此持续时间:

  

PT46H23M12S

当然,此代码假定输入String始终包含三个字段(小时,分钟和秒)。但是您可以在解析值之前检查values.length(并且仅当相应的值不为零时才调用plus方法。)

如果您正在使用 Java< = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ThreeTenABP(更多关于如何使用它here)。

唯一的区别是包名称(在Java 8中为java.time而在ThreeTen Backport(或Android的ThreeTenABP中)为org.threeten.bp),但类和方法名称是一样的。

答案 1 :(得分:1)

您可以在 Java 8 中使用期间类。

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

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

当然,我错过了这个小时,分钟和秒钟的方式。

为此,持续时间

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

答案 2 :(得分:0)

Apache POI支持的数据类型列于here

我建议使用0x15," h:mm:ss"所有之中。

您可以使用以下两个代码块进行读写。但阅读后你应该手动解析字符串。

写入花在新文件上的总时间:

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();

要读取现有文件所花费的总时间:

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();

答案 3 :(得分:0)

接受的答案是正确的,完全符合要求。此答案提供了一些其他详细信息以及从给定的 46:23:12 字符串创建 ISO-8601 standards 字符串的替代方法。

java.time.Duration 以 ISO-8601 标准为模型,并作为 JSR-310 implementation 的一部分与 Java-8 一起引入。 Java-9 引入了一些更方便的方法。

演示:

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();
    }
}

输出:

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

Trail: Date Time 了解现代日期时间 API。