Javaで日時を扱う(Java7まで)
Java8では、日時を扱うクラス群が様変わりしてしまいました。これを機に、日時の扱いをまとめてみたいと思います。今回は、Java7までの日時、次回は、Java8での日時を書きたいと思います。
Java7までは、主に、Dateクラス、Calendarクラスを使いますね。Apache Commons LangのDateUtils、DateFormatUtilsも使えると便利。
Apache Commons Lang について
- https://commons.apache.org/proper/commons-lang/
- バージョン3.2では、Java6以上が必要。
- バージョン3.0では、Java5以上が必要。
- バージョン2.xは、Java1.4で使用可能。
現在/指定日時の作成
Dateクラスの現在/指定日時を作成する。
// 現在日時 Date nowDate1 = new Date(); // 文字列→Date DateFormat dateTimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date date1 = dateTimeFormat.parse("2016/5/2 15:00:00"); // 文字列→Date(Apache Commons Lang) // ※Java5から、書式引数を可変長引数として記述できるようになった。 Date date1b = DateUtils.parseDate("2016/5/2 15:00:00", "yyyy/MM/dd HH:mm:ss"); Date date1c = DateUtils.parseDate("2016-5-2 15:00:00", "yyyy/MM/dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss"); // Calendar→Date Date date2 = new GregorianCalendar(2016, 5 - 1, 2, 15, 0, 0).getTime(); // long→Date Date date3 = new Date(System.currentTimeMillis());
Calendarクラスの現在/指定日時を作成する。
// 現在日時 Calendar nowCal1 = Calendar.getInstance(); // 指定日時 Calendar cal1 = new GregorianCalendar(2016, 5 - 1, 2, 15, 0, 0); // Date→Calendar Calendar cal2 = Calendar.getInstance(); cal2.setTime(date1); // Date→Calendar(Apache Commons Lang) Calendar cal2b = DateUtils.toCalendar(date1); // long→Calendar Calendar cal3 = Calendar.getInstance(); cal3.setTimeInMillis(System.currentTimeMillis());
long型(ミリ秒)の現在/指定日時を作成する。
// 現在日時 long nowMsec1 = System.currentTimeMillis(); // 指定日時 long msec1 = System.currentTimeMillis() - 24 * 60 * 60 * 1000; // Date→long long msec2 = date1.getTime(); // Calendar→long long msec3 = cal1.getTimeInMillis();
文字列の現在/指定日時を作成する。
// Date→文字列 DateFormat timestampFormat1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); String str1 = timestampFormat1.format(date1); // Date→文字列(Apache Commons Lang) String str1b = DateFormatUtils.format(date1, "yyyy/MM/dd HH:mm:ss.SSS"); // Calendar→文字列 String str2 = format.format(cal1.getTime()); // long→文字列 String str3 = format.format(new Date(msec1));
日時から日付の取り出し
// Date 日時→日付(時刻ゼロ) Calendar tmpCal1 = Calendar.getInstance(); tmpCal1.setTime(date1); Calendar tmpCal2 = new GregorianCalendar(tmpCal1.get(Calendar.YEAR), tmpCal1.get(Calendar.MONTH), tmpCal1.get(Calendar.DATE)); Date ymdDate1 = tmpCal2.getTime(); // Calendar 日時→日付(時刻ゼロ) Calendar ymdCal1 = new GregorianCalendar(cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH), cal1.get(Calendar.DATE)); // Date 日時→日付(時刻ゼロ)(Apache Commons Lang) Date ymdDate2 = DateUtils.truncate(date1, Calendar.DATE); // Calendar 日時→日付(時刻ゼロ)(Apache Commons Lang) Calendar ymdCal2 = DateUtils.truncate(cal1, Calendar.DATE); // 上記以外に、書式"yyyy/MM/dd"のフォーマットで文字列として取得することも可能。
日時から時刻の取り出し
// 時刻のみを取り出すことは出来ない模様。 // 必要なら、書式"HH:mm:ss"のフォーマットで文字列として取得する(?)
曜日の取得
// Dateから曜日取得 // ※ロケールによって曜日の表記が変わる。 DateFormat weekFormat1 = new SimpleDateFormat("E", Locale.JAPANESE); DateFormat weekFormat2 = new SimpleDateFormat("EEEE", Locale.JAPANESE); String weekStr1 = weekFormat1.format(date1); String weekStr2 = weekFormat2.format(date1); // Calendarから曜日取得 int weekInt1 = cal1.get(Calendar.DAY_OF_WEEK); String[] weekNames = new String[] { "日", "月", "火", "水", "木", "金", "土" }; String weekStr3 = weekNames[weekInt1 - 1]; // Java6では、Calendar.getDisplayNameメソッドが使える。 String weekStr4 = cal1.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.JAPANESE); String weekStr5 = cal1.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.JAPANESE); // Dateから曜日取得(Apache Commons Lang) // ※ロケールによって曜日の表記が変わる。 String weekStr6 = DateFormatUtils.format(date1, "E", Locale.JAPANESE); String weekStr7 = DateFormatUtils.format(date1, "EEEE", Locale.JAPANESE); // Calendarから曜日取得(Apache Commons Lang) // ※ロケールによって曜日の表記が変わる。 String weekStr8 = DateFormatUtils.format(cal1, "E", Locale.JAPANESE); String weekStr9 = DateFormatUtils.format(cal1, "EEEE", Locale.JAPANESE);
日時計算
加算/減算
// Date 1秒後、1日後 // ※Java5では、TimeUnitが使えるようになった。 Date nextSecDate = new Date(msec1 + TimeUnit.SECONDS.toMillis(1)); Date nextDayDate = new Date(msec1 + TimeUnit.DAYS.toMillis(1)); // Calendar 1秒後、1日後、1ヶ月後 Calendar nextSecCal = (Calendar) cal1.clone(); nextSecCal.add(Calendar.SECOND, 1); Calendar nextDayCal = (Calendar) cal1.clone(); nextDayCal.add(Calendar.DATE, 1); Calendar nextMonthCal = (Calendar) cal1.clone(); nextMonthCal.add(Calendar.MONTH, 1); // Date 1秒後、1日後(Apache Commons Lang) Date nextSecDate2 = DateUtils.addSeconds(date1, 1); Date nextDayDate2 = DateUtils.addDays(date1, 1); Date nextMonthDate2 = DateUtils.addMonths(date1, 1);
月初/月末を求める。
// Calendar 月初、月末 Calendar monthBeginning = (Calendar) cal1.clone(); monthBeginning.set(Calendar.DATE, 1); Calendar monthEnd = (Calendar) cal1.clone(); monthEnd.set(Calendar.DATE, cal1.getActualMaximum(Calendar.DATE));
差を求める。
// Date 日時の差 ミリ秒単位、日数単位(切り捨て) // ※日付の差がほしいときは、日時→日付のみに変換して計算する。 long dateDiffMsec = nextDayDate.getTime() - date1.getTime(); long dateDiffDays = (nextDayDate.getTime() - date1.getTime()) / TimeUnit.DAYS.toMillis(1); // Calendar 日時の差 ミリ秒単位、日数単位(切り捨て) // ※日付の差がほしいときは、日時→日付のみに変換して計算する。 long calDiffMsec = nextDayCal.getTimeInMillis() - cal1.getTimeInMillis(); long calDiffDays = (nextDayCal.getTimeInMillis() - cal1.getTimeInMillis()) / TimeUnit.DAYS.toMillis(1); // Date 日付の差(Apache Commons Lang) long dateDiffDays2 = (DateUtils.truncate(nextDayDate, Calendar.DATE).getTime() - DateUtils.truncate(date1, Calendar.DATE).getTime()) / TimeUnit.DAYS.toMillis(1); // Calendar 日付の差(Apache Commons Lang) long calDiffDays2 = (DateUtils.truncate(nextDayCal, Calendar.DATE).getTimeInMillis() - DateUtils.truncate(cal1, Calendar.DATE).getTimeInMillis()) / TimeUnit.DAYS.toMillis(1);
比較する。
// Dateの前後比較 boolean dateBeforeFlag = date1.before(nextDayDate); boolean dateAfterFlag = nextDayDate.after(date1); // Calendarの前後比較 boolean calBeforeFlag = cal1.before(nextDayCal); boolean calAfterFlag = nextDayCal.after(cal1); // Date 日付一致確認(Apache Commons Lang) // ※時刻は無視して、日付のみ比較される。 boolean dateSameFlag = DateUtils.isSameDay(date1, nextSecDate); // Calendar 日付一致確認(Apache Commons Lang) // ※時刻は無視して、日付のみ比較される。 boolean calSameFlag = DateUtils.isSameDay(cal1, nextSecCal);
参考
- Java日付処理メモ(Hishidama's Java Date Memo) http://www.ne.jp/asahi/hishidama/home/tech/java/date.html
- 日時に関する情報を取得する(get) - Calendarクラス http://www.javadrive.jp/start/calendar/index2.html
Javaで日時を扱う(Java8)
Java8では、日時を扱うクラス群が様変わりしてしまいました。これを機に、日時の扱いをまとめてみたいと思います。前回は、Java7までの日時、今回は、Java8での日時を書きました。
Java8では、Java7までのDate,Calendarの代替として、次のクラスなどが導入されましたね。
現在/指定日時の作成
Instantクラスの現在/指定日時を作成する。
// 現在日時 Instant nowInstant = Instant.now(); // long→Instant Instant instant2 = Instant.ofEpochMilli(msec1); // LocalDateTime→Instant Instant instant3b = localDt1.toInstant(ZoneId.systemDefault().getRules().getOffset(Instant.EPOCH)); // ZonedDateTime→Instant Instant instant4ca = zonedDt1.toInstant(); Instant instant4cb = Instant.from(zonedDt1); // 文字列→Instant Instant instant5 = Instant.parse("2007-12-03T10:15:30.00Z");
LocalDateTimeクラスの現在/指定日時を作成する。
// 現在日時 LocalDateTime nowLocalDt = LocalDateTime.now(); // 指定日時 LocalDateTime localDt2 = LocalDateTime.of(2016, 5, 2, 15, 0, 0); // long→LocalDateTime LocalDateTime localDt3 = LocalDateTime.ofInstant(Instant.ofEpochMilli(msec1), ZoneId.systemDefault()); // Instant→LocalDateTime LocalDateTime localDt4 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault()); // ZonedDateTime→LocalDateTime LocalDateTime localDt5a = zonedDt1.toLocalDateTime(); LocalDateTime localDt5b = LocalDateTime.from(zonedDt1); // 文字列→LocalDateTime LocalDateTime localDt6a = LocalDateTime.parse("2007-12-03T10:15:30.123"); LocalDateTime localDt6b = LocalDateTime.parse("2007/12/03 10:15:30.123", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS"));
ZonedDateTimeの現在/指定日時を作成する。
// 現在日時 ZonedDateTime nowZonedDt = ZonedDateTime.now(ZoneId.of("Asia/Tokyo")); // 指定日時 ZonedDateTime zonedDt2 = ZonedDateTime.of(2016, 5, 2, 15, 0, 0, 0, ZoneId.of("Asia/Tokyo")); // long→ZonedDateTime ZonedDateTime zonedDt3 = ZonedDateTime.ofInstant(Instant.ofEpochMilli(msec1), ZoneId.systemDefault()); // Instant→ZonedDateTime ZonedDateTime zonedDt4a = instant1.atZone(ZoneId.systemDefault()); ZonedDateTime zonedDt4b = ZonedDateTime.ofInstant(instant1, ZoneId.systemDefault()); // LocalDateTime→ZonedDateTime ZonedDateTime zonedDt5a = localDt1.atZone(ZoneId.systemDefault()); ZonedDateTime zonedDt5b = ZonedDateTime.ofLocal(localDt1, ZoneId.systemDefault(), null); // 文字列→ZonedDateTime型 ZonedDateTime zonedDt6a = ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Paris]"); ZonedDateTime zonedDt6b = ZonedDateTime.parse("2016/05/02 10:15:30 Asia/Tokyo", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss VV")); ZonedDateTime zonedDt6c = ZonedDateTime.parse("2016/05/02 10:15:30 JST", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss zzz"));
文字列の現在/指定日時を作成する。
// Instant→文字列 String instantStr1 = DateTimeFormatter.ISO_INSTANT.format(instant1); String instantStr2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS") .format(LocalDateTime.ofInstant(instant1, ZoneId.systemDefault())); // LocalDateTime→文字列 String localStr1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS").format(localDt1); // ZonedDateTime→文字列 // "xxxxx VV" - (例)"+09:00 Asia/Tokyo" // "xxxx zzz" - (例)"+0900 JST" String zonedStr1a = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSSxxxxx VV").format(zonedDt1); String zonedStr1b = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSSxxxx zzz").format(zonedDt1);
日時から日付/時刻の取り出し
// Instant 日時→日付 Instant ymdInstant1 = instant1.truncatedTo(ChronoUnit.DAYS); // LocalDateTime 日時→日付、時刻 LocalDate localDate1 = localDt1.toLocalDate(); LocalTime localTime1 = localDt1.toLocalTime(); // ZonedDateTime 日時→日付、時刻 ZonedDateTime ymdZoned1 = zonedDt1.truncatedTo(ChronoUnit.DAYS); LocalDate localDate2 = zonedDt1.toLocalDate(); LocalTime localTime2 = zonedDt1.toLocalTime();
曜日の取得
// Instant→曜日 String instantWeek1 = DateTimeFormatter.ofPattern("E, EEEE", Locale.JAPANESE) .format(LocalDateTime.ofInstant(instant1, ZoneId.systemDefault())); String instantWeek2 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault()).getDayOfWeek() .getDisplayName(TextStyle.FULL, Locale.JAPANESE); // LocalDateTime→曜日 // ※"E","EEEE"は、タイムゾーンによって曜日の表記が変わる。 String localWeek1 = DateTimeFormatter.ofPattern("E, EEEE", Locale.JAPANESE).format(localDt1); String localWeek2 = localDt1.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.JAPANESE); // ZonedDateTime→曜日 // ※"E","EEEE"は、タイムゾーンによって曜日の表記が変わる。 String zonedWeek1 = DateTimeFormatter.ofPattern("E, EEEE", Locale.JAPANESE).format(zonedDt1); String zonedWeek2 = zonedDt1.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.JAPANESE);
日時計算
加算/減算
// LocalDateTime 1秒後、1日後、1ヶ月後 LocalDateTime localNextSec = localDt1.plusSeconds(1); LocalDateTime localNextDay = localDt1.plusDays(1); LocalDateTime localNextMonth = localDt1.plusMonths(1); // ZonedDateTime 1秒後、1日後、1ヶ月後 ZonedDateTime zonedNextSec = zonedDt1.plusSeconds(1); ZonedDateTime zonedNextDay = zonedDt1.plusDays(1); ZonedDateTime zonedNextMonth = zonedDt1.plusMonths(1);
月初/月末を求める。
// LocalDateTime 月初、月末 LocalDateTime localMonthBeginning = localDt1.with(TemporalAdjusters.firstDayOfMonth()); LocalDateTime localMonthEnd = localDt1.with(TemporalAdjusters.lastDayOfMonth()); // ZonedDateTime 月初、月末 ZonedDateTime zonedMonthBeginning = zonedDt1.with(TemporalAdjusters.firstDayOfMonth()); ZonedDateTime zonedMonthEnd = zonedDt1.with(TemporalAdjusters.lastDayOfMonth());
差を求める。
// LocalDateTime 日時の差 ミリ秒単位、日数単位(切り捨て) long localDiffMsec = ChronoUnit.MILLIS.between(localDt1, localNextDay); long localDiffDays1 = ChronoUnit.DAYS.between(localDt1, localNextDay); long localDiffDays2 = ChronoUnit.DAYS.between(localDt1.toLocalDate(), localNextDay.toLocalDate()); // LocalDateTime 日時の差 時分秒単位、年月日単位 Duration localDuration = Duration.between(localDt1, localNextDay); Period localPeriod = Period.between(localDt1.toLocalDate(), localNextDay.toLocalDate()); // ZonedDateTime 日時の差 ミリ秒単位、日数単位(切り捨て) long zonedDiffMsec = ChronoUnit.MILLIS.between(zonedDt1, zonedNextDay); long zonedDiffDays1 = ChronoUnit.DAYS.between(zonedDt1, zonedNextDay); long zonedDiffDays2 = ChronoUnit.DAYS.between(zonedDt1.toLocalDate(), zonedNextDay.toLocalDate()); // ZonedDateTime 日時の差 時分秒単位、年月日単位 Duration zonedDuration = Duration.between(zonedDt1, zonedNextDay); Period zonedPeriod = Period.between(zonedDt1.toLocalDate(), zonedNextDay.toLocalDate());
比較する。
// LocalDateTime boolean localAfterFlag = localNextDay.isAfter(localDt1); // ZonedDateTime boolean zonedAfterFlag = zonedNextDay.isAfter(zonedDt1);
参考
- Java日付処理メモ(Hishidama's Java Date Memo) http://www.ne.jp/asahi/hishidama/home/tech/java/date.html
- 日時に関する情報を取得する(get) - Calendarクラス http://www.javadrive.jp/start/calendar/index2.html
- Java日付時刻APIメモ(Hishidama's Java8 Date and Time API Memo) http://www.ne.jp/asahi/hishidama/home/tech/java/datetime.html
- Java日付時刻フォーマッターメモ(Hishidama's Java8 DateTimeFormatter Memo) http://www.ne.jp/asahi/hishidama/home/tech/java/DateTimeFormatter.html