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)にも書いてあり、この通りなのですが、ややこしいので、検証して整理してみました。
前提として、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」でインポートされます。
このやり方も、エクスポート/インポート時に気をつけたい方法ではあります。