新しい日付と時刻のAPI:第12章「アクションでのJava 8」

  • Javaの1.0では、日付と時刻のサポートは唯一のjava.util.Dateクラスを頼ることができます。二つの大きな欠点がある一方で、このクラス:今年の最初の選択は、1900年に開始されたが、月は0から始まります。
  • Javaの1.1では、多くの方法のDateクラスは破棄され、java.util.Calendarのクラスを置き換えています。ただし、Calendarクラスは、同様の問題や設計上の欠陥を持って、これらの方法は、コード記述されたエラーが発生しやすいの使用につながりました。

DateFormatのアプローチは、独自の問題を抱えています。例えば、それはスレッドセーフではありません。2つのスレッドが同じ構文解析日付フォーマッタを使用しようとすると、予期しない結果を得ることがこれが意味。

1. LOCALDATEとにLocalTime

1.1 LOCALDATE

Javaの8新しい日付と時刻のAPIは、LOCALDATEクラスのインスタンスは、単に情報が含まれていない日付と時刻を提供し、不変オブジェクトです。また、タイムゾーンに関連した情報には含まれていません。

staticファクトリメソッドのインスタンスを作成しますLOCALDATE。以下に示すようにLOCALDATEの例は、年、月、曜日などの一般的に値を読み取るために使用されるいくつかの方法を提供します。

LocalDate localDate = LocalDate.of(2014, 3, 18);
int year = localDate.getYear();
Month month = localDate.getMonth();
int day = localDate.getDayOfMonth();
DayOfWeek dow = localDate.getDayOfWeek();
int len = localDate.lengthOfMonth();
boolean leap = localDate.isLeapYear();

// 使用工厂方法从系统时钟中获取当前的日期
LocalDate today = LocalDate.now();

System.out.println(String.format("year:%s\nmonth:%s\nday:%s\ndow:%s\nlen:%s\nleap:%s", year, month, day, dow, len, leap));
System.out.println(today);

结果:
year:2014
month:MARCH
day:18
dow:TUESDAY
len:31
leap:false
2019-03-27

Javaの8日付 - 時間のクラスは、同様のファクトリメソッドを提供します。メソッドを渡すパラメータTemporalFieldを得るために、同じ情報を取得します。フィールドの時間的な目標値にアクセスする方法をTemporalFieldインターフェース定義。ChronoField列挙TemporalFieldインタフェースはgetメソッドを使用して値の要素を列挙することができます実装します。

int year = localDate.get(ChronoField.YEAR);
int month = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.get(ChronoField.DAY_OF_MONTH);

1.2にLocalTime

使用にLocalTimeクラスにLocalTimeの使用2つのファクトリメソッドをオーバーロードされたのインスタンスを作成することができ、時間を表しています。

  • 受信リロード時間と分の第一の機能
  • 2番目のオーバーロード機能も秒を受け取ります。

LocalTimeクラスも、次のようにいくつかの方法は、これらの変数のアクセス値を取得しています。

LocalTime localTime = LocalTime.of(13, 45, 20);
int hour = localTime.getHour();
int minute = localTime.getMinute();
int second = localTime.getSecond();
System.out.println(String.format("hour:%s\nminute:%s\nsecond:%s", hour, minute, second));

打印结果:
hour:13
minute:45
second:20

LOCALDATEとにLocalTimeは、作成された文字列によって自分に代わって解決することができます。静的メソッドの解析を使用して達成することができます。

LocalDate date = LocalDate.parse("2019-03-27");
LocalTime time = LocalTime.parse("20:17:08");

これは、parseメソッドてDateTimeFormatterに渡すことができます。そのような定義の例は、どのように日付または時刻オブジェクトをフォーマットします。古いバージョンのjava.util.DateFormatを交換します。

パラメータとして渡された文字列は、正当なLOCALDATEとして解析やlocaltimeがオブジェクトをすることができない場合は、両方の解析方法はDateTimeParseException例外から継承されたのRuntimeExceptionをスローします。

2.合併の日付と時刻

複雑なクラスのLocalDateTime、とにLocalTime LOCALDATEフィットです。また、タイムゾーン情報と、日付と時刻を示しています。それは直接作成、またはオブジェクト構築の合併日時経由することができます。

LocalTime time = LocalTime.of(21, 31, 50);
LocalDate date = LocalDate.of(2019, 03, 27);

LocalDateTime dt1 = LocalDateTime.of(2017, Month.NOVEMBER, 07, 22, 31, 51);
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(22, 21, 14);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);

オブジェクトの作成のLocalDateTime

  • 直接作成
  • atTime方法LOCALDATEを通して物体を通過する時間
  • atDate方法にLocalTimeを通して物体を通過する時間

それとも、中LOCALDATEやlocaltimeのLocalDateTimeから成分を抽出するtoLocalDate toLocalTime方法を使用することができます。

LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();

3.コンピュータの日付と時刻の形式

コンピュータ、「2019年3月27日午前11時20分03秒」の観点から、このアプローチは、時間の持続期間の点は、簡単にコンピュータモデリング時間、最も自然な形を理解することは、容易に理解することはされません単一の大きな整数。新java.time.Instantの授業時間の道をモデル化し、それは基本的に(1970年1月真夜中の第一部門でUTC伝統的な地区に設定されている)、Unixの時間計算から経過した秒数の最初の年です。

インスタントの作成3.1

  • 静的ファクトリメソッドは、クラス代表のインスタンスを作成秒の値を渡すofEpochSecond。
  • 調整するためのパラメータとして渡された秒数の値のパラメータナノ秒で秒を受け、ヘビーデューティーバージョンを、強化ofEpochSecond staticファクトリメソッドもあります。オーバーロードされたバージョンは、999 999 0〜999ナノ秒のスライスの保存を確実にするために、ナノ秒のパラメータを調整します。
Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3, 0);
// 2 秒之后再加上100万纳秒(1秒)
Instant.ofEpochSecond(2, 1_000_000_000);
// 4秒之前的100万纳秒(1秒)
Instant.ofEpochSecond(4, -1_000_000_000);

今3.2ファクトリメソッド

インスタントクラスはまた、現在の時刻のタイムスタンプを取得することができる、今静的ファクトリメソッドをサポートしています。

Instant now = Instant.now();
System.out.println(now);

2019-03-27T03:26:39.451Z

インスタントは、秒数を含み、機械の使用を容易にするために設計されており、ナノ秒単位で構成されています。したがって、インスタントは、私たちが理解することは非常に簡単であるそれらの時間単位を扱うことができません。

int day = Instant.now().get(ChronoField.DAY_OF_MONTH);
它会抛出下面这样的异常:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfMonth
但是你可以通过Duration和Period类使用Instant,接下来我们会对这部分内容进行介绍。

4.期間和期間

4.1期間

時間は、すべてのクラスが読み込まれ、モデルオブジェクトの時間値を操作する方法を定義するインタフェースを実装します。あなたは2つのオブジェクト間の持続時間を作成する必要がある場合、我々は継続クラス間の静的なファクトリメソッドを必要とします。次の2つのLocalTimesオブジェクト、2つのオブジェクト間の期間LocalDateTimes、または2つのインスタントオブジェクトを作成することができます。

LocalTime time1 = LocalTime.of(21, 50, 10);
LocalTime time2 = LocalTime.of(22, 50, 10);
LocalDateTime dateTime1 = LocalDateTime.of(2019, 03, 27, 21, 20, 40);
LocalDateTime dateTime2 = LocalDateTime.of(2019, 03, 27, 21, 20, 40);
Instant instant1 = Instant.ofEpochSecond(1000 * 60 * 2);
Instant instant2 = Instant.ofEpochSecond(1000 * 60 * 3);

Duration d1 = Duration.between(time1, time2);
Duration d2 = Duration.between(dateTime1, dateTime2);
Duration d3 = Duration.between(instant1, instant2);
// PT1H 相差1小时
System.out.println("d1:" + d1);
// PT2H 相差2小时
System.out.println("d2:" + d2);
// PT16H40M 相差16小时40分钟
System.out.println("d3:" + d3);

2が混在することはできませんので、人々の利便性のためのLocalDateTimeは、インスタントの機械加工を容易にするために、読み取ります。あなたは2つのタイプのオブジェクト間の期間を作成する場合は、DateTimeException例外をトリガします。

期間クラスは、主秒とナノ秒単位で時間の長さを測定するために使用されているため、また、あなたはパラメータの間で行うための唯一の方法を対象とするLOCALDATEを渡すことはできません。

4.2期間

使用クラス期間の途中モデリング時間単位数の年、月または日。この方法は、間のクラスファクトリを使用する2つのLOCALDATE間の長さを得るために使用することができます。

Period period = Period.between(LocalDate.of(2019, 03, 7), LocalDate.of(2019, 03, 17));
// 相差10天
System.out.println("Period between:" + period);

期間と期間のクラスは、非常に便利なファクトリクラスの多くを提供し、対応する直接のインスタンスを作成します。

Duration threeMinutes = Duration.ofMinutes(3);
Duration fourMinutes = Duration.of(4, ChronoUnit.MINUTES);

Period tenDay = Period.ofDays(10);
Period threeWeeks = Period.ofWeeks(3);
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);
Duration类和Period类共享了很多相似的方法,有兴趣的可以参考官网的文档。

今まで、私たちはこれらの日付を紹介 - 時間オブジェクトは、より良いサポート関数型プログラミング、スレッドセーフにあるフィールドモードの一貫性を維持し、主要な設計上の意思決定を行うためにどの、変更不可です。

もちろん、新しい日付と時刻のAPIは、これらのオブジェクトの変数バージョンを作成するためにいくつかの便利な方法を提供します。たとえば、既存のLOCALDATE例3日間に追加したい場合があります。また、当社は、指定されたパターンに基づいて、どのように紹介します

時刻の形式、およびどのように解析し、出力日付にこの形式を使用する - たとえば、DD / MM / YYYY、作成日のために。

5.操作、日付の解析と書式設定

あなたはすでにあなたがそれの修正版を作成することをLOCALDATEオブジェクトを持っている場合は、最も直接的かつ最も簡単な方法は、withAttributeメソッドを使用することです。withAttributeメソッドは、オブジェクトのコピーを作成し、必要に応じてそのプロパティを変更します。

// 这段代码中所有的方法都返回一个修改了属性的对象。它们都不会修改原来的对象!
LocalDate date1 = LocalDate.of(2017, 12, 15);
LocalDate date2 = date1.withYear(2019);
LocalDate date3 = date2.withDayOfMonth(25);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9);

これらは、すべての日付と時刻のAPIクラスは、このようなLOCALDATE、にLocalTime、LocalDateTimeをやインスタントとして、単一の時点を定義し、これらの2つのメソッドを実装し、一時的なインタフェースで宣言されています。より正確には、およびgetメソッドを使用して、我々は、読み取りを分離し、ゾーン時間的オブジェクトの値を変更することができます。オブジェクトがアクセスを要求する時間的フィールドをサポートしていない場合は、そのようなアクセスインスタントしようとして、UnsupportedTemporalTypeException例外をスローChronoField.MONTHオブジェクトOF YEARフィールド、またはChronoField.NANO LOCALDATEオブジェクトOF SECONDフィールドは、この例外がスローされますときに。

// 以声明的方式操纵LocalDate对象,可以加上或者减去一段时间
LocalDate date1 = LocalDate.of(2014, 10, 19);
LocalDate date2 = date1.plusWeeks(1);
LocalDate date3 = date2.minusYears(3);
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);

プラスの方法は、我々が得る方法と同様のものであり、単に導入最後の行で使用される一般的な方法であり、マイナスその方法は、時間的なインタフェースで宣言されています。時間的には一定の期間に将来を見越してか、ロールバックオブジェクトこれらの方法を通じて、TemporalUnitプラスマイナス数の目的は、我々は非常に簡単に、我々は非常に簡単にTemporalUnitインターフェースChronoUnit列挙を実装することができます。

6. TemporalAdjuster

時には、より複雑な操作のいくつかの必要性は、例えば、次の日曜日、翌営業日、または月の最後の日に日付を調整します。それはTemporalAdjusterオブジェクトのよりカスタマイズされた選択、日付を扱うの柔軟性を提供して渡して、メソッドの大型バージョンで使用することができます。

// 对于最常见的用例,日期和时间API已经提供了大量预定义的TemporalAdjuster。可以通过TemporalAdjuster类的静态工厂方法访问。
LocalDate date1 = LocalDate.of(2013, 12, 11);
LocalDate date2 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
LocalDate date3 = date2.with(TemporalAdjusters.lastDayOfMonth());

TemporalAdjusterは、メソッドの名前は非常に直感的で、より複雑な操作の日付を使用することができます。TemporalAdjusterの期待にノー事前に定義された行場合は、カスタムTemporalAdjusterを作成することができます。TemporalAdjusterインタフェース宣言唯一の方法(すなわち、インターフェース機能)。時間的時間的オブジェクトさらにオブジェクトを変換する方法を定義するインターフェースの必要性を実現するために、それはUnaryOperatorとみなすことができます

@FunctionalInterface
public interface TemporalAdjuster {
    Temporal adjustInto(Temporal temporal);
}

7.印刷出力と解析日付 - 時刻オブジェクト

時刻オブジェクトのデザイン - 新しいjava.time.formatパッケージは、フォーマットした日付を解析するために、具体的です。最も重要なクラスの一つがてDateTimeFormatterです。フォーマットは、その静的ファクトリメソッドや定数を通じ作成する最も簡単な方法です。すべててDateTimeFormatterインスタンスは、特定の形式で特定の日付や時刻を表す文字列を作成するために使用することができます。

LocalDate date = LocalDate.of(2013, 10, 11);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);

20131011
2013-10-11

日付は、あなたがファクトリメソッド解析の再作成を使用することができることを再作成したオブジェクトに、日付や時刻を表す文字列を解析して。

LocalDate date2 = LocalDate.parse("20141007", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date3 = LocalDate.parse("2014-10-07", DateTimeFormatter.ISO_LOCAL_DATE);

DateTimeFormatterインスタンスは、古いjava.util.DateFormatのスレッドセーフスレッドセーフです。複数のスレッド間で共有シングルトンインスタンス作成されたフォーマットは、何の問題インスタンスではありません。また、ofPattern staticファクトリメソッドは、特定のパターンに従ってフォーマッタを作成することができます。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formattedDateStr = date.format(formatter);
LocalDate date1 = LocalDate.parse(formattedDateStr, formatter);

ofPattern方法はまた、ロケールがフォーマッタを作成合格することができるオーバーロードされたバージョンを提供します。

DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN);
LocalDate date = LocalDate.of(2015, 11, 14);
String formattedDate = date.format(italianFormatter);
LocalDate date1 = LocalDate.parse(formattedDate, italianFormatter);

DateTimeFormatterBuilderクラスは、より複雑な形状をより細かく制御を提供するために、ある提供します。また、そのような場合、感度分析、柔軟な解析、充填、などのセクションで指定したオプションのフォーマットとして非常に強力な分析機能を提供します。

DateTimeFormatterBuilderフォーマッタカスタムにより、

DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder()
                .appendText(ChronoField.DAY_OF_MONTH)
                .appendLiteral(". ")
                .appendText(ChronoField.MONTH_OF_YEAR)
                .appendLiteral(" ")
                .appendText(ChronoField.YEAR)
                .parseCaseInsensitive()
                .toFormatter(Locale.ITALIAN);
LocalDate now = LocalDate.now();
String s = now.format(italianFormatter);

8.プロセス異なるタイムゾーンやカレンダー

新しい日付と時刻のAPIの重要な機能は、新たに処理ゾーンに追加されます。新しいクラスは、古いバージョンのjava.util.TimeZoneを交換java.time.ZoneId。同じ日付と時刻を持つ他のカテゴリは、zoneidをクラスも変更することはできません。基準時間間隔に同じ面積が一定の規則に従って。このクラスのインスタンス40の時間帯に含まれるZoneRulesは、各オブジェクトを特定するzoneidエリアIDで表され、getRulesするzoneidの特定の領域を呼び出すことによって得られる()ルールであってもよいです。

ZoneId shanghaiZone = ZoneId.of("Asia/Shanghai");

新しいJavaメソッドtoZoneId 8はするzoneidに古いタイムゾーンオブジェクトになります。領域ID「が領域{} / {都市}」形式、タイムゾーンデータベースを提供するために、Internet Assigned Numbers Authority(IANA)によって設定された領域の集合です。

ZoneId zoneId = TimeZone.getDefault().toZoneId();

するzoneidオブジェクトはLOCALDATE、のLocalDateTimeまたはインスタントそれが指定されたタイムゾーンに対して点を表し、オブジェクトZonedDateTimeインスタンスを統合するように構成されてもよいです。

LocalDate date = LocalDate.of(2019, 03, 27);
ZonedDateTime zdt1 = date.atStartOfDay(shanghaiZone);

LocalDateTime dateTime = LocalDateTime.of(2015, 12, 21, 11, 11, 11);
ZonedDateTime zdt2 = dateTime.atZone(shanghaiZone);

Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(shanghaiZone);
通过ZoneId,你还可以将LocalDateTime转换为Instant:

LocalDateTime dateTime = LocalDateTime.of(2016, 10, 14, 15, 35);
Instant instantFromDateTime = dateTime.toInstant(shanghaiZone);
你也可以通过反向的方式得到LocalDateTime对象:

Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, shanghaiZone);

他の実施形態より一般的には、発現領域と固定バイアス電流の時間帯UTC /グリニッジの使用です。サブクラスZoneOffsetのzoneidを使用は、現在の時刻とグリニッジ標準時との差を表します。

ZoneOffset newYorkOffset = ZoneOffset.of("-05:00");

9.概要

  • Javaの8 java.util.Dateクラスの古いバージョンと日付と時刻をモデル化するための他のクラスの前に、あなたは、変動と貧困層のオフセット値、デフォルト値、および命名を含め、設計上の欠陥や矛盾がたくさんあります。
  • 新しい日付と時刻のAPI、日付 - 時間オブジェクトは不変です。
  • 新しいAPIは、二つの異なる時間表現を提供し、効果的に人と機械のさまざまなニーズを区別実行されています。
  • あなたは絶対的または相対的で日付と時刻を操作することができた結果が、操作は常に新しいインスタンスを返し、古い日付時刻オブジェクトは変更されません。
  • TemporalAdjusterは、もはや一度だけ、その値を変更し、あなたは需要に応じて、独自の日付コンバータを定義することができますに限定、あなたが日付を操作するために、より洗練された方法を使用することができません。
  • これで、特定の形式要件に従って、独自のフォーマッタを定義し、プリントアウトまたは日付時刻オブジェクトを解析することができます。これらの形式は、独自のプログラミングを作成することができ、テンプレートから作成することができ、そして、彼らは、スレッドセーフです。
  • あなたはそれらをローカライズ、地域/場所に関して方法を使用するか、または途中の時間帯のUTC / GMT絶対偏差であり、目標日時間にそれを適用することができます。

リソース

  • ノー公共の返信:Java8は英語版で、「アクションでJava 8」を得ることができます!

チップ

  • ご支援に感謝し、収集および転送へようこそ!(1•ㅂ•)و✧
  • バックエンドの弟は、バックエンドの開発に焦点を当て、あなたが一緒に進行したい:私は公共の数字の関心を歓迎します!

公開された31元の記事 ウォン称賛17 ビュー10000 +

おすすめ

転載: blog.csdn.net/xinruodingshui/article/details/104550611