Date
たちえば、あるデータベースは2021-03-10 Midnightという日付を返すものの、もう一方のデータベースはこれを2021-03-10 Midnight in Central Europe GMT+2として扱い、UTCに変換して保存し、取り込んだ後に2021-03-09となる日付型に変換します。これはしばしばバグとみなされますが、論理的な説明があります。
データベースは、オブジェクトを2021-03-10として保存します。
これはJavaに送られ、(使用する変換に応じて)次のようになります。
- 2021-03-10 00:00:00.000 UTC
- 2021-03-10 02:00:00.000 GMT+2
次にデータベースに送られ、次のように処理されます:
- 2021-03-10 00:00:00.000 GMT+2
- 2021-03-09 22:00:00.000 UTC
UTCに変換すると、日付が1日繰り上がります。そのため、日付に関連する問題が発生した場合は常に日付全体(タイムゾーン、時間、秒)を分析する必要があります。
精度
Talendはjava.util.Dateを使用しているので、マイクロ秒やナノ秒の精度は利用できません。ただし、コンポーネントによっては、入力されるObject型がjava.sql.Timestampであるかどうかをチェックする場合があります。その場合はナノ秒単位も利用できます。この単位を使用するためには、スキーマ定義でObject型を選択し、ソースとターゲットのコンポーネントでこれをサポートする必要があります。
実行する価値がある実験
どのような問題でも、トラブルシューティングとして次の方法を試すことができます:
- tFileOutputコンポーネントを使い、その値をダンプして読み取る。こうすることで、タイムゾーンをコントロールしやすくなります。
- Duser.timezoneパラメーターを使い、動作が変わるかどうか確認する。詳細は、Time Zone Settings in the JREををご覧ください。
- これらのタイムゾーンの扱い方については、JDBCドライバーのドキュメンテーションをご覧ください。
- 以下のパターンと結果を持つtLogRowコンポーネントを使用する:
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
ターゲットデータベースは、タイムゾーンと組み合わさった前の例のタイムスタンプ部分を保存できる場合もできない場合もあります。それによって日数がずれる可能性があります。
可能な回避策
Strings型を使い、データベースやそのドライバーが変換を処理できるかどうかを確認します。String型であれば、表示されているものがそのまま得られるので、他の隠れた情報はありません。
tJavaRowコンポーネントでJavaコードを使い、タイムゾーンを変換します。
String pattern = "yyyy-MM-dd";
log.info(TalendDate.formatDate(pattern, input_row.startDate));
output_row.startDateUTC = TalendDate.parseDateInUTC("yyyy-MM-dd zzz",
TalendDate.formatDate("yyyy-MM-dd", input_row.startDate)+" UTC");
データ動作の詳細は、Your Calendrical Fallacy Is...をご覧ください。