HOWTO · Java
Java で文字列をタイムスタンプに変換する
Java で文字列をタイムスタンプに変換する 4つの方法を示します。
このページの内容
java.sql.Timestamp は小数秒の精度を持つ日時を表し、JDBC でよく使われます。入力の形式に応じてパーサーを選びます。SQL 形式の日時には Timestamp.valueOf()、独自形式の日時には DateTimeFormatter、日付だけの入力には LocalDate を使います。いずれの変換でも、入力に含まれていないタイムゾーンは特定できません。
標準的な日時文字列には Timestamp.valueOf() を使う
2024-06-15 14:30:00 のような文字列は、Timestamp.valueOf(String) で SQL のタイムスタンプ形式として直接解析できます。この API は JDBC のタイムスタンプ・エスケープ形式の値を受け取り、小数秒も指定できます。ここに示す秒までの形式だけに限られるわけではありません。入力の日付要素の順序や区切り文字が異なる場合は、別のパーサーを使ってください。
次の例を実行します。
import java.sql.Timestamp;
public class StringToTimestamp {
public static void main(String[] args) {
String input = "2024-06-15 14:30:00";
Timestamp timestamp = Timestamp.valueOf(input);
System.out.println(timestamp);
}
}
2024-06-15 14:30:00.0
出力される .0 は小数秒の部分です。形式が不正な値は API によって拒否されます。外部からの入力は検証し、アプリケーションの入力境界で解析エラーを処理してください。
DateTimeFormatter で独自形式の日時文字列を解析する
15/06/2024 14:30:00 のようなパターンの値は、DateTimeFormatter で LocalDateTime に解析し、そのオブジェクトを Timestamp.valueOf(LocalDateTime) に渡します。パターンは入力に合わせる必要があります。dd/MM/uuuu は日、月、年を表し、HH:mm:ss は24時間制です。LocalDateTime にはオフセットもタイムゾーンもありません。そのため、この方法では現地の日時フィールドを保持できますが、一意の時点は特定できません。
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CustomTimestamp {
public static void main(String[] args) {
String input = "15/06/2024 14:30:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(input, formatter);
Timestamp timestamp = Timestamp.valueOf(localDateTime);
}
}
SimpleDateFormat で解析した日付を Timestamp に変換する
java.util.Date を使うレガシーコードでは、SimpleDateFormat で独自のパターンを解析できます。解析結果は Date です。getTime() はそのエポックミリ秒値を返し、この値を Timestamp のコンストラクターに渡せます。タイムゾーンを設定しない場合、SimpleDateFormat は JVM のデフォルトのタイムゾーンを使用します。また、デフォルトでは寛容な解析を行います。解釈を予測可能にする必要がある場合は、両方を明示的に設定してください。この例では UTC を指定し、寛容な解析を無効にしています。API のインスタンスは変更可能でスレッドセーフではないため、同じインスタンスを複数のスレッドから同時に共有しないでください。
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class LegacyTimestamp {
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
formatter.setLenient(false);
Date parsed = formatter.parse("15/06/2024 14:30:00");
Timestamp timestamp = new Timestamp(parsed.getTime());
}
}
日付だけの文字列を LocalDate.atStartOfDay() で Timestamp に変換する
日付だけの値には時刻が含まれていません。LocalDate として解析し、atStartOfDay() で意図する時刻を午前0時に定めてから、生成された LocalDateTime を Timestamp に変換します。こうすることで前提を明示できます。入力になかった時刻を保持するわけではありません。
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class DateOnlyTimestamp {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2024-06-15");
LocalDateTime startOfDay = date.atStartOfDay();
Timestamp timestamp = Timestamp.valueOf(startOfDay);
}
}
LocalDateTime と Timestamp の使い分け
値がローカルの暦日と時刻であり、アプリケーションでまだタイムゾーンを割り当てない場合は LocalDateTime を使います。JDBC などの API が java.sql.Timestamp を必要とする場合は Timestamp を使います。これは小数秒を保持でき、ミリ秒値を通じてタイムライン上の時点を表します。LocalDateTime から変換するとき、その値の導出には JVM のデフォルトのタイムゾーンが使われます。そのため、デフォルト設定が異なるマシンでは、同じローカル日時フィールドが異なる時点に対応することがあります。
入力にオフセットや地域が指定されている場合は、java.time のオフセット対応型またはタイムゾーン対応型でその情報を解析して保持してから、時点やデータベース型に変換してください。Timestamp.valueOf() も LocalDateTime も、送信元が意図したタイムゾーンを推測できません。データベースの列型や JDBC ドライバーが独自のタイムゾーン規則を適用する場合もあるため、アプリケーションでの保存時と取得時の前提をそろえてください。