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

如何在Java中存储花费的时间或总持续时间?,java,time,apache-poi,duration,Java,Time,Apache Poi,Duration,我正在使用POI API for Java自动化excel报告。我将有几个报告在我的处置,我阅读使用POI,处理他们,并创建一个新的excel报告 excel文件中的一列包含所花费的总时间,也就是说,它可以采用以下格式,46:23:12——即46小时23分12秒 我了解如何读取日期和时间值,并且通常将它们存储在java.util.date中。这里的问题是这是一个持续时间,花费的时间可能超过24小时。哪种数据类型适用于此?我如何使用POI来阅读这篇文章呢?有一个Period类,您可以在Java8中

我正在使用POI API for Java自动化excel报告。我将有几个报告在我的处置,我阅读使用POI,处理他们,并创建一个新的excel报告

excel文件中的一列包含所花费的总时间,也就是说,它可以采用以下格式,
46:23:12
——即
46小时23分12秒


我了解如何读取日期和时间值,并且通常将它们存储在
java.util.date
中。这里的问题是这是一个持续时间,花费的时间可能超过24小时。哪种数据类型适用于此?我如何使用POI来阅读这篇文章呢?

有一个Period类,您可以在Java8中使用它

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() );
当然,我错过了关于小时、分和秒的情况

为此,有持续时间

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

在Java8中,时间量由表示

我不确定Apache POI是否有方法直接处理
持续时间
,因此我认为最好的方法是将值获取为
字符串
, 然后解析此
字符串
以获取值并将这些值添加到
持续时间

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()
,它将以以下格式返回此持续时间:

PT46H23M12S


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



如果您使用的是Java,则会列出apachepoi支持的数据类型

我建议使用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();

接受的答案是正确的,完全符合要求。这个答案提供了一些额外的细节,以及从
46:23:12
的给定字符串创建字符串的替代方法

是以ISO-8601标准为模型的,并作为的一部分与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
了解现代日期时间API

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() );
  • 无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7
  • 如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认

您的java版本是什么?我可以根据需要使用任何版本。我不确定POI提供了哪些选项,但Excel将时间存储为一天的分数(即0.5意味着12:00pm)。因此,您可以尝试将该单元格读取为十进制数,然后将其转换为您需要的任何表示形式(例如,
持续时间
)。
持续时间
更适合,因为
期间
需要定义的开始和结束日期。啊,是的。对不起,凤凰社,这个答案是对的。在这里添加了一些扩展