この演習問題では、旅客フライトの ABAP クラスのコンソール出力にフライト期間を追加します。出発空港と到着空港のさまざまなタイムゾーンを考慮して、出発時刻と到着時刻に基づいて旅客フライトの期間を計算します。
タスク 1: テンプレートのコピー (オプション)
テンプレートクラス /LRN/CL_S4D401_TCS_TYPE_CONV をコピーします。前の演習問題を完了した場合は、このタスクをスキップし、クラス ZCL_##_SOLUTION の編集を続行することができます。
ステップ
クラス /LRN/CL_S4D401_TCS_TYPE_CONV を独自のパッケージのクラスにコピーします (推奨名: ZCL_##_SOLUTION、## はグループ番号)。
Project Explorer で、クラス /LRN/CL_S4D401_TCS_TYPE_CONV を右クリックしてコンテキストメニューを開きます。
コンテキストメニューから Duplicate.... を選択します。
Package 項目にパッケージの名称を入力します。Name 項目に、ZCL_##_SOLUTION (## はグループ番号) と入力します。
Next を選択します。
移送依頼を確認し、Finish を選択します。
コピーを有効化します。
Ctrl + F3 を押してクラスを有効化します。
タスク 2: 出力の拡張
ローカルクラス LCL_PASSENGER_FLIGHT を編集し、フライト期間 (分単位) のコンポーネント期間を使用して属性 connection_details を拡張します。次に、GET_DESCRIPTION メソッドを編集し、出力にフライト期間を追加します。
ステップ
ローカルクラス LCL_PASSENGER_FLIGHT で、属性 connection_details を整数型のコンポーネント期間で拡張します。
ローカルクラス LCL_PASSENGER_FLIGHT で、構造データ型 st_connection_details の定義を見つけます。
コードを以下のように調整します。
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.
メソッド GET_DESCRIPTION の実装にナビゲートします。メソッドの最後に、connection_details-duration と r_result に適切な説明を追加する APPEND 文を挿入します。
以下のコードを追加します。
1
APPEND |Duration: { connection_details-duration } minutes| TO r_result.
ABAP クラスを有効化します。
Ctrl + F3 を押します。
タスク 3: 乗客フライトの期間の計算
class_constructor メソッドで、乗客のフライトの期間を計算します。出発時刻と到着時刻を使用し、空港が異なるタイムゾーンにあることを考慮してください。
ヒント
空港のタイムゾーンは、データベーステーブル /LRN/AIRPORT にあります。
ステップ
テーブルのような属性 connections_buffer に列の期間を追加します。
構造データ型 st_connections_buffer の定義を見つけます。
コードを以下のように調整します。
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.
メソッド CLASS_CONSTRUCTOR の実装を拡張します。メソッドの開始時に、すべての空港の空港 ID およびタイムゾーンをデータベーステーブル /LRN/AIRPORT からローカルの内部テーブル空港に読み込みます。
コードを以下のように調整します。
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.
メソッドの最後に、インラインで宣言された作業領域 (推奨名: connection) を使用して、connections_buffer 属性に対するループを追加します。
コードを以下のように調整します。
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.
ABAP 命令 CONVERT … INTO UTCLONG を使用して、現地時間の出発時刻を汎用タイムスタンプに変換します。タイムゾーンとして、出発空港のタイムゾーンを使用し、日付として現在のシステム日付を使用します。
注意
CONVERT ...INTO UTCLONG 命令では、日付、時刻、およびタイムゾーンが取得され、これらの値が UTC タイムスタンプに変換されます。この演習問題では、現在のシステム日付を出発と到着の両方の参照日付として使用します。つまり、フライト接続が日付変更線を越えていないと仮定します。これは、演習問題シナリオに対して行われるシンプル化です。日付軸をまたぐ接続の場合、計算結果は不適切な期間値になります。
ヒント
メソッド cl_abap_context_info=>get_system_date を呼び出して、現在のシステム日付を取得します。
コードを以下のように調整します。
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.
到着時刻と到着空港についても同様の処理を行います。
コードを以下のように調整します。
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.
作業領域接続の構成品目期間に、2 つの UTC タイムスタンプの差異 (分) を入力します。
注記
組み込み関数 utclong_diff を使用して、差異を計算します。この関数は差を秒単位で返すことに注意してください。
コードを以下のように調整します。
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.
最後に、ループ内で MODIFY 命令を使用して、内部テーブル connections_buffer の現在の行を作業領域からのコンポーネント期間の新規内容で更新します。
コードを以下のように調整します。
123456
connection-duration = utclong_diff(
high = arrival_utclong
low = departure_utclong
) / 60.
MODIFY connections_buffer FROM connection TRANSPORTING duration.
コードをコンソールアプリとして有効化してテストします。
Ctrl + F3 を押します。
F9 を押します。