■日付操作クラス
はじめに
DateクラスやCalendarクラスを使用すると、
特定の日付と時刻に関するプログラムについて操作することができます。
java.utilパッケージ内には、コレクションの他に日付操作クラスなどのクラスもあります。
現場では、プログラムの処理中の 「値」 だけではなく、
「時間」 も大切な情報として記録することがほとんどなので、しっかり身につけましょう!
※この記事内で基準となる日付は2019/03現在のものとなります
Step1: Dateクラス
Dateクラスは、日付を管理しているクラスです。
簡単に現在の日付と時刻を取得することができるクラスです。
ただし、日付の計算などを行う場合には、適していないクラスです。
例題
以下の通りコーディングし、Dateクラスのインスタンスを生成後、コンソールへ出力しなさい。
import java.util.Date; public class DateMain{ public static void main(String[] args){ Date now = new Date(); System.out.println(now); } }
【実行結果】
Mon Dec 12 14:25:22 JST 2011
補足
- ・タイムゾーン
- 出力内容の
JST
のことで、日本標準時刻が世界標準+9時間であることを示しています。
世界標準時刻は、 GMT(グリニッジ標準時) と呼ばれ、
その GMT を基準として、日本であれば JST 、アメリカであれば PST のように表記し、
「 GMT ± n時間の差 」があることを明示的に示します。
上記 GMT に微調整を加えた、 UTC(協定世界時) というものもありますが、
今は時刻の基準があるんだなーという認識で問題ありません。
(現場に出て、こういった時刻を扱うことが出てきたら「タイムゾーン」、「GMT」、「UTC」などについて詳しく調べてみるといいでしょう!
Step2: Calendarクラス
Calendarクラスは、日時の計算などを行う場合に使用します。
例えば、 「今日から1ヶ月と2週間後(45日後)」 というような
少しややこしい日付の計算をしなければいけない時に、この Calendarクラス
が活躍してくれます。
Step1に書いてある Dateクラス
とは、ここが違うポイントになりますね。
例題
以下の通りコーディングし、カレンダークラスの getTime()
メソッドを実行しなさい。
import java.util.Calendar; public class DateMain2 { public static void main(String[] args){ Calendar cal = Calendar.getInstance(); System.out.println(cal.getTime()); } }
【実行結果】
Thu Jun 06 19:22:17 JST 2019
new Date
の際の出力内容と同じフォーマットの結果値が得られます。
Calendarクラスに用意されている「主要フィールド」一覧
フィールド | 用途 |
---|---|
YEAR | 年 |
MONTH | 月(0~11) |
DATE, DAY_OF_MONTH | 現在の月の何日目かを表す |
WEEK_OF_MONTH | 現在の月の何週目かを表す |
DAY_OF_WEEK | 現在の週の何日目かを表す |
AM_PM | 午前午後を表す(午前0、午後1) |
HOUR | 午前または午後の何時かを表す(0~11) |
HOUR_OF_DAY | 24時制で何時かを表す |
MINUTE | 何分かを表す |
SECOND | 何秒かを表す |
例題
それでは、どのようにすれば 日付の計算 ができるのか、
下記に示すCalendarクラスのサンプルプログラムを作成して、実行してみましょう。
import java.util.Calendar; public class CalenMain { public static void main(String[] args) { // 今日が2020/06/27の場合の年月日を表示 Calendar cal = Calendar.getInstance(); System.out.println(cal.get(Calendar.YEAR)); System.out.println(cal.get(Calendar.MONTH) + 1); System.out.println(cal.get(Calendar.DATE)); } }
【実行結果】
2020 6 27
カレンダークラスで定義されている Calendar.MONTH
は
JANUARY(実値=0)〜UNDECIMBER(実値=11)
まで定義が存在し、
実際の月の値は、「-1
」の値を保持しているため、
上記では「+1
」することで実際に表示される月の値を調整しています。
また、繰り上げや繰り下げの対応をしたい場合、getメソッドで対応してしまうと、あくまで「月の値 + 1」であるため、「13月、14月、15月」という表示になってしまいますし、年の加算減算はしてくれません。
では、どのような方法を取るべきかというと、下記メソッドを使用します。
cal.add(年月日, 調整したい値(マイナス値も可))
※+する値は現在日時によって変ります。
// addメソッドを使用して+7する cal.add(Calendar.MONTH, 7);
【実行結果】
2021 1 27
上記のようにすることで、正常な値を設定可能です。
補足
- ・うるう年
- 上記は正しい書き方にはなりますが、例外もあります。
それが「 うるう年 」の場合です。
【条件】
- 西暦年号が4で割り切れる年
- ただし西暦年号が100で割り切れて400で割り切れない年は平年(100で割り切れない場合、100で割り切れても400で割れる場合はうるう年)
/** * うるう年判定 * @param year */ public static void printLeapYear(final int year) { boolean isLeapYear = false; if (year % 4 == 0) { if ((year % 100) == 0) { isLeapYear = ((year % 400) == 0); } else { isLeapYear = true; } } System.out.println(year + "年はうるう年" + (isLeapYear ? "です。" : "ではありません。")); }
カレンダーの設定が合っているのにもかかわらず想定している日付とならない場合は、
うるう年のチェックをしてみるといいでしょう!
Step3: Timeクラス
JDK1.8からTimeクラスが追加されました。
このクラスはDateクラスとCalendarクラスの両方の特徴があり、
データ保持と日付操作がTimeクラス1つで行うことができます。
Timeクラスには、LocalDateとLocaltimeのインスタンスを持つLocalDateTime、LocalDateTimeに加え
オフセット(標準時との時差)を含むOffsetDateTime、OffsetDateTimeに加えタイムゾーンを含む
ZonedDateTimeがあります。
例
import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; public class TimeMain { public static void main(String[] args) { LocalDateTime ldtNow = LocalDateTime.now(); System.out.println(ldtNow.toString()); OffsetDateTime odtNow = OffsetDateTime.now(); System.out.println(odtNow.toString()); ZonedDateTime zdtNow = ZonedDateTime.now(); System.out.println(zdtNow.toString()); } }
【実行結果】
2019-03-06T13:49:52.685599 2019-03-06T13:49:52.686943+09:00 2019-03-06T13:49:52.690983+09:00[Asia/Tokyo]
TimeクラスはDateクラスやCalendarクラスと異なり、直接値を変更することはできません。
日時などの値を変更する場合はインスタンスを生成しなおす必要があります。
また、月の値の対応もCalendarクラスと異なっており、月が1の場合、そのまま1月として出力されます。
import java.time.LocalDateTime; public class LocalDateWithMonth { public static void main(String[] args) { LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt.getMonthValue() + "月"); ldt = ldt.withMonth(12); System.out.println(ldt.getMonthValue() + "月"); } }
【実行結果】
3月 12月
補足
- ・
isLeap()
メソッド - 前述でうるうどしの説明がありましたが、
TimeクラスにはYear
クラスというものが存在し、そのYear
クラスでは、
うるう年を判定する staticメソッドが用意されています。
【サンプル: うるう年判定】
// 変数 year が 2020の場合 System.out.println(year + "年は、うるう年" + (Year.isLeap(year) ? "です。" : "ではありません。"));
【出力結果】
2020年は、うるう年です。
とても簡単に使用できますね。
ロジックを考えることって大切ですが、
開発者に優しいJava標準のAPIが実装されているならば、それを使わない手はありません!
・条件演算子(三項演算子)
うるう年判定 isLeap()
メソッドでさらっと出ていますが…
条件演算子は三項演算子とも呼ばれる演算子で、条件によって処理を分けることができます。
条件式 ? 式1 : 式2
条件式の値が true (真) だった場合に式1に処理し、false (偽) だった場合に式2を処理します。
参考
Calendarクラスのサマリー
Calendarにまつわるプロパティやメソッドの仕様が記載されています。
カリキュラムに記載されていない内容で確認したい、使ってみたいものがあった場合に一度目を通すといいでしょう。
課題
Java2章からはEclipseでの課題対応となります。
※ プロジェクトの作成方法については Eclipseの使い方 を参考にしてください。
プロジェクト名・・・ 2-6
パッケージ名1 ・・・ study
Java クラス名 ・・・ Study.java (下記コードをコピー)
package study; import java.time.Year; import java.util.Calendar; import java.util.Date; /** * * 本課題では、基本的な日付操作クラスの使い方を学びましょう。 * * 問①から問③まであります。 * 問②に関しては、コメントを記述してください。 * * ※この課題に関しては課題実施日によって結果が異なるため、出力結果が個々で異なります。 */ public class Study { public static void main(String args[]) { // Dateクラスのインスタンスを生成 Date now = new Date(); // 問① ローカル変数「now」を使用し、本日の日付を表示してください。 // Calendarクラスのインスタンスを生成 Calendar calendar = Calendar.getInstance(); // 問② 以下の「Calendar.MONTH) + 1」の処理は、想定していない値となる可能性があります。 // その理由をコメントへ記述してください。 // [ここへ記述] System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH) + 1); System.out.println(calendar.get(Calendar.DATE)); // 問③ 上記の「calendar」を使用し、本日から1年2ヶ月15日先の日付を表示しなさい。 // - この課題に関しては課題実施日によって結果が異なりますので、Wiki課題の画像とは結果が異なります。 // - また、うるう年の場合は設定内容が正しくとも日付がズレて表示される可能性があります。 // うるう年判定 printLeapYear(calendar.get(Calendar.YEAR)); } /** * うるう年判定 * 問③で日付がズレる可能性があるため補足として出力 * @param year */ private static void printLeapYear(final int year) { System.out.println(year + "年は、うるう年" + (Year.isLeap(year) ? "です。" : "ではありません。")); } }
以下の添付画像のようにコンソールへ出力されるよう課題を実施し提出してください。
※ 今回のコードは課題実施日によって出力が異なりますので、あくまで参考としてください。
課題を提出するときには、「2-6」ディレクトリ配下にあるすべてのファイルをコミット、プッシュしてください。