Java Excel日付のシリアル値をDate型へ変換する方法

JavaでExcel日付のシリアル値をDate型へ変換する方法です。

Java Excel日付のシリアル値をDate型へ変換する方法

>画像

とある案件でJavaでExcelを読み込んでデータベースに登録するって処理がありました。まあ、こういった要望はよくあるので筆者にとってはいつもことだったんですけど、なんとExcelの日付がシリアル値として取得されてしまったんですね。

Excelを読み込んだのは「JavaでExcel(xlsx)をOOXMLで読み込む方法」で紹介した方法を使いました。

まあ、取得されたExcel日付のシリアル値がjava.util.Dateへ変換できればいいかと思ってこの記事を書くことにしました。

ここでは JavaでExcel日付のシリアル値をDate型へ変換する方法 を紹介します。


前提条件

まず、Excelのセルに日付が入る位置が決まっていることが前提です。実務で使われているExcelの多くは、列で入力項目が管理されていると思うので、日付が入る列が決まっていると思います。

Excelのセルに日付が入る位置が決まっていることが前提

これから紹介するコードは、上図のような書式のExcelを読み込む場合に有効です。

Excel日付のシリアル値をDate型へ変換

では、Excel日付のシリアル値をDate型へ変換する方法を紹介します。

package test;

import java.util.Calendar;
import java.util.Date;

public class SerialToDate {
  public static void main(String[] args) {
    System.out.println(String.format("%1$tF",toDate("44285"))); // 2021-03-30
    System.out.println(String.format("%1$tF",toDate("44286"))); // 2021-03-31
    System.out.println(String.format("%1$tF",toDate("44287"))); // 2021-04-01
    System.out.println(String.format("%1$tF",toDate("44288"))); // 2021-04-02
  }
  /**
   * 指定されたExcel日付のシリアル値を日付型に変換して返します。
   *
   * @param value 文字列
   * @return true:正常, false:異常
   */
  private static Date toDate(String value) {
    // 1900/1/1のシリアルが1なので、加算する値は取得した値 - 1になる
    int serial = Integer.parseInt(value)- 1;
    // 1900/2/29は存在しないがエクセル内では存在しているらしいので
    // その日付以降であればさらに -1
    serial -= (serial > 60 ? 1 : 0);
    // Windowsでのデフォルトでは1900/1/1 12:00:00AMから
    // 上記時刻を表すCalendarクラスのインスタンス
    Calendar cal = Calendar.getInstance();
    cal.set(1900, 0, 1, 12, 0, 0);
    // 基準日に加算
    cal.add(Calendar.DATE, serial);
    return cal.getTime();
  }
}

このコードを実行すると、、、

Excel日付のシリアル値を日付型に変換した結果

おおおー、Javaの日付型に変換されたー。

参考サイト

こちらのサイトのコードを転用させていただきました。ありがとうございます。

https://oshiete.goo.ne.jp/qa/6811912.html

上記サイトによれば、WindowsとMacで仕様が異なるようですが、オプションで補正が可能なようです。

日付と時刻の関数 (リファレンス) - Office サポート

まとめ

JavaでExcel日付のシリアル値をDate型へ変換する方法を紹介しました。

シリアル値は特定の日付からの経過日数を表します。デフォルトから加算していけば変換できるのですが、Excelには存在しないはずの1900/2/29が存在しているようで、ここがハマるポイントでしょうかね。

この辺りはJava POIに任せてしまうのがホントはいいんでしょうね。

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。