日付/時刻の操作
- Date-Time-APIを使おう(Java8以降)
現在時間取得
- LocalDateは日時
- LocalTimeは時間
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
public class Main {
//現在日時・時刻を取得
public static void main(String[] args) {
System.out.println(LocalDateTime.now()); //2020-10-31T07:49:16.502455881
System.out.println(OffsetDateTime.now()); //2020-10-31T07:49:16.503291965Z
System.out.println(ZonedDateTime.now()); //020-10-31T07:49:16.504062367Z[Etc/UTC]
System.out.println(LocalDate.now()); //2020-10-31
System.out.println(LocalTime.now()); //07:49:16.504349859
}
}
特定の日時・時刻を取得
- LocalDateTime.ofメソッド
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
//特定の日時・時刻を取得
public static void main(String[] args) {
//年月日・時分秒ナノ秒から日時を生成
var ldt1 = LocalDateTime.of(2019, 1, 10, 10, 20, 30, 513);
var ldt2 = LocalDateTime.of(2019, Month.JANUARY, 10, 10, 20, 30);
//var ldt3 = LocalDateTime.of(2019, 1, 40, 10, 20, 30); //範囲外なのでエラー
System.out.println(ldt1); //2019-01-10T10:20:30.000000513
System.out.println(ldt2); //2019-01-10T10:20:30.000000513
//日付・時間のみ生成
var ld = LocalDate.of(2019, 1, 10);
System.out.println(ld); //2019-01-10
var lt = LocalTime.of(10, 20, 30);
System.out.println(lt); //10:20:30
var ldt4 = LocalDateTime.of(ld, lt);
System.out.println(ldt4); //2019-01-10T10:20:30
//タイムゾーンオフセット値(ZoneOffsetオブジェクト)
var odt = OffsetDateTime.of(2019, 1, 10, 10, 20, 30, 999, ZoneOffset.ofHours(9));
System.out.println(odt); //2019-01-10T10:20:30.000000999+09:00
var ot = OffsetTime.of(10, 20, 30, 999, ZoneOffset.ofHours(9));
System.out.println(ot); //10:20:30.000000999+09:00
var zdt = ZonedDateTime.of(2019, 1, 10, 10, 20, 30, 999, ZoneId.of("Asia/Tokyo"));
System.out.println(zdt); //2019-01-10T10:20:30.000000999+09:00[Asia/Tokyo]
}
}
日付時刻文字列を変換
-
parseメソッド
- formatterを指定すると、指定形式で解析された値を取得できる
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
//日付・時刻文字列から変換
public static void main(String[] args) {
//ISO日付
System.out.println(LocalDate.parse(
"2019-01-01", DateTimeFormatter.ISO_DATE)); //2019-01-01
//年と日数
System.out.println(LocalDate.parse(
"2019-123", DateTimeFormatter.ISO_ORDINAL_DATE)); //2019-05-03
//年と週数
System.out.println(LocalDate.parse(
"2019-W40-5", DateTimeFormatter.ISO_WEEK_DATE)); //2019-10-04
//タイムゾーンID付き日時
System.out.println(ZonedDateTime.parse(
"2019-01-10T10:20:30.000000999+09:00[Asia/Tokyo]",
DateTimeFormatter.ISO_DATE_TIME)); //2019-01-10T10:20:30.000000999+09:00[Asia/Tokyo]
}
}
日付時刻を比較
- equals / isBefore / isAfter
import java.time.LocalDateTime;
public class Main {
public static void main(String[] args) {
var dt1 = LocalDateTime.of(2019, 12, 31, 10, 20, 30);
var dt2 = LocalDateTime.of(2020, 1, 1, 10, 20, 30);
System.out.println(dt1.equals(dt2)); //false
System.out.println(dt1.isBefore(dt2)); //true
System.out.println(dt1.isAfter(dt2)); //false
}
}
時刻要素取得
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
public class Main {
public static void main(String[] args) {
var dt = LocalDateTime.of(2019, 1, 10, 10, 20, 30, 123);
var week = new String[] {"日曜日", "月曜日", "火曜日", "水曜日","木曜日", "金曜日", "土曜日"};
System.out.println(dt.getYear() + "年" +dt.getMonthValue() + "月" +dt.getDayOfMonth() + "日 " +dt.getDayOfWeek() + " " +dt.getHour() + "時" +dt.getMinute() + "分"+ dt.getSecond() + "秒"+ dt.getNano() + "ナノ秒");
System.out.println("月名は" + dt.getMonth() +" 今年" + dt.getDayOfYear() + "日目"); //月名はJANUARY 今年10日目
//ChronoFieldで時間取得
System.out.println(dt.get(ChronoField.YEAR) + "年" +dt.get(ChronoField.MONTH_OF_YEAR) + "月" +dt.get(ChronoField.DAY_OF_MONTH) + "日" +week[dt.get(ChronoField.DAY_OF_WEEK) -1] + " "+dt.get(ChronoField.HOUR_OF_DAY) + "時" +dt.get(ChronoField.MINUTE_OF_HOUR) + "分" +dt.get(ChronoField.SECOND_OF_MINUTE) + "秒" +dt.get(ChronoField.NANO_OF_SECOND) + "ナノ秒");
}
} //2019年1月10日水曜日 10時20分30秒123ナノ秒
日付時間を整形
- DateTimeFormatterメソッドの引数に応じて整形
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
public class Main {
public static void main(String[] args) {
var dt1 = LocalDateTime.of(2020, 11, 1, 10, 20, 30);
var dt2 = ZonedDateTime.of(2019, 11, 1, 10, 20, 30, 0, ZoneId.of("Asia/Tokyo"));
System.out.println(dt1.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL))); //Sunday, November 1, 2020
System.out.println(dt2.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG))); //November 1, 2019 at 10:20:30 AM JST
System.out.println(dt1.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM))); //Nov 1, 2020
System.out.println(dt2.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT))); //11/1/19, 10:20 AM
}
}
-
DateTimeFormatter.ofPatternメソッドで好きな形に整形
- 標準フォーマットの方が、ロケールに合わせて適切な書式(英語とか)にしてくれるのでおすすめ
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
var dt1 = LocalDateTime.of(2020, 11, 1, 10, 20, 30);
var dt2 = ZonedDateTime.of(2020, 11, 1, 10, 20, 30, 0, ZoneId.of("Asia/Tokyo"));
System.out.println(dt1.format(DateTimeFormatter.ofPattern("y.MM.dd H:m:s"))); //2020.11.01 10:20:30
System.out.println(dt2.format(DateTimeFormatter.ofPattern("Y年L月d日(E)a K時m分s秒 (z)"))); //2020年11月1日(Sun)AM 10時20分30秒 (JST)
}
}
-
JapaneseDate.ofメソッドで元号から日付生成
-
var d = JapaneseDate.of(JapaneseEra.REIWA, 1, 1, 1);
はError
-
//和暦
import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
var d = JapaneseDate.of(JapaneseEra.REIWA, 2, 1, 1);
System.out.println(d); //Japanese Reiwa 2-01-01
//Gが元号
var df = DateTimeFormatter.ofPattern("Gy年MM月dd日");
System.out.println(d.format(df)); //Reiwa2年01月01日
}
}
日付時刻の差分差分
- Period(日付) / Duration(時間) クラスのbetweenメソッド
- Periodの引数は一旦toLocalDateでLocalDateに変換する必要
- Durationの引数はTemporal型:LocalDateやZonedDate系のインスタンスを全部受け取れる
//日数経過カウント
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Period;
public class Main {
public static void main(String[] args) {
var dt1 = LocalDateTime.of(2019, 12, 31, 0, 0, 0);
var dt2 = LocalDateTime.of(2020, 11, 1, 10, 20, 30);
var period = Period.between(dt1.toLocalDate(), dt2.toLocalDate());
System.out.println("日付の差:" +
period.getYears() + "年" + period.getMonths() + "ヶ月" +
period.getDays() + "日間"); //日付の差:0年10ヶ月1日間
var duration = Duration.between(dt1, dt2);
System.out.println("時間の差:" + duration.toHours() + "時間"); //時間の差:7354時間
}
}
日付加算減算
-
plus / minus メソッド
- plusYears / plusWeeks のように時間計算に特化したメソッドもある
//x年後,y日前の日付
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
var d = LocalDate.of(2020, 11, 1);
System.out.println(d); //2020-11-01
//3年後
System.out.println(d.plus(3, ChronoUnit.YEARS)); //2023-11-01
//22日前
System.out.println(d.minus(22, ChronoUnit.DAYS)); //2020-10-10
}
}
- Period/Durationを渡して日付間隔で加算減算
- Period:P<日付>
-
P2Y2M
=2年2ヶ月
-
- Duration:P<日付>T<時間>
-
-P1DT5M
=1日5分前
-
- Period:P<日付>
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Period;
public class Main {
public static void main(String[] args) {
var d = LocalDateTime.of(2020, 11, 1, 10, 20, 30);
var period = Period.ofYears(3);
//P<日付>T<時間>
var duration = Duration.parse("P22DT1H1M1S"); //22日1時間1分1秒
System.out.println(d); //2020-11-01T10:20:30
System.out.println(d.plus(period)); //2023-11-01T10:20:30
System.out.println(d.minus(duration)); //2020-10-10T09:19:29
}
}
Calenderクラス(Java7以前)
-
toInstantメソッドでCalendeからDate-TimeAPIに変換
- toInstantメソッド:1970/1/1からの経過時間を保持
- ofInstantメソッドでLocalDateTimeなどのオブジェクト生成
//CalenderからDate-TimeAPIに変換
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
var cal = Calendar.getInstance();
var dt1 = LocalDateTime.ofInstant(cal.toInstant(), ZoneId.systemDefault());
var dt2 = OffsetDateTime.ofInstant(cal.toInstant(), ZoneId.systemDefault());
var dt3 = ZonedDateTime.ofInstant(cal.toInstant(), ZoneId.systemDefault());
System.out.println(dt1); //2020-11-01T03:30:12.156
System.out.println(dt2); //2020-11-01T03:30:12.156Z
System.out.println(dt3); //2020-11-01T03:30:12.156Z[Etc/UTC]
}
}
- Date-TimeAPIからCalenderに変換
- Calendarの精度はミリ秒なのでミリ秒以下切り捨て
- 生成したInstantオブジェクトをDate.fromメソッドで受け取りDateオブジェクト生成
- setTimeメソッドでDateからCalendarに値を入れる
//Date-TimeAPIからCalenderに変換
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
var dt = LocalDateTime.of(2020, 11, 1, 10, 20, 30, 123456789);
var d = Date.from(dt.toInstant(ZoneOffset.of("+09:00")));
//setTimeメソッドでDateからCalendarに値を入れる
var cal = Calendar.getInstance();
cal.setTime(d);
System.out.println(cal); //java.util.GregorianCalendar[time=1604193630123,,(略),,AM_PM=0,HOUR=1,HOUR_OF_DAY=1,MINUTE=20,SECOND=30,MILLISECOND=123,ZONE_OFFSET=0,DST_OFFSET=0]
}
}