SCW Icons
hero bg no divider
Blog

ジョダ・タイムからjava.timeへのマイグレーション

キャメロン・グレゴール
Published Nov 12, 2021
Last updated on Mar 10, 2026

コードの移行 (つまり、レガシーコード) は面白くありません。一線を越えるには、膨大な計画と努力が必要です。開発者にとって最も刺激的でやる気を起こさせる作業ではありませんが、レガシーコードを新しいライブラリバージョンに移行するには、決意と適切な経験が必要です。 ジョーダタイム java.timeへの移行は、綿密な計画と実行を必要とするそのような移行の1つです。

Java SE 8 より前にリリースされた Java プロジェクトで、日付/時刻処理を使用している場合は、おそらく Joda-Time を使用していたはずです。Joda-Time は SE 8 より前の日付と時刻の関数を処理するための優れたライブラリであり、事実上の標準でもありました。もしあなたのプロジェクトなら まだ Joda-Timeを使用していますが、java.timeに移行してから読み進めたいと考えています。

Java SE 8のリリースには、一般にjava.time (JSR-310) と呼ばれる、新しく改良された標準の日付と時刻のAPIが含まれていました。Joda-Time プロジェクトでは、java.time (JSR-310) への移行を推奨するようになりました。

java.time (JSR-310) は Joda-Time の影響を強く受けていますが、後方互換性がなく、概念や用語が変更されています。そのため、Joda-Time から java.time への移行には、変更するコードのすべての行に細心の注意が必要なのです。これには時間がかかり、より簡単で自動化された移行方法があったらいいのにと思うでしょう。

移行にはもっと良い方法があり、Senseiを使用して作成しました。Senseiは、ユーザーが定義したレシピ(ルール)に従ってコード変換を自動的に実行するIntelliJプラグインです。反復的な移行作業を行うよりも、再利用可能なレシピの定義に時間をかけてください。この自動化は、従来の Joda-Time コードを変換するだけでなく、チームが新しいコードを記述する際に IDE のガイドラインにすぐ従えるようにするのにも役立ちます。

皆様が有利なスタートを切れるように、Senseiの公開クックブックを作成しました ジャワタイムでの標準化 (JSR-310) これには、Joda-Timeからjava.timeへの移行をより簡単な方法で行うためのレシピが含まれています。このレシピは増え続けており、今後もさらに多くのレシピで対象範囲を拡大していく予定です。

これは、Senseiがどのようにレガシーコードの移行を簡単にするのかを理解するのに役立つかもしれないサンプル移行の例です。

Video of how to set java.time zoned date time

反復的な手動移行から自動コード変換まで

では、新しい DateTime を作成する例を見てみましょう。1 行のコードを Joda-Time から java.time に移行する際に隠れた落とし穴がいくつか見えてきます。次に、「java.time の標準化 (JSR-310)」クックブックにある Sensei レシピの 1 つを見て、すべての開発者が同じ移行を何度も再利用できるように、この情報がどのように取り込まれているかを示します。

この例では、日付時刻フィールドの値を表す 7 つの int 引数から Joda-Time 日時を構築しています。

これをjava.timeの同等のものに移行するにはどうすればいいですか?

ザの このコンストラクターの Joda-Time での Javadoc 言う:

デフォルトタイムゾーンのIsoChronologyを使用して日時フィールド値からインスタンスを構築します。

最初は、あると思うかもしれません 日付/時刻 java.time のクラスですが、クラスはありません。「joda time から java タイムへの移行」をグーグルで検索すると、おそらく Stephen Colebourne のブログ投稿が見つかるでしょう。 Joda-Time から java.time への変換

これにより、良いスタートを切ることができ、java.time.ZonedDateTime または java.time.OffsetDateTime を使用する方向性がわかります。最初の質問ですが、どれを使えばいいでしょうか?スティーブンのコメントに基づくと、おそらくZonedDateTimeでしょう。

調べてみると ゾーン日付/時刻 javadoc、コンストラクターがまったく表示されません。Stephen のブログ記事に戻ると、さらに読み進めます。

建設。Joda-Time には Object を受け取って型変換を行うコンストラクターがあります。java.time にはファクトリメソッドしかないため、文字列には parse () メソッドが提供されていますが、変換はユーザーの問題です。

そのため、静的ファクトリメソッドが必要です。静的メソッドを検索すると、かなり近いものが見つかりますが、まったく同じではありません。

オリジナルのJoda-Time DateTimeコンストラクターと同様に7つのintパラメーターがありますが、注意を払わないと重要な詳細を見逃してしまいます。7 番目のパラメーターはもはやミリ秒ではなく、代わりにナノ秒を想定しています。これは、java.time が Joda-Time よりも精度が高く、瞬時をナノ秒単位で測定するためです。これは見逃しがちな、重要な詳細事項です。さらに、このメソッドは ZoneID を想定しているので、以前はなぜ必要なかったのか、なぜ今必要なのか不思議に思うでしょう。

デフォルトのタイムゾーンを使用すると説明していた元のコンストラクタのjavadocを思い出してください。デフォルトのZoneIDを取得する方法があるのではないでしょうか。

ザの ゾーン ID 用ジャバドック リストされているコンストラクターについては説明していませんが、使用できる静的メソッドを見るとわかります システムデフォルト ()

ZoneIDを整理したので、ミリ秒からナノ秒への変換について何をすべきでしょうか?java.util.Concurrent.TimeUnit を使用して変換を実行できるかもしれません。

このメソッドは long を返し、このメソッドは int を想定しているので、今度は変換の問題も解決する必要があります。簡単なことをやってみるといいかもしれません。掛け算?

これは動作しますが、少し場違いに見えます。まだお気づきでない方もいらっしゃると思いますが、私たちは 1 行のコードを移行するためにかなりの時間と労力を費やしてきました。しかし、ご想像のとおり、このような編集は手作業で行う必要があり、改善されることはありません。

しかし、java.time APIをもう少し詳しく見てみると、もう少し流暢に見えるソリューションを見つけることができます。

ZonedDateTimeにはミリ秒を設定する明確な方法はありませんが、次の方法で設定できます。 (テンポラル・フィールド・フィールド、長い newValue) メソッド付き、を使用して クロノフィールド. ミリオブセカンド テンポラル・フィールドのように。

そして、Javaのドキュメントには、ナノ秒への変換が自動的に実行されると記載されています。

このフィールドを使用して値を設定する場合、値に1,000,000を掛けた値でNANO_OF_SECONDを設定する場合と同じように動作するはずです。

したがって、ファクトリメソッドでナノ秒に0を指定するだけで、次のようになります。 メソッドを使用して、元の値とミリ秒をすべて含む ZonedDateTime を作成します。

最終結果を見ると、たった1行のコードしか変更していないようで、たった1つの移行の研究に費やした労力が伝わりません。

より迅速かつ簡単に移行するためのレシピを作成

Senseiは、この苦労して得た情報を他の開発者と共有する方法を提供しています。これらすべての要件を網羅したレシピを作成することで、Senseiユーザーはマウスをクリックするだけで移行を実行できるようになります。

Senseiのレシピは、主に3つのセクションで構成されています。

  • メタデータ
  • 検索
  • 適用可能な修正

この呼び出しを同等の java.time に移行するのに役立つ Sensei レシピ (YAML レシピと見なすこともできます) を見てみましょう。

DateTime foo = 新しい日付時刻 (年、月、日、時間、分、秒、ミリ秒)

メタデータセクション

メタデータセクションには、レシピとその使用方法に関する情報が含まれています。

検索セクション

Senseiレシピの検索セクションでは、このレシピを適用するコード要素を指定します。

検索:
インスタンス作成:
引数:
1:
タイプ:整数
2:
タイプ:整数
3:
タイプ:整数
4:
タイプ:整数
5:
タイプ:整数
6:
タイプ:整数
7:
タイプ:整数
引数の数:7
タイプ:org.joda.time.DateTime

この検索セクションでは、次のことがわかります。

  • を検索中 インスタンス作成、 つまり、コンストラクターの使用法です。注:あります 他にも多くの検索ターゲットが利用可能
  • コンストラクターには 7 つの引数が必要です。引数は以下で指定されます。 引数のカウント 財産
  • 引数 1-7 は int 型でなければなりません
  • のコンストラクターを探しています タイプ org.joda.time.DateTime

「利用可能な修正」セクション

AvailableFixes セクションでは、一致するコード要素に適用できる修正を 1 つ以上指定できます。各修正には複数のアクションを設定できますが、今回の場合は 1 つの修正で 2 つのアクションを実行します。

  • ザの 名前 修正のどれかがユーザーに「クイックフィックス」メニューに表示され、ユーザーがこのクイックフィックスを適用した場合に何が起こるかを説明します。
  • アクションリストには、このクイックフィックスによって実行されるアクションが表示されます。
  • ザの 書き換え action は、mustache テンプレートを使用してコード要素を書き換えます。変数と文字列置換関数を使用できます。
  • ザの 割り当てられた変数を変更 action は、このコンストラクターが変数への値の割り当てに使用されているかどうかを確認します。その場合、このアクションは変数を、で指定された型として宣言するように変更します。 タイプ

レシピを使用してコード変換を行う

レシピを記述して有効にすると、コードをスキャンして、適用できるセグメントが強調表示されます。

下のスクリーンショットでは、ターゲットコンストラクターがSenseiによってマークされていることがわかります。マークされたコンストラクターにカーソルを合わせると、レシピの簡単な説明とクイックフィックスオプションが表示されます。 java.time.ZonedDateTime への移行

Migrate New Date Time

を選択した後 java.time.ZonedDateTime への移行 クイックフィックス、コードはレシピで指定したアクションに従って変換されます。

Zoned Date Time With Year Month Day Hour

一回限りの移行とチーム間での統一されたコーディングプラクティス-Senseiで

上記の例からわかるように、1 行のコードを移行するには、苦労して得た知識が必要です。Senseiは、その知識を実用的なレシピや料理本に変えて、チーム内で共有することができます。1 回限りの移行スプリントを計画することも、Joda-Time コードに出くわしたときに java.time を段階的に瞬時に変換するというアプローチをとることもできます。レシピを有効化/無効化することで、論理的な段階または段階的に移行を行うことができ、Sensei がスキャンするファイルの範囲を拡大または縮小することもできます。この柔軟性により、コード移行の負担が軽減されます。

ライブラリの移行は、Senseiを使用してプロジェクトを標準化するさまざまな方法の一例にすぎません。プルリクエストや自分でコーディングしているときに頻繁に遭遇する、アンチパターンや特定の手動コード変換に常に目を光らせておくことができます。次のようなものがある場合 コーディングガイドライン 開発者が見逃しがちですが、ガイドラインをレシピに変換すれば、開発者は承認されたコード変換を自信を持って適用できます。

ご不明な点がございましたら、ぜひお聞かせください。以下のサイトから Slack にご参加ください。 sensei-scw.slack.com

リソースを表示
リソースを表示

Joda-Time を便利な方法で java.time に移行する方法

もっと興味がありますか?

キャメロンはセキュア・コード・ウォリアーのシニア・ソフトウェア開発者です。15 年以上のソフトウェア提供経験があり、開発者の生産性に情熱を傾け、オープンソースソフトウェアに積極的に貢献しています。

learn more

Secure Code Warriorは、ソフトウェア開発ライフサイクル全体にわたってコードを保護し、サイバーセキュリティを最優先とする文化を築くお手伝いをします。アプリケーションセキュリティマネージャ、開発者、CISO、またはセキュリティ関係者のいずれであっても、安全でないコードに関連するリスクを軽減するお手伝いをします。

デモを予約
シェア:
linkedin brandsSocialx logo
著者
キャメロン・グレゴール
Published Nov 12, 2021

キャメロンはセキュア・コード・ウォリアーのシニア・ソフトウェア開発者です。15 年以上のソフトウェア提供経験があり、開発者の生産性に情熱を傾け、オープンソースソフトウェアに積極的に貢献しています。

シェア:
linkedin brandsSocialx logo

コードの移行 (つまり、レガシーコード) は面白くありません。一線を越えるには、膨大な計画と努力が必要です。開発者にとって最も刺激的でやる気を起こさせる作業ではありませんが、レガシーコードを新しいライブラリバージョンに移行するには、決意と適切な経験が必要です。 ジョーダタイム java.timeへの移行は、綿密な計画と実行を必要とするそのような移行の1つです。

Java SE 8 より前にリリースされた Java プロジェクトで、日付/時刻処理を使用している場合は、おそらく Joda-Time を使用していたはずです。Joda-Time は SE 8 より前の日付と時刻の関数を処理するための優れたライブラリであり、事実上の標準でもありました。もしあなたのプロジェクトなら まだ Joda-Timeを使用していますが、java.timeに移行してから読み進めたいと考えています。

Java SE 8のリリースには、一般にjava.time (JSR-310) と呼ばれる、新しく改良された標準の日付と時刻のAPIが含まれていました。Joda-Time プロジェクトでは、java.time (JSR-310) への移行を推奨するようになりました。

java.time (JSR-310) は Joda-Time の影響を強く受けていますが、後方互換性がなく、概念や用語が変更されています。そのため、Joda-Time から java.time への移行には、変更するコードのすべての行に細心の注意が必要なのです。これには時間がかかり、より簡単で自動化された移行方法があったらいいのにと思うでしょう。

移行にはもっと良い方法があり、Senseiを使用して作成しました。Senseiは、ユーザーが定義したレシピ(ルール)に従ってコード変換を自動的に実行するIntelliJプラグインです。反復的な移行作業を行うよりも、再利用可能なレシピの定義に時間をかけてください。この自動化は、従来の Joda-Time コードを変換するだけでなく、チームが新しいコードを記述する際に IDE のガイドラインにすぐ従えるようにするのにも役立ちます。

皆様が有利なスタートを切れるように、Senseiの公開クックブックを作成しました ジャワタイムでの標準化 (JSR-310) これには、Joda-Timeからjava.timeへの移行をより簡単な方法で行うためのレシピが含まれています。このレシピは増え続けており、今後もさらに多くのレシピで対象範囲を拡大していく予定です。

これは、Senseiがどのようにレガシーコードの移行を簡単にするのかを理解するのに役立つかもしれないサンプル移行の例です。

Video of how to set java.time zoned date time

反復的な手動移行から自動コード変換まで

では、新しい DateTime を作成する例を見てみましょう。1 行のコードを Joda-Time から java.time に移行する際に隠れた落とし穴がいくつか見えてきます。次に、「java.time の標準化 (JSR-310)」クックブックにある Sensei レシピの 1 つを見て、すべての開発者が同じ移行を何度も再利用できるように、この情報がどのように取り込まれているかを示します。

この例では、日付時刻フィールドの値を表す 7 つの int 引数から Joda-Time 日時を構築しています。

これをjava.timeの同等のものに移行するにはどうすればいいですか?

ザの このコンストラクターの Joda-Time での Javadoc 言う:

デフォルトタイムゾーンのIsoChronologyを使用して日時フィールド値からインスタンスを構築します。

最初は、あると思うかもしれません 日付/時刻 java.time のクラスですが、クラスはありません。「joda time から java タイムへの移行」をグーグルで検索すると、おそらく Stephen Colebourne のブログ投稿が見つかるでしょう。 Joda-Time から java.time への変換

これにより、良いスタートを切ることができ、java.time.ZonedDateTime または java.time.OffsetDateTime を使用する方向性がわかります。最初の質問ですが、どれを使えばいいでしょうか?スティーブンのコメントに基づくと、おそらくZonedDateTimeでしょう。

調べてみると ゾーン日付/時刻 javadoc、コンストラクターがまったく表示されません。Stephen のブログ記事に戻ると、さらに読み進めます。

建設。Joda-Time には Object を受け取って型変換を行うコンストラクターがあります。java.time にはファクトリメソッドしかないため、文字列には parse () メソッドが提供されていますが、変換はユーザーの問題です。

そのため、静的ファクトリメソッドが必要です。静的メソッドを検索すると、かなり近いものが見つかりますが、まったく同じではありません。

オリジナルのJoda-Time DateTimeコンストラクターと同様に7つのintパラメーターがありますが、注意を払わないと重要な詳細を見逃してしまいます。7 番目のパラメーターはもはやミリ秒ではなく、代わりにナノ秒を想定しています。これは、java.time が Joda-Time よりも精度が高く、瞬時をナノ秒単位で測定するためです。これは見逃しがちな、重要な詳細事項です。さらに、このメソッドは ZoneID を想定しているので、以前はなぜ必要なかったのか、なぜ今必要なのか不思議に思うでしょう。

デフォルトのタイムゾーンを使用すると説明していた元のコンストラクタのjavadocを思い出してください。デフォルトのZoneIDを取得する方法があるのではないでしょうか。

ザの ゾーン ID 用ジャバドック リストされているコンストラクターについては説明していませんが、使用できる静的メソッドを見るとわかります システムデフォルト ()

ZoneIDを整理したので、ミリ秒からナノ秒への変換について何をすべきでしょうか?java.util.Concurrent.TimeUnit を使用して変換を実行できるかもしれません。

このメソッドは long を返し、このメソッドは int を想定しているので、今度は変換の問題も解決する必要があります。簡単なことをやってみるといいかもしれません。掛け算?

これは動作しますが、少し場違いに見えます。まだお気づきでない方もいらっしゃると思いますが、私たちは 1 行のコードを移行するためにかなりの時間と労力を費やしてきました。しかし、ご想像のとおり、このような編集は手作業で行う必要があり、改善されることはありません。

しかし、java.time APIをもう少し詳しく見てみると、もう少し流暢に見えるソリューションを見つけることができます。

ZonedDateTimeにはミリ秒を設定する明確な方法はありませんが、次の方法で設定できます。 (テンポラル・フィールド・フィールド、長い newValue) メソッド付き、を使用して クロノフィールド. ミリオブセカンド テンポラル・フィールドのように。

そして、Javaのドキュメントには、ナノ秒への変換が自動的に実行されると記載されています。

このフィールドを使用して値を設定する場合、値に1,000,000を掛けた値でNANO_OF_SECONDを設定する場合と同じように動作するはずです。

したがって、ファクトリメソッドでナノ秒に0を指定するだけで、次のようになります。 メソッドを使用して、元の値とミリ秒をすべて含む ZonedDateTime を作成します。

最終結果を見ると、たった1行のコードしか変更していないようで、たった1つの移行の研究に費やした労力が伝わりません。

より迅速かつ簡単に移行するためのレシピを作成

Senseiは、この苦労して得た情報を他の開発者と共有する方法を提供しています。これらすべての要件を網羅したレシピを作成することで、Senseiユーザーはマウスをクリックするだけで移行を実行できるようになります。

Senseiのレシピは、主に3つのセクションで構成されています。

  • メタデータ
  • 検索
  • 適用可能な修正

この呼び出しを同等の java.time に移行するのに役立つ Sensei レシピ (YAML レシピと見なすこともできます) を見てみましょう。

DateTime foo = 新しい日付時刻 (年、月、日、時間、分、秒、ミリ秒)

メタデータセクション

メタデータセクションには、レシピとその使用方法に関する情報が含まれています。

検索セクション

Senseiレシピの検索セクションでは、このレシピを適用するコード要素を指定します。

検索:
インスタンス作成:
引数:
1:
タイプ:整数
2:
タイプ:整数
3:
タイプ:整数
4:
タイプ:整数
5:
タイプ:整数
6:
タイプ:整数
7:
タイプ:整数
引数の数:7
タイプ:org.joda.time.DateTime

この検索セクションでは、次のことがわかります。

  • を検索中 インスタンス作成、 つまり、コンストラクターの使用法です。注:あります 他にも多くの検索ターゲットが利用可能
  • コンストラクターには 7 つの引数が必要です。引数は以下で指定されます。 引数のカウント 財産
  • 引数 1-7 は int 型でなければなりません
  • のコンストラクターを探しています タイプ org.joda.time.DateTime

「利用可能な修正」セクション

AvailableFixes セクションでは、一致するコード要素に適用できる修正を 1 つ以上指定できます。各修正には複数のアクションを設定できますが、今回の場合は 1 つの修正で 2 つのアクションを実行します。

  • ザの 名前 修正のどれかがユーザーに「クイックフィックス」メニューに表示され、ユーザーがこのクイックフィックスを適用した場合に何が起こるかを説明します。
  • アクションリストには、このクイックフィックスによって実行されるアクションが表示されます。
  • ザの 書き換え action は、mustache テンプレートを使用してコード要素を書き換えます。変数と文字列置換関数を使用できます。
  • ザの 割り当てられた変数を変更 action は、このコンストラクターが変数への値の割り当てに使用されているかどうかを確認します。その場合、このアクションは変数を、で指定された型として宣言するように変更します。 タイプ

レシピを使用してコード変換を行う

レシピを記述して有効にすると、コードをスキャンして、適用できるセグメントが強調表示されます。

下のスクリーンショットでは、ターゲットコンストラクターがSenseiによってマークされていることがわかります。マークされたコンストラクターにカーソルを合わせると、レシピの簡単な説明とクイックフィックスオプションが表示されます。 java.time.ZonedDateTime への移行

Migrate New Date Time

を選択した後 java.time.ZonedDateTime への移行 クイックフィックス、コードはレシピで指定したアクションに従って変換されます。

Zoned Date Time With Year Month Day Hour

一回限りの移行とチーム間での統一されたコーディングプラクティス-Senseiで

上記の例からわかるように、1 行のコードを移行するには、苦労して得た知識が必要です。Senseiは、その知識を実用的なレシピや料理本に変えて、チーム内で共有することができます。1 回限りの移行スプリントを計画することも、Joda-Time コードに出くわしたときに java.time を段階的に瞬時に変換するというアプローチをとることもできます。レシピを有効化/無効化することで、論理的な段階または段階的に移行を行うことができ、Sensei がスキャンするファイルの範囲を拡大または縮小することもできます。この柔軟性により、コード移行の負担が軽減されます。

ライブラリの移行は、Senseiを使用してプロジェクトを標準化するさまざまな方法の一例にすぎません。プルリクエストや自分でコーディングしているときに頻繁に遭遇する、アンチパターンや特定の手動コード変換に常に目を光らせておくことができます。次のようなものがある場合 コーディングガイドライン 開発者が見逃しがちですが、ガイドラインをレシピに変換すれば、開発者は承認されたコード変換を自信を持って適用できます。

ご不明な点がございましたら、ぜひお聞かせください。以下のサイトから Slack にご参加ください。 sensei-scw.slack.com

リソースを表示
リソースを表示

レポートをダウンロードするには、以下のフォームに記入してください

当社の製品および/または関連するセキュアコーディングのトピックに関する情報を送信する許可をお願いします。当社は、お客様の個人情報を常に細心の注意を払って取り扱い、マーケティング目的で他社に販売することは決してありません。

送信
scw success icon
scw error icon
フォームを送信するには、「アナリティクス」クッキーを有効にしてください。設定が完了したら、再度無効にしても構いません。

コードの移行 (つまり、レガシーコード) は面白くありません。一線を越えるには、膨大な計画と努力が必要です。開発者にとって最も刺激的でやる気を起こさせる作業ではありませんが、レガシーコードを新しいライブラリバージョンに移行するには、決意と適切な経験が必要です。 ジョーダタイム java.timeへの移行は、綿密な計画と実行を必要とするそのような移行の1つです。

Java SE 8 より前にリリースされた Java プロジェクトで、日付/時刻処理を使用している場合は、おそらく Joda-Time を使用していたはずです。Joda-Time は SE 8 より前の日付と時刻の関数を処理するための優れたライブラリであり、事実上の標準でもありました。もしあなたのプロジェクトなら まだ Joda-Timeを使用していますが、java.timeに移行してから読み進めたいと考えています。

Java SE 8のリリースには、一般にjava.time (JSR-310) と呼ばれる、新しく改良された標準の日付と時刻のAPIが含まれていました。Joda-Time プロジェクトでは、java.time (JSR-310) への移行を推奨するようになりました。

java.time (JSR-310) は Joda-Time の影響を強く受けていますが、後方互換性がなく、概念や用語が変更されています。そのため、Joda-Time から java.time への移行には、変更するコードのすべての行に細心の注意が必要なのです。これには時間がかかり、より簡単で自動化された移行方法があったらいいのにと思うでしょう。

移行にはもっと良い方法があり、Senseiを使用して作成しました。Senseiは、ユーザーが定義したレシピ(ルール)に従ってコード変換を自動的に実行するIntelliJプラグインです。反復的な移行作業を行うよりも、再利用可能なレシピの定義に時間をかけてください。この自動化は、従来の Joda-Time コードを変換するだけでなく、チームが新しいコードを記述する際に IDE のガイドラインにすぐ従えるようにするのにも役立ちます。

皆様が有利なスタートを切れるように、Senseiの公開クックブックを作成しました ジャワタイムでの標準化 (JSR-310) これには、Joda-Timeからjava.timeへの移行をより簡単な方法で行うためのレシピが含まれています。このレシピは増え続けており、今後もさらに多くのレシピで対象範囲を拡大していく予定です。

これは、Senseiがどのようにレガシーコードの移行を簡単にするのかを理解するのに役立つかもしれないサンプル移行の例です。

Video of how to set java.time zoned date time

反復的な手動移行から自動コード変換まで

では、新しい DateTime を作成する例を見てみましょう。1 行のコードを Joda-Time から java.time に移行する際に隠れた落とし穴がいくつか見えてきます。次に、「java.time の標準化 (JSR-310)」クックブックにある Sensei レシピの 1 つを見て、すべての開発者が同じ移行を何度も再利用できるように、この情報がどのように取り込まれているかを示します。

この例では、日付時刻フィールドの値を表す 7 つの int 引数から Joda-Time 日時を構築しています。

これをjava.timeの同等のものに移行するにはどうすればいいですか?

ザの このコンストラクターの Joda-Time での Javadoc 言う:

デフォルトタイムゾーンのIsoChronologyを使用して日時フィールド値からインスタンスを構築します。

最初は、あると思うかもしれません 日付/時刻 java.time のクラスですが、クラスはありません。「joda time から java タイムへの移行」をグーグルで検索すると、おそらく Stephen Colebourne のブログ投稿が見つかるでしょう。 Joda-Time から java.time への変換

これにより、良いスタートを切ることができ、java.time.ZonedDateTime または java.time.OffsetDateTime を使用する方向性がわかります。最初の質問ですが、どれを使えばいいでしょうか?スティーブンのコメントに基づくと、おそらくZonedDateTimeでしょう。

調べてみると ゾーン日付/時刻 javadoc、コンストラクターがまったく表示されません。Stephen のブログ記事に戻ると、さらに読み進めます。

建設。Joda-Time には Object を受け取って型変換を行うコンストラクターがあります。java.time にはファクトリメソッドしかないため、文字列には parse () メソッドが提供されていますが、変換はユーザーの問題です。

そのため、静的ファクトリメソッドが必要です。静的メソッドを検索すると、かなり近いものが見つかりますが、まったく同じではありません。

オリジナルのJoda-Time DateTimeコンストラクターと同様に7つのintパラメーターがありますが、注意を払わないと重要な詳細を見逃してしまいます。7 番目のパラメーターはもはやミリ秒ではなく、代わりにナノ秒を想定しています。これは、java.time が Joda-Time よりも精度が高く、瞬時をナノ秒単位で測定するためです。これは見逃しがちな、重要な詳細事項です。さらに、このメソッドは ZoneID を想定しているので、以前はなぜ必要なかったのか、なぜ今必要なのか不思議に思うでしょう。

デフォルトのタイムゾーンを使用すると説明していた元のコンストラクタのjavadocを思い出してください。デフォルトのZoneIDを取得する方法があるのではないでしょうか。

ザの ゾーン ID 用ジャバドック リストされているコンストラクターについては説明していませんが、使用できる静的メソッドを見るとわかります システムデフォルト ()

ZoneIDを整理したので、ミリ秒からナノ秒への変換について何をすべきでしょうか?java.util.Concurrent.TimeUnit を使用して変換を実行できるかもしれません。

このメソッドは long を返し、このメソッドは int を想定しているので、今度は変換の問題も解決する必要があります。簡単なことをやってみるといいかもしれません。掛け算?

これは動作しますが、少し場違いに見えます。まだお気づきでない方もいらっしゃると思いますが、私たちは 1 行のコードを移行するためにかなりの時間と労力を費やしてきました。しかし、ご想像のとおり、このような編集は手作業で行う必要があり、改善されることはありません。

しかし、java.time APIをもう少し詳しく見てみると、もう少し流暢に見えるソリューションを見つけることができます。

ZonedDateTimeにはミリ秒を設定する明確な方法はありませんが、次の方法で設定できます。 (テンポラル・フィールド・フィールド、長い newValue) メソッド付き、を使用して クロノフィールド. ミリオブセカンド テンポラル・フィールドのように。

そして、Javaのドキュメントには、ナノ秒への変換が自動的に実行されると記載されています。

このフィールドを使用して値を設定する場合、値に1,000,000を掛けた値でNANO_OF_SECONDを設定する場合と同じように動作するはずです。

したがって、ファクトリメソッドでナノ秒に0を指定するだけで、次のようになります。 メソッドを使用して、元の値とミリ秒をすべて含む ZonedDateTime を作成します。

最終結果を見ると、たった1行のコードしか変更していないようで、たった1つの移行の研究に費やした労力が伝わりません。

より迅速かつ簡単に移行するためのレシピを作成

Senseiは、この苦労して得た情報を他の開発者と共有する方法を提供しています。これらすべての要件を網羅したレシピを作成することで、Senseiユーザーはマウスをクリックするだけで移行を実行できるようになります。

Senseiのレシピは、主に3つのセクションで構成されています。

  • メタデータ
  • 検索
  • 適用可能な修正

この呼び出しを同等の java.time に移行するのに役立つ Sensei レシピ (YAML レシピと見なすこともできます) を見てみましょう。

DateTime foo = 新しい日付時刻 (年、月、日、時間、分、秒、ミリ秒)

メタデータセクション

メタデータセクションには、レシピとその使用方法に関する情報が含まれています。

検索セクション

Senseiレシピの検索セクションでは、このレシピを適用するコード要素を指定します。

検索:
インスタンス作成:
引数:
1:
タイプ:整数
2:
タイプ:整数
3:
タイプ:整数
4:
タイプ:整数
5:
タイプ:整数
6:
タイプ:整数
7:
タイプ:整数
引数の数:7
タイプ:org.joda.time.DateTime

この検索セクションでは、次のことがわかります。

  • を検索中 インスタンス作成、 つまり、コンストラクターの使用法です。注:あります 他にも多くの検索ターゲットが利用可能
  • コンストラクターには 7 つの引数が必要です。引数は以下で指定されます。 引数のカウント 財産
  • 引数 1-7 は int 型でなければなりません
  • のコンストラクターを探しています タイプ org.joda.time.DateTime

「利用可能な修正」セクション

AvailableFixes セクションでは、一致するコード要素に適用できる修正を 1 つ以上指定できます。各修正には複数のアクションを設定できますが、今回の場合は 1 つの修正で 2 つのアクションを実行します。

  • ザの 名前 修正のどれかがユーザーに「クイックフィックス」メニューに表示され、ユーザーがこのクイックフィックスを適用した場合に何が起こるかを説明します。
  • アクションリストには、このクイックフィックスによって実行されるアクションが表示されます。
  • ザの 書き換え action は、mustache テンプレートを使用してコード要素を書き換えます。変数と文字列置換関数を使用できます。
  • ザの 割り当てられた変数を変更 action は、このコンストラクターが変数への値の割り当てに使用されているかどうかを確認します。その場合、このアクションは変数を、で指定された型として宣言するように変更します。 タイプ

レシピを使用してコード変換を行う

レシピを記述して有効にすると、コードをスキャンして、適用できるセグメントが強調表示されます。

下のスクリーンショットでは、ターゲットコンストラクターがSenseiによってマークされていることがわかります。マークされたコンストラクターにカーソルを合わせると、レシピの簡単な説明とクイックフィックスオプションが表示されます。 java.time.ZonedDateTime への移行

Migrate New Date Time

を選択した後 java.time.ZonedDateTime への移行 クイックフィックス、コードはレシピで指定したアクションに従って変換されます。

Zoned Date Time With Year Month Day Hour

一回限りの移行とチーム間での統一されたコーディングプラクティス-Senseiで

上記の例からわかるように、1 行のコードを移行するには、苦労して得た知識が必要です。Senseiは、その知識を実用的なレシピや料理本に変えて、チーム内で共有することができます。1 回限りの移行スプリントを計画することも、Joda-Time コードに出くわしたときに java.time を段階的に瞬時に変換するというアプローチをとることもできます。レシピを有効化/無効化することで、論理的な段階または段階的に移行を行うことができ、Sensei がスキャンするファイルの範囲を拡大または縮小することもできます。この柔軟性により、コード移行の負担が軽減されます。

ライブラリの移行は、Senseiを使用してプロジェクトを標準化するさまざまな方法の一例にすぎません。プルリクエストや自分でコーディングしているときに頻繁に遭遇する、アンチパターンや特定の手動コード変換に常に目を光らせておくことができます。次のようなものがある場合 コーディングガイドライン 開発者が見逃しがちですが、ガイドラインをレシピに変換すれば、開発者は承認されたコード変換を自信を持って適用できます。

ご不明な点がございましたら、ぜひお聞かせください。以下のサイトから Slack にご参加ください。 sensei-scw.slack.com

オンラインセミナーを見る
始めよう
learn more

以下のリンクをクリックして、このリソースのPDFをダウンロードしてください。

Secure Code Warriorは、ソフトウェア開発ライフサイクル全体にわたってコードを保護し、サイバーセキュリティを最優先とする文化を築くお手伝いをします。アプリケーションセキュリティマネージャ、開発者、CISO、またはセキュリティ関係者のいずれであっても、安全でないコードに関連するリスクを軽減するお手伝いをします。

レポートを表示デモを予約
PDF をダウンロード
リソースを表示
シェア:
linkedin brandsSocialx logo
もっと興味がありますか?

シェア:
linkedin brandsSocialx logo
著者
キャメロン・グレゴール
Published Nov 12, 2021

キャメロンはセキュア・コード・ウォリアーのシニア・ソフトウェア開発者です。15 年以上のソフトウェア提供経験があり、開発者の生産性に情熱を傾け、オープンソースソフトウェアに積極的に貢献しています。

シェア:
linkedin brandsSocialx logo

コードの移行 (つまり、レガシーコード) は面白くありません。一線を越えるには、膨大な計画と努力が必要です。開発者にとって最も刺激的でやる気を起こさせる作業ではありませんが、レガシーコードを新しいライブラリバージョンに移行するには、決意と適切な経験が必要です。 ジョーダタイム java.timeへの移行は、綿密な計画と実行を必要とするそのような移行の1つです。

Java SE 8 より前にリリースされた Java プロジェクトで、日付/時刻処理を使用している場合は、おそらく Joda-Time を使用していたはずです。Joda-Time は SE 8 より前の日付と時刻の関数を処理するための優れたライブラリであり、事実上の標準でもありました。もしあなたのプロジェクトなら まだ Joda-Timeを使用していますが、java.timeに移行してから読み進めたいと考えています。

Java SE 8のリリースには、一般にjava.time (JSR-310) と呼ばれる、新しく改良された標準の日付と時刻のAPIが含まれていました。Joda-Time プロジェクトでは、java.time (JSR-310) への移行を推奨するようになりました。

java.time (JSR-310) は Joda-Time の影響を強く受けていますが、後方互換性がなく、概念や用語が変更されています。そのため、Joda-Time から java.time への移行には、変更するコードのすべての行に細心の注意が必要なのです。これには時間がかかり、より簡単で自動化された移行方法があったらいいのにと思うでしょう。

移行にはもっと良い方法があり、Senseiを使用して作成しました。Senseiは、ユーザーが定義したレシピ(ルール)に従ってコード変換を自動的に実行するIntelliJプラグインです。反復的な移行作業を行うよりも、再利用可能なレシピの定義に時間をかけてください。この自動化は、従来の Joda-Time コードを変換するだけでなく、チームが新しいコードを記述する際に IDE のガイドラインにすぐ従えるようにするのにも役立ちます。

皆様が有利なスタートを切れるように、Senseiの公開クックブックを作成しました ジャワタイムでの標準化 (JSR-310) これには、Joda-Timeからjava.timeへの移行をより簡単な方法で行うためのレシピが含まれています。このレシピは増え続けており、今後もさらに多くのレシピで対象範囲を拡大していく予定です。

これは、Senseiがどのようにレガシーコードの移行を簡単にするのかを理解するのに役立つかもしれないサンプル移行の例です。

Video of how to set java.time zoned date time

反復的な手動移行から自動コード変換まで

では、新しい DateTime を作成する例を見てみましょう。1 行のコードを Joda-Time から java.time に移行する際に隠れた落とし穴がいくつか見えてきます。次に、「java.time の標準化 (JSR-310)」クックブックにある Sensei レシピの 1 つを見て、すべての開発者が同じ移行を何度も再利用できるように、この情報がどのように取り込まれているかを示します。

この例では、日付時刻フィールドの値を表す 7 つの int 引数から Joda-Time 日時を構築しています。

これをjava.timeの同等のものに移行するにはどうすればいいですか?

ザの このコンストラクターの Joda-Time での Javadoc 言う:

デフォルトタイムゾーンのIsoChronologyを使用して日時フィールド値からインスタンスを構築します。

最初は、あると思うかもしれません 日付/時刻 java.time のクラスですが、クラスはありません。「joda time から java タイムへの移行」をグーグルで検索すると、おそらく Stephen Colebourne のブログ投稿が見つかるでしょう。 Joda-Time から java.time への変換

これにより、良いスタートを切ることができ、java.time.ZonedDateTime または java.time.OffsetDateTime を使用する方向性がわかります。最初の質問ですが、どれを使えばいいでしょうか?スティーブンのコメントに基づくと、おそらくZonedDateTimeでしょう。

調べてみると ゾーン日付/時刻 javadoc、コンストラクターがまったく表示されません。Stephen のブログ記事に戻ると、さらに読み進めます。

建設。Joda-Time には Object を受け取って型変換を行うコンストラクターがあります。java.time にはファクトリメソッドしかないため、文字列には parse () メソッドが提供されていますが、変換はユーザーの問題です。

そのため、静的ファクトリメソッドが必要です。静的メソッドを検索すると、かなり近いものが見つかりますが、まったく同じではありません。

オリジナルのJoda-Time DateTimeコンストラクターと同様に7つのintパラメーターがありますが、注意を払わないと重要な詳細を見逃してしまいます。7 番目のパラメーターはもはやミリ秒ではなく、代わりにナノ秒を想定しています。これは、java.time が Joda-Time よりも精度が高く、瞬時をナノ秒単位で測定するためです。これは見逃しがちな、重要な詳細事項です。さらに、このメソッドは ZoneID を想定しているので、以前はなぜ必要なかったのか、なぜ今必要なのか不思議に思うでしょう。

デフォルトのタイムゾーンを使用すると説明していた元のコンストラクタのjavadocを思い出してください。デフォルトのZoneIDを取得する方法があるのではないでしょうか。

ザの ゾーン ID 用ジャバドック リストされているコンストラクターについては説明していませんが、使用できる静的メソッドを見るとわかります システムデフォルト ()

ZoneIDを整理したので、ミリ秒からナノ秒への変換について何をすべきでしょうか?java.util.Concurrent.TimeUnit を使用して変換を実行できるかもしれません。

このメソッドは long を返し、このメソッドは int を想定しているので、今度は変換の問題も解決する必要があります。簡単なことをやってみるといいかもしれません。掛け算?

これは動作しますが、少し場違いに見えます。まだお気づきでない方もいらっしゃると思いますが、私たちは 1 行のコードを移行するためにかなりの時間と労力を費やしてきました。しかし、ご想像のとおり、このような編集は手作業で行う必要があり、改善されることはありません。

しかし、java.time APIをもう少し詳しく見てみると、もう少し流暢に見えるソリューションを見つけることができます。

ZonedDateTimeにはミリ秒を設定する明確な方法はありませんが、次の方法で設定できます。 (テンポラル・フィールド・フィールド、長い newValue) メソッド付き、を使用して クロノフィールド. ミリオブセカンド テンポラル・フィールドのように。

そして、Javaのドキュメントには、ナノ秒への変換が自動的に実行されると記載されています。

このフィールドを使用して値を設定する場合、値に1,000,000を掛けた値でNANO_OF_SECONDを設定する場合と同じように動作するはずです。

したがって、ファクトリメソッドでナノ秒に0を指定するだけで、次のようになります。 メソッドを使用して、元の値とミリ秒をすべて含む ZonedDateTime を作成します。

最終結果を見ると、たった1行のコードしか変更していないようで、たった1つの移行の研究に費やした労力が伝わりません。

より迅速かつ簡単に移行するためのレシピを作成

Senseiは、この苦労して得た情報を他の開発者と共有する方法を提供しています。これらすべての要件を網羅したレシピを作成することで、Senseiユーザーはマウスをクリックするだけで移行を実行できるようになります。

Senseiのレシピは、主に3つのセクションで構成されています。

  • メタデータ
  • 検索
  • 適用可能な修正

この呼び出しを同等の java.time に移行するのに役立つ Sensei レシピ (YAML レシピと見なすこともできます) を見てみましょう。

DateTime foo = 新しい日付時刻 (年、月、日、時間、分、秒、ミリ秒)

メタデータセクション

メタデータセクションには、レシピとその使用方法に関する情報が含まれています。

検索セクション

Senseiレシピの検索セクションでは、このレシピを適用するコード要素を指定します。

検索:
インスタンス作成:
引数:
1:
タイプ:整数
2:
タイプ:整数
3:
タイプ:整数
4:
タイプ:整数
5:
タイプ:整数
6:
タイプ:整数
7:
タイプ:整数
引数の数:7
タイプ:org.joda.time.DateTime

この検索セクションでは、次のことがわかります。

  • を検索中 インスタンス作成、 つまり、コンストラクターの使用法です。注:あります 他にも多くの検索ターゲットが利用可能
  • コンストラクターには 7 つの引数が必要です。引数は以下で指定されます。 引数のカウント 財産
  • 引数 1-7 は int 型でなければなりません
  • のコンストラクターを探しています タイプ org.joda.time.DateTime

「利用可能な修正」セクション

AvailableFixes セクションでは、一致するコード要素に適用できる修正を 1 つ以上指定できます。各修正には複数のアクションを設定できますが、今回の場合は 1 つの修正で 2 つのアクションを実行します。

  • ザの 名前 修正のどれかがユーザーに「クイックフィックス」メニューに表示され、ユーザーがこのクイックフィックスを適用した場合に何が起こるかを説明します。
  • アクションリストには、このクイックフィックスによって実行されるアクションが表示されます。
  • ザの 書き換え action は、mustache テンプレートを使用してコード要素を書き換えます。変数と文字列置換関数を使用できます。
  • ザの 割り当てられた変数を変更 action は、このコンストラクターが変数への値の割り当てに使用されているかどうかを確認します。その場合、このアクションは変数を、で指定された型として宣言するように変更します。 タイプ

レシピを使用してコード変換を行う

レシピを記述して有効にすると、コードをスキャンして、適用できるセグメントが強調表示されます。

下のスクリーンショットでは、ターゲットコンストラクターがSenseiによってマークされていることがわかります。マークされたコンストラクターにカーソルを合わせると、レシピの簡単な説明とクイックフィックスオプションが表示されます。 java.time.ZonedDateTime への移行

Migrate New Date Time

を選択した後 java.time.ZonedDateTime への移行 クイックフィックス、コードはレシピで指定したアクションに従って変換されます。

Zoned Date Time With Year Month Day Hour

一回限りの移行とチーム間での統一されたコーディングプラクティス-Senseiで

上記の例からわかるように、1 行のコードを移行するには、苦労して得た知識が必要です。Senseiは、その知識を実用的なレシピや料理本に変えて、チーム内で共有することができます。1 回限りの移行スプリントを計画することも、Joda-Time コードに出くわしたときに java.time を段階的に瞬時に変換するというアプローチをとることもできます。レシピを有効化/無効化することで、論理的な段階または段階的に移行を行うことができ、Sensei がスキャンするファイルの範囲を拡大または縮小することもできます。この柔軟性により、コード移行の負担が軽減されます。

ライブラリの移行は、Senseiを使用してプロジェクトを標準化するさまざまな方法の一例にすぎません。プルリクエストや自分でコーディングしているときに頻繁に遭遇する、アンチパターンや特定の手動コード変換に常に目を光らせておくことができます。次のようなものがある場合 コーディングガイドライン 開発者が見逃しがちですが、ガイドラインをレシピに変換すれば、開発者は承認されたコード変換を自信を持って適用できます。

ご不明な点がございましたら、ぜひお聞かせください。以下のサイトから Slack にご参加ください。 sensei-scw.slack.com

目次

PDF をダウンロード
リソースを表示
もっと興味がありますか?

キャメロンはセキュア・コード・ウォリアーのシニア・ソフトウェア開発者です。15 年以上のソフトウェア提供経験があり、開発者の生産性に情熱を傾け、オープンソースソフトウェアに積極的に貢献しています。

learn more

Secure Code Warriorは、ソフトウェア開発ライフサイクル全体にわたってコードを保護し、サイバーセキュリティを最優先とする文化を築くお手伝いをします。アプリケーションセキュリティマネージャ、開発者、CISO、またはセキュリティ関係者のいずれであっても、安全でないコードに関連するリスクを軽減するお手伝いをします。

デモを予約[ダウンロード]
シェア:
linkedin brandsSocialx logo
リソースハブ

始めるためのリソース

その他の投稿
リソースハブ

始めるためのリソース

その他の投稿