SalesforceでのDataloaderでの日付の扱いと、インポート時に一日ずれる件の検証

Salesforceは、複数言語や世界中のタイムゾーンに対応しており、ユーザごとに自由に言語設定やタイムゾーンを設定できます。

便利なのですが、注意しないと、エクスポート/インポート時に思わぬ時刻ずれが発生してしまうことにもなりかねません。

私自身、いろいろな場面であぶないなーと感じていることもあり、ここらへんの振る舞いをまとめておこうと思います。

Dataloaderでエクスポートした時のフォーマット

データローダーでエクスポートすると、

日付型項目(2016/09/01)  → 2016-09-01
日時型項目(2017/01/01 1:00)  → 2016-12-31T16:00:00.000Z

のようになります。

形式は、「YYYY-MM-DDThh:mm:ss.SSSZ」の形となっています。

エクスポート時、日時の項目はすべて、GMT(グリニッジ標準時)に変換されて上記のように出力されますが、日付項目は、日付で切り捨てされて出力されます。

ここで、「T」は、時刻の要素が始まりますよという印の文字列で、ISO8601で定義されています。

また、「SSS」はミリ秒、最後の「Z」はGMTをあらわします。

Dataloaderのインポート時の問題と振る舞いの整理

ここで、「2016-09-01」の項目をDataloaderでインポートすると、日付が一日前になってしまう問題が知られています。(https://help.salesforce.com/articleView?id=000047804&language=ja&type=1)にも書いてあり、この通りなのですが、ややこしいので、検証して整理してみました。

Dataloaderのタイムゾーン指定

前提として、Salesforceの内部では、日付型、日付時間型項目のデータは全てGMT(グリニッジ標準時)に変換され格納される仕様です。

なお、DataloaderのSettingでは、タイムゾーンを指定でき、「Asia/Tokyo」(GMT+9:00)のように設定することができます。(多くの場合、タイムゾーンには「Asia/Tokyo」が設定されていると思います。)

では、「Asia/Tokyo」はタイムゾーンに指定された設定のDataloaderでSalesforceへのインポートを行うと、何が起こるでしょうか。

この場合、「データにタイムゾーンの指定が無ければ、(GMT+9:00)としてインポートを行う」という動きになります。

つまり、「2016-09-01」は、インポート時に「2016-09-01 00:00(GMT+9:00)」と解釈されるため、「2016-08-31 15:00(GMT)」と変換され、日付としては「2016-08-31」が格納されることになります。

ここでキモなのは「タイムゾーンの指定が無ければ」というところで、日付型は時間の指定がないため、暗黙的にDataloaderの設定のタイムゾーンが使われることになりますが、日時型はそれに限りません。

日時型の項目へは、Dataloaderでは以下のようなフォーマットでもインポートができます。

①「YYYY-MM-DDThh:mm:ss.SSSZ」・・・例:2016-12-31T16:00:00.000Z
②「YYYY-MM-DDThh:mm:ssZ」・・・例:2016-12-31T16:00:00Z
③「YYYY-MM-DDThh:mm:ss」・・・例:2017-01-01T09:00:00

①と②の場合はインポート時もGMTとみなされ、SFDC内に格納されるデータは「2016-12-31T16:00:00.000Z」になります。そして、表示時に、ログインしているユーザのタイムゾーン設定に変換されますので、「Asia/Tokyo」のユーザであれば、「2017/01/01 1:00」と表示されることになります。

③は、インポート時に「2017-01-01T09:00:00(GMT+9:00)」と解釈され、SFDC内に格納されるデータは「2017-01-01T00:00:00.000Z」となり、表示は「Asia/Tokyo」のユーザであれば、「2017/01/01 9:00」となります。

どの運用が良いか

上記の振る舞いの整理を踏まえて、対処法と注意点を考えてみます。

Dataloaderのタイムゾーン設定を「GMT」にする。

運用上、一番間違いが少なさそうなのは、Dataloaderのタイムゾーン設定を「GMT」にすることだと思います。

下記のように日時項目であっても、時刻まで指定したり、一日前の日付を指定するという方法もありますが、エクスポート時に切り捨てられて「2016-09-01」のような形式となってしまうので、それを再度インポートするときにまた一日前に変換しないといけません。

特に、開発時やインポート/エクスポート運用が頻繁な場合は、GMTを指定した方が変換が無く、間違いが少ないと思います。

GMT指定でインポートする

日付項目であっても時刻指定の形式でインポートできますので、「2017-01-01T00:00:00.000Z」のようにGMT指定でインポートすることができます。

こうすると、インポート時にGMTとみなされ、変換が発生しないので、内部的にも「2017-01-01」で格納されます。上記で述べたように、エクスポート時に「2017-01-01」となってしまいますので、再インポート時には注意したいですね。

9時間足した日時をインポートする

「2017-01-01T09:00:00」のようにタイムゾーンの指定無しでインポートすると、Dataloaderのタイムゾーン設定がいかされますので、「Asia/Tokyo」であれば、変換されて、「2017-01-01T00:00:00」でインポートされます。

このやり方も、エクスポート/インポート時に気をつけたい方法ではあります。