5
3

More than 3 years have passed since last update.

【Java】日付/時刻の操作

Last updated at Posted at 2020-11-01

日付/時刻の操作

  • 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分前
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]
    }
}
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3