如何在Java中实现Excel/Google Sheets式整数转日期功能?
解决方案:Java实现Excel/Google Sheets日期转换逻辑
首先得明确Excel和Google Sheets(默认用1900日期系统)的日期计算规则:
在1900日期系统里,整数
1对应1900年1月1日,每往后一个整数就代表多一天。简单说,整数n对应的日期就是1900-01-01加上(n-1)天。
你提到的整数4305对应14/10/1911,验证一下:1900-01-01加上4304天(4305-1)确实是1911年10月14日,完全匹配规则。
下面用Java 8+的java.time API(推荐替代旧的Date/Calendar类)来实现这个转换逻辑,代码示例如下:
核心转换方法
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class ExcelDateConverter { // 1900日期系统的基准起始日期 private static final LocalDate EXCEL_EPOCH = LocalDate.of(1900, 1, 1); // 定义输出的日期格式(dd/MM/yyyy) private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); /** * 把Excel/Google Sheets的日期整数转成对应日期字符串 * @param excelDate 输入的日期整数 * @return 格式化后的日期字符串 */ public static String convertExcelDateToString(int excelDate) { // 基准日期加上(excelDate - 1)天,得到目标日期 LocalDate targetDate = EXCEL_EPOCH.plusDays(excelDate - 1); return targetDate.format(DATE_FORMATTER); } /** * 批量处理递减的整数数组,转换成对应的日期序列 * @param excelDates 递减的日期整数数组 * @return 格式化后的日期字符串列表 */ public static List<String> convertExcelDatesToDateSequence(int[] excelDates) { return Arrays.stream(excelDates) .mapToObj(ExcelDateConverter::convertExcelDateToString) .collect(Collectors.toList()); } public static void main(String[] args) { // 测试示例:递减的整数数组 int[] inputDates = {4305, 4304, 4303, 4302, 4301}; List<String> dateSequence = convertExcelDatesToDateSequence(inputDates); // 打印转换结果 System.out.println("转换后的日期序列:"); dateSequence.forEach(System.out::println); // 预期输出: // 14/10/1911 // 13/10/1911 // 12/10/1911 // 11/10/1911 // 10/10/1911 } }
关键细节说明
- 基准日期:我们用
LocalDate.of(1900, 1, 1)作为起始点,这是Excel和Google Sheets默认的1900日期系统基准。 - 天数计算:因为整数1本身就对应基准日期,所以要减去1天来计算需要追加的天数。
- 批量处理:借助Java Stream API可以快速遍历整数数组,生成对应的日期序列,代码简洁高效。
额外注意点
如果你的业务需要处理早于1900-03-01的日期,得注意Excel的一个历史bug:它错误地把1900年判定为闰年,所以会存在1900-02-29这个实际不存在的日期。如果要兼容这个场景,需要额外做判断处理(比如当excelDate等于60时,返回1900-03-01而非1900-02-29)。不过你的需求起始日期是1911年,完全不用考虑这个问题。
内容的提问来源于stack exchange,提问作者Lucas Heise




