1. カレンダーの概要
Java では、Date の使用を置き換えるために、Calendar を使用することを公式に推奨しています。変換のリンクは、Calendar の getTime() メソッドを使用して Date 型オブジェクトを取得します。このオブジェクトの最下層は、Long 型パラメーターを持つ Date の 2 番目のコンストラクターを使用して作成されます。この Long 型パラメーターは、Calendar の時刻フィールドに保存された値です。たとえば、この時刻フィールドの値は、特定の実装クラスで定義されます。 、GregorianCalendar の computeTime() の実装。このメソッドの目的は、Calendar の 2 つのモードと、Calendar の setTime(Date date) メソッドを使用して、フィールド値を時刻値に変換することです。 Date オブジェクトは、Calendar オブジェクトに変換されます。このメソッドは、最下位層によって呼び出される setTimeInMillis(long millis) メソッドの値を受け取ります。 ) をパラメーターとして指定し、最下層で Long パラメーター値を時間フィールドに割り当てます。フィールド値はこの時点で再計算されます。
カレンダーと日付の変換
1 public static void main(String[] args) { 2 //Calendar--->Date 3 Calendar c = Calendar.getInstance(); 4 Date d = c.getTime(); 5 //Date--->Calendar 6 Date d1 = new Date(); 7 Calendar c1 = Calendar.getInstance(); 8 c1.setTime(d1); 9 10 System.out.println(d);11 System.out.println(c1.get(Calendar.YEAR)+"年"+(c1.get(Calendar.MONTH)+1)+"月"+c1.get(Calendar.DATE)+"日");12 }
結果:
Sat Jul 08 10:39:14 CST 20172017年7月8日
2. カレンダーの時間とフィールド
カレンダーには時間の内容を記述するフィールドが 2 つあり、1 つは時間で、カレンダーを保存するために使用されます。オブジェクトによって表される時点は、1970 年 1 月 1 日の 00:00:00 のミリ秒数に基づいています。もう 1 つはフィールドであり、これは内容を表しませんが、カレンダー内で定義されている最も静的な定数です。 。 分野。
これは一般に同期、つまり同じ時点を表しますが、同期していない場合もあります:
a. 最初はフィールドが設定されておらず、時間は無効です
b. 時間が設定されている場合。設定すると、すべてのフィールドが同期された時点に自動的に設定されます
c. 特定のフィールドが個別に設定されている場合、時間は自動的に期限切れになります
より正確には、Calendar.getInstance()メソッドで新しい値を取得したときに、オブジェクトの場合、それが表す時点は時間を通じて設定され、この時間の値は System.currentTimeMillis() を通じて取得されます。カレンダーは時間を通じて定義され、 isTimeSet は true であり、時間値が最新 ( true ) であることを示します。 areFieldsSet は false です。これは、フィールドフィールドの値がすべて古い (false) ことを意味します。これは、時間値をリセットすると、Calendar で表される時点が変更されたためです (これが初めてであり、開始と同等です)。はい、これは変更とみなされます。後でカレンダーの時間の新しい値をリセットすると、カレンダーの時点は再び変更され、最新の時間値で表される時点を指します。フィールドにまだ何かがある場合は、元の時点のコンテンツを表し、フィールド内の値が時間と同期していることを確認するためにすべてのフィールド値を再計算するために computeFields() メソッドが呼び出されます。同時に、areFieldsSet と areAllFieldsSet は true に設定され、すべてのフィールドで表される時刻も最新 (true) であることを示します。実際、時間値を変更するたびに、2 つのドメインによって記述される時点が一貫している (つまり、同期している) ことを確認するために自動的に再計算がトリガーされます。これは、上記の b で説明したとおりです。
ただし、set(int field, int value) によってフィールド内の行とフィールドを個別に変更すると、areFieldsSet が true で areAllFieldsSet が false の場合、フィールドの一部のみが変更されることを意味します。最新、つまり一部のフィールドが古い場合、フィールドの再計算がトリガーされ、その後、isTimeSet が false に設定され、areFieldsSet が false に設定されます。 true (現在のフィールドは true に設定されます) に設定します。この場合、 getTime() を使用して時間値で表される時点を取得すると、 isTimeSet が false であるため、時間の再計算がトリガーされます。フィールドの値に基づいて isTimeSet を true に設定します。同様に、get(int field) を通じてフィールド値を取得するときは、まず isTimeSet が true であるかどうかを確認します。 false の場合は、 isTimeSet の再計算もトリガーされます。次に、areFieldsSet が false であることを確認します。これにより、残りのフィールドの再計算がトリガーされます。
時間の再計算はフィールドに基づいており、正確には一部のフィールドに基づいており、一部のフィールドもフィールドに基づいて再計算されるため、一部のフィールドは固定されており、時間と密接に関係していると言えます。
上記はすべて、外部的には単純な呼び出しのみが必要であり、外部メソッドを通じて取得したものが直接正しい値であることが保証されます。
1 public static void main(String[] args) throws ParseException { 2 System.out.println("-------初始情况-------"); 3 Calendar c = Calendar.getInstance(); 4 System.out.println(c.getTime()); 5 System.out.println(c.get(Calendar.DATE)); 6 System.out.println(c.get(Calendar.HOUR)); 7 System.out.println("-------重设置time-------"); 8 c.setTime(new SimpleDateFormat("yyyyMMdd").parse("20170501")); 9 System.out.println(c.getTime());10 System.out.println(c.get(Calendar.DATE));11 System.out.println(c.get(Calendar.HOUR));12 System.out.println("-------重设置field-------");13 c.set(Calendar.MONTH, 4);14 System.out.println(c.getTime());15 System.out.println(c.get(Calendar.DATE));16 System.out.println(c.get(Calendar.HOUR));17 System.out.println("总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成");18 }
結果:
-------初始情况-------Sat Jul 08 13:08:34 CST 2017 8 1 -------重设置time-------Mon May 01 00:00:00 CST 2017 1 0 -------重设置field-------Mon May 01 00:00:00 CST 2017 1 0总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成
3. カレンダーの 2 つの解析モード
寛容: このモードでは、ユーザーがカレンダーに割り当てた不規則な値は自動的に正規化されます。たとえば、1 月 32 日は次のように解析されます。 2 月 1 日
非寛大: このモードでは、不規則な入力は自動的に解析されませんが、不規則な入力が見つかると例外が報告されます
これはカレンダーのフォールト トレランスとも呼ばれ、カレンダーの開閉はlenient setLenient(boolean lenient) メソッドを使用して設定します。 true はフォールト トレランスをオンにすることを意味し (デフォルト)、false はこの機能をオフにすることを意味します。
结果:
Tue Oct 03 13:18:48 CST 2017Exception in thread "main" java.lang.IllegalArgumentException: DAY_OF_MONTH at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2583) at java.util.Calendar.updateTime(Calendar.java:2606) at java.util.Calendar.getTimeInMillis(Calendar.java:1118) at java.util.Calendar.getTime(Calendar.java:1091) at JdkTest.main(JdkTest.java:87)
从上面的例子中可以看出,默认情况下,我们为Calendar的月份赋值为8即九月份,日期赋值为33即下一月3号,输出为10月3日,容错性将这种不符合规则的输入规则化处理了,而关闭容错性之后,同样的赋值只会报异常java.lang.IllegalArgumentException(非法参数异常)。
4、Calendar的使用
1 public static void main(String[] args) throws ParseException { 2 //通过SimpleDateFormat解析日期字符串 3 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss.SSS"); 4 Date date = sdf.parse("20170502 13:33:23.433"); 5 //将Date格式日期转换成Calendar 6 Calendar c = Calendar.getInstance(); 7 c.setTime(date); 8 //获取时间值 9 System.out.println(c.getTime());10 System.out.println("年份为"+c.get(Calendar.YEAR));11 System.out.println("月份为"+c.get(Calendar.MONTH));12 System.out.println("日期为"+c.get(Calendar.DATE));13 System.out.println("日期为"+c.get(Calendar.DAY_OF_MONTH));14 System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK));15 System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));16 System.out.println("日期为"+c.get(Calendar.DAY_OF_YEAR));17 System.out.println("时为"+c.get(Calendar.HOUR));18 System.out.println("时为"+c.get(Calendar.HOUR_OF_DAY));19 System.out.println("分为"+c.get(Calendar.MINUTE));20 System.out.println("秒为"+c.get(Calendar.SECOND));21 System.out.println("毫秒为"+c.get(Calendar.MILLISECOND));22 System.out.println("星期为"+c.get(Calendar.WEEK_OF_MONTH));23 System.out.println("星期为"+c.get(Calendar.WEEK_OF_YEAR));24 System.out.println("历型为"+c.get(Calendar.ERA));25 System.out.println("zone为"+c.get(Calendar.ZONE_OFFSET));26 //设置27 c.set(Calendar.MONTH, Calendar.APRIL);28 System.out.println("修改后月份为"+c.get(Calendar.MONTH));29 c.set(1999, 0, 23);30 System.out.println(c.getTime());31 c.set(2000, 1, 12, 13, 33, 14);32 System.out.println(c.getTime());33 c.set(2001, 2, 13, 14, 13);34 System.out.println(c.getTime());35 //运算36 System.out.println("-----运算-----");37 c.add(Calendar.YEAR, 12);38 System.out.println(c.getTime());39 c.add(Calendar.MONTH, -1);40 System.out.println(c.getTime());41 c.roll(Calendar.DATE, true);42 System.out.println(c.getTime());43 c.add(Calendar.DATE, 1);44 System.out.println(c.getTime());45 //roll与add运算对比46 c.set(2000, 1, 29);47 System.out.println(c.getTime());48 c.roll(Calendar.DATE, 1);49 System.out.println(c.getTime());50 c.set(2000, 1, 29);51 c.add(Calendar.DATE, 1);52 System.out.println(c.getTime());53 }
结果:
Tue May 02 13:33:23 CST 2017年份为2017 月份为4 日期为2 日期为2 日期为3 日期为1 日期为122 时为1 时为13 分为33 秒为23 毫秒为433 星期为1 星期为18 历型为1 zone为28800000 修改后月份为3 Sat Jan 23 13:33:23 CST 1999Sat Feb 12 13:33:14 CST 2000Tue Mar 13 14:13:14 CST 2001 -----运算-----Wed Mar 13 14:13:14 CST 2013Wed Feb 13 14:13:14 CST 2013Thu Feb 14 14:13:14 CST 2013Fri Feb 15 14:13:14 CST 2013Tue Feb 29 14:13:14 CST 2000Tue Feb 01 14:13:14 CST 2000Wed Mar 01 14:13:14 CST 2000
对比上面最后的两行输出,可以看出add与roll的运算规则其实是不同的,roll的运算不会影响大规则(这里的大规则指的是月份的改变)的改变,而add会影响。
以上がカレンダーの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。