コードの分析およびテスト
データ型およびデータ型変換の正しい使用
文字項目の処理
ABAP SQL でのコードプッシュダウンの使用
内部テーブルのパフォーマンスの改善
権限チェックの実装
効果的なオブジェクト指向コードの設計
例外クラスの定義と処理
ABAP コードへの文書の追加

日付、時刻、タイムスタンプを使用した計算

Objective

After completing this lesson, you will be able to 日付、時刻、タイムスタンプを使用して計算します。

日付、時刻、タイムスタンプを使用した計算

組込 ABAP データ型 D および T により、それぞれ日時を表すことができます。日付の書式は、ユーザの出力書式に関係なく、常に YYYYMMDD です。時刻の書式は、ユーザの出力書式に関係なく、常に 24 時間表記の HHMMSS です。時間は1 秒間正確です。

時刻および日付のシステム情報

クラス cl_abap_context_info により、現在の時刻および日付情報を検索するために使用できるメソッドが提供されます。

詳細については、以下のビデオを視聴してください。

日付および時刻の計算

ABAP では、2 つの日付の差異を検索したり、特定の日付から日数を加算および減算したりするなど、直接日付計算を実行することができます。計算を実行するために、ABAP では日付が整数 (0001/01/01 以降の日数) に変換され、関連する値が加算または減算されます。時間計算の実行時に、ABAP によって時刻が午前 0 時以降の秒数に変換されます。

日付項目でのオフセットおよび長さの使用

ABAP では、日付は YYYYMMDD の書式で保存されます。オフセットと長さを使用して、日付の個々のコンポーネントにアクセスすることができます。たとえば、月にアクセスするには、日付項目の 5 番目と 6 番目の文字が必要です。これを行うには、var_date+4(2) を指定します。これにより、4 文字が日付に入り、次の 2 文字が使用されるようになります。この場合、年、月、日へのアクセスは以下のようになります。

  • 年: var_date(4)
  • 月: var_date+4(2)
  • 日: var_date +6(2)

タイムスタンプフィールドの使用

データ型 D と同様に、ABAP には ISO-8601 に従ったタイムスタンプを表すデータ型 utclong が組み込まれています。このデータ型の精度は 100 ナノ秒で、書式は YYYY-MM-DD HH:MM:SS.sssssss です。

タイムスタンプフィールドの使用方法の詳細については、以下のビデオを視聴してください。

試してみる - 時刻、日付、およびタイムスタンプを使用した計算

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードを METHOD if_oo_adt_classrun~main. 文と ENDMETHOD. 文の間でエディタにコピーします。
    Code Snippet
    123456789101112131415161718192021222324252627
    DATA timestamp1 TYPE utclong. DATA timestamp2 TYPE utclong. DATA difference TYPE decfloat34. DATA date_user TYPE d. DATA time_user TYPE t. timestamp1 = utclong_current( ). out->write( |Current UTC time { timestamp1 }| ). timestamp2 = utclong_add( val = timestamp1 days = 7 ). out->write( |Added 7 days to current UTC time { timestamp2 }| ). difference = utclong_diff( high = timestamp2 low = timestamp1 ). out->write( |Difference between timestamps in seconds: { difference }| ). out->write( |Difference between timestamps in days: { difference / 3600 / 24 }| ). CONVERT UTCLONG utclong_current( ) INTO DATE date_user TIME time_user TIME ZONE cl_abap_context_info=>get_user_time_zone( ). out->write( |UTC timestamp split into date (type D) and time (type T )| ). out->write( |according to the user's time zone (cl_abap_context_info=>get_user_time_zone( ) ).| ). out->write( |{ date_user date = user }, { time_user time = user }| ).
  3. Ctrl + F3 を押してクラスを有効化します。
  4. コードを試して、トピックについて理解します。

タイムスタンプを使用した計算の実行

この演習問題では、旅客フライトの ABAP クラスのコンソール出力にフライト期間を追加します。出発空港と到着空港のさまざまなタイムゾーンを考慮して、出発時刻と到着時刻に基づいて旅客フライトの期間を計算します。

テンプレート:

  • /LRN/CL_S4D401_TCS_TYPE_CONV (グローバルクラス)

ソリューション:

  • /LRN/CL_S4D401_TCS_TIMESTAMP (グローバルクラス)

タスク 1: テンプレートのコピー (オプション)

テンプレートクラス /LRN/CL_S4D401_TCS_TYPE_CONV をコピーします。前の演習問題を完了した場合は、このタスクをスキップし、クラス ZCL_##_SOLUTION の編集を続行することができます。

ステップ

  1. クラス /LRN/CL_S4D401_TCS_TYPE_CONV を独自のパッケージのクラスにコピーします (推奨名: ZCL_##_SOLUTION、## はグループ番号)。

    1. Project Explorer で、クラス /LRN/CL_S4D401_TCS_TYPE_CONV を右クリックしてコンテキストメニューを開きます。

    2. コンテキストメニューから Duplicate.... を選択します。

    3. Package 項目にパッケージの名称を入力します。Name 項目に、ZCL_##_SOLUTION (## はグループ番号) と入力します。

    4. Next を選択します。

    5. 移送依頼を確認し、Finish を選択します。

  2. コピーを有効化します。

    1. Ctrl + F3 を押してクラスを有効化します。

タスク 2: 出力の拡張

ローカルクラス LCL_PASSENGER_FLIGHT を編集し、フライト期間 (分単位) のコンポーネント期間を使用して属性 connection_details を拡張します。次に、GET_DESCRIPTION メソッドを編集し、出力にフライト期間を追加します。

ステップ

  1. ローカルクラス LCL_PASSENGER_FLIGHT で、属性 connection_details を整数型のコンポーネント期間で拡張します。

    1. ローカルクラス LCL_PASSENGER_FLIGHT で、構造データ型 st_connection_details の定義を見つけます。

    2. コードを以下のように調整します。

      ABAP
      12345678
      TYPES: BEGIN OF st_connection_details, airport_from_id TYPE /dmo/airport_from_id, airport_to_id TYPE /dmo/airport_to_id, departure_time TYPE /dmo/flight_departure_time, arrival_time TYPE /dmo/flight_arrival_time, duration TYPE i, END OF st_connection_details.
  2. メソッド GET_DESCRIPTION の実装にナビゲートします。メソッドの最後に、connection_details-duration と r_result に適切な説明を追加する APPEND 文を挿入します。

    1. 以下のコードを追加します。

      ABAP
      1
      APPEND |Duration: { connection_details-duration } minutes| TO r_result.
  3. ABAP クラスを有効化します。

    1. Ctrl + F3 を押します。

タスク 3: 乗客フライトの期間の計算

class_constructor メソッドで、乗客のフライトの期間を計算します。出発時刻と到着時刻を使用し、空港が異なるタイムゾーンにあることを考慮してください。

ヒント

空港のタイムゾーンは、データベーステーブル /LRN/AIRPORT にあります。

ステップ

  1. テーブルのような属性 connections_buffer に列の期間を追加します。

    1. 構造データ型 st_connections_buffer の定義を見つけます。

    2. コードを以下のように調整します。

      ABAP
      12345678910
      TYPES: BEGIN OF st_connections_buffer, carrier_id TYPE /dmo/carrier_id, connection_id TYPE /dmo/connection_id, airport_from_id TYPE /dmo/airport_from_id, airport_to_id TYPE /dmo/airport_to_id, departure_time TYPE /dmo/flight_departure_time, arrival_time TYPE /dmo/flight_arrival_time, duration TYPE i, END OF st_connections_buffer.
  2. メソッド CLASS_CONSTRUCTOR の実装を拡張します。メソッドの開始時に、すべての空港の空港 ID およびタイムゾーンをデータベーステーブル /LRN/AIRPORT からローカルの内部テーブル空港に読み込みます。

    1. コードを以下のように調整します。

      ABAP
      123456789101112
      METHOD class_constructor. SELECT FROM /lrn/airport FIELDS airport_id, timzone INTO TABLE @DATA(airports). SELECT FROM /lrn/connection FIELDS carrier_id, connection_id, airport_from_id, airport_to_id, departure_time, arrival_time INTO TABLE @connections_buffer. ENDMETHOD.
  3. メソッドの最後に、インラインで宣言された作業領域 (推奨名: connection) を使用して、connections_buffer 属性に対するループを追加します。

    1. コードを以下のように調整します。

      ABAP
      12345678910111213141516
      METHOD class_constructor. SELECT FROM /lrn/airport FIELDS airport_id, timzone INTO TABLE @DATA(airports). SELECT FROM /lrn/connection FIELDS carrier_id, connection_id, airport_from_id, airport_to_id, departure_time, arrival_time INTO TABLE @connections_buffer. LOOP AT connections_buffer INTO DATA(connection). ENDLOOP. ENDMETHOD.
  4. ABAP 命令 CONVERT … INTO UTCLONG を使用して、現地時間の出発時刻を汎用タイムスタンプに変換します。タイムゾーンとして、出発空港のタイムゾーンを使用し、日付として現在のシステム日付を使用します。

    注意

    CONVERT ...INTO UTCLONG 命令では、日付、時刻、およびタイムゾーンが取得され、これらの値が UTC タイムスタンプに変換されます。この演習問題では、現在のシステム日付を出発と到着の両方の参照日付として使用します。つまり、フライト接続が日付変更線を越えていないと仮定します。これは、演習問題シナリオに対して行われるシンプル化です。日付軸をまたぐ接続の場合、計算結果は不適切な期間値になります。

    ヒント

    メソッド cl_abap_context_info=>get_system_date を呼び出して、現在のシステム日付を取得します。
    1. コードを以下のように調整します。

      ABAP
      12345678
      DATA(today) = cl_abap_context_info=>get_system_date( ). LOOP AT connections_buffer INTO DATA(connection). CONVERT DATE today TIME connection-departure_time TIME ZONE airports[ airport_id = connection-airport_from_id ]-timzone INTO UTCLONG DATA(departure_utclong). ENDLOOP.
  5. 到着時刻と到着空港についても同様の処理を行います。

    1. コードを以下のように調整します。

      ABAP
      12345678910111213
      DATA(today) = cl_abap_context_info=>get_system_date( ). LOOP AT connections_buffer INTO DATA(connection). CONVERT DATE today TIME connection-departure_time TIME ZONE airports[ airport_id = connection-airport_from_id ]-timzone INTO UTCLONG DATA(departure_utclong). CONVERT DATE today TIME connection-arrival_time TIME ZONE airports[ airport_id = connection-airport_to_id ]-timzone INTO UTCLONG DATA(arrival_utclong). ENDLOOP.
  6. 作業領域接続の構成品目期間に、2 つの UTC タイムスタンプの差異 (分) を入力します。

    注記

    組み込み関数 utclong_diff を使用して、差異を計算します。この関数は差を秒単位で返すことに注意してください。
    1. コードを以下のように調整します。

      ABAP
      12345678910111213141516
      LOOP AT connections_buffer INTO DATA(connection). CONVERT DATE today TIME connection-departure_time TIME ZONE airports[ airport_id = connection-airport_from_id ]-timzone INTO UTCLONG DATA(departure_utclong). CONVERT DATE today TIME connection-arrival_time TIME ZONE airports[ airport_id = connection-airport_to_id ]-timzone INTO UTCLONG DATA(arrival_utclong). connection-duration = utclong_diff( high = arrival_utclong low = departure_utclong ) / 60. ENDLOOP.
  7. 最後に、ループ内で MODIFY 命令を使用して、内部テーブル connections_buffer の現在の行を作業領域からのコンポーネント期間の新規内容で更新します。

    1. コードを以下のように調整します。

      ABAP
      123456
      connection-duration = utclong_diff( high = arrival_utclong low = departure_utclong ) / 60. MODIFY connections_buffer FROM connection TRANSPORTING duration.
  8. コードをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。