日時の列の動作と形式
世界中にユーザーと事務所がある場合、複数のタイム ゾーンで日付と時刻の値を適切に表現することが重要です。 DateTimeAttributeMetadata (DateTimeAttributeMetadata EntityType または DateTimeAttributeMetadata Class) は、Microsoft Dataverse で型 DateTime の列を定義および管理するために使用されます。 DateTimeBehavior プロパティを使用して (組織サービスについては、DateTimeAttributeMetadata.DateTimeBehavior Property を参照してください)、日付と時刻の値をタイム ゾーン情報を付けて格納するか、付けないで格納するかを定義し、DateTimeAttributeMetadata.Format Property を使用してこれらの列の表示形式を指定します。
注意
エンティティとテーブルの違いがわかりませんか? Microsoft Dataverse で「開発者: 用語を理解する」を参照してください。
また、 Dataverse のカスタマイズ領域を使用して、日時列の動作と形式を定義します。 詳細情報: 日時の列の動作と形式。
注意
Dataverse のすべての日付と時刻の列は、初期値に 1/1/1753 12:00 AM をサポートします。
日時列の動作を指定する
DateTimeBehavior (DateTimeBehavior ComplexType または DateTimeBehavior Class) を使用して DateTimeAttributeMetadata EntityType.DateTimeBehavior プロパティの値を指定することができます。 DateTimeBehavior には次のメンバーが含まれます。各メンバーは、メンバー名と同じ値の文字列を返します:
| メンバーの名前および値 | 内容 |
|---|---|
UserLocal |
- 日時値を UTC 値としてシステムに格納します。 - 取得操作によって UTC 値が返されます。 - 更新操作は UTC 値を現在のユーザーのタイム ゾーン値に変換し、更新に対して指定された値の種類 (DateTimeKind) に基づいて、更新された値をそのまま、あるいは同等の UTC 値として格納します。 指定された値の種類が UTC の場合は、そのまま格納されます。 そうでない場合は、UTC 相当値が格納されます。 - 書式設定された値を取得すると、UTC から、ユーザーのタイム ゾーンとロケールの設定に基づいて、ユーザーの現在のタイム ゾーンを変換されます。 - Web API の場合、列は DateTimeOffset として公開されます。 - この動作は、 CreatedOn および ModifiedOn のようなシステム列に使用され、変更することはできません。 日時値をタイム ゾーン情報を付けて格納するユーザー定義列の動作に対して、これを使用します。 |
DateOnly |
- 時刻値なしで、実際値の日付の値を格納します。 - フォーマットされた値を取得すると、日付の値が表示されます。 - Web API の場合、列は Date として公開されます。 - この動作は、時刻情報が必要とされない生年月日や記念日を格納する、ユーザー定義の列に対して使用します。 |
TimeZoneIndependent |
- ユーザーのタイムゾーンに関係なく、実際の日時値をシステムに格納します。 - 取得および更新操作の場合、タイム ゾーンの変換は行われません、実際の日付と時刻の値が返されて、ユーザーのタイム ゾーンに関係なく、システム内でそれぞれ更新されます。 - 書式設定された値を取得すると、現在のユーザーのタイム ゾーンとロケールの設定で指定された形式に基づいて、日付と時刻の値が (タイム ゾーンの変換なしで) 表示されます。 - Web API の場合、列は DateTimeOffset として公開されます。 - この動作は、ホテルのチェックインおよびチェック アウトの時間などの情報を格納する列に対して使用されます。 |
次のサンプル コードは、新しい日時列の UserLocal 動作の設定方法を示しています :
// Create a date time attribute for the Account
// with the UserLocal behavior
dtAttribute = new DateTimeAttributeMetadata
{
SchemaName = "new_SampleDateTimeAttribute",
DisplayName = new Label("Sample Date Time Attribute", _languageCode),
RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
Description = new Label("Created by SDK Sample", _languageCode),
DateTimeBehavior = DateTimeBehavior.UserLocal,
Format = DateTimeFormat.DateAndTime,
ImeMode = ImeMode.Disabled
};
CreateAttributeRequest createAttributeRequest = new CreateAttributeRequest
{
EntityName = Account.EntityLogicalName,
Attribute = dtAttribute
};
_serviceProxy.Execute(createAttributeRequest);
Console.WriteLine("Created attribute '{0}' with UserLocal behavior\nfor the Account.\n",
dtAttribute.SchemaName);
このサンプル コードでは、文字列値 DateTimeBehavior = "UserLocal" を直接指定することによって、 DateTimeBehavior プロパティの値を設定することもできます。
日付と時刻の列の作成時に動作を指定しなかった場合、既定では UserLocal の動作で列が作成されます。
重要
- 動作を
DateOnlyまたはTimeZoneIndependentに設定した状態で、日時の列を作成すると、この列の動作は変更できません。 詳細情報 : DateTime 列の動作を変更する DateOnlyまたはTimeZoneIndependentの動作を持つ日付と時刻の列は、オフライン モードの旧バージョンの Dynamics 365 for Outlook クライアントで編集した場合、UserLocalの動作をするものとして処理されます。 これは、このクライアントが新しい動作を認識せず、その動作をUserLocalと区別して処理しないことによります。 日時の列はアップグレードで新しい動作に変換されません。したがって、ベスト プラクティスは、カスタマイザーが新しい動作のいずれかを採用する前に、すべての Dataverse クライアントを最新のリリースにアップグレードすることです。 オンライン時には、列のデータを新しい行動で編集しても問題なく動作します。
日付・時間の列の形式を指定する
Format プロパティを使用して、列がシステムにどのように保存されているかに関係なく、属性の日付/時刻の表示形式を指定します。 DateTimeFormat 列挙体 (DateTimeFormat EnumType or DateTimeFormat Enum) を使用して、 DateAndTime または DateOnly のいずれかの表示形式を指定できます。
DateTimeAttributeMetadata.DateTimeBehavior プロパティが DateOnly に設定されている場合、 DateTimeAttributeMetadata.Format プロパティの値を DateAndTime に設定または変更することはできません。
[日付のみ] の動作でサポートされない日付および時刻のクエリ演算子
時刻関連のクエリ演算子は、 DateOnly 動作に対してはサポートされません。 ここに表示されている時間固有のクエリ演算子を除いて、すべてのクエリ演算子がサポートされます。
- が X 分よりも古い
- X 時間よりも古い
- が過去 X 時間
- が今後 X 時間
詳細情報: FetchXML の会計日クエリ演算子および older than 日付/時刻クエリ演算子
OData API を使用してユーザーのローカルの日付と時刻の値を送信する
Microsoft Power Platform で、ユーザーが UI を介してユーザー固有のタイムゾーンで日付と時刻を送信すると、自動計算によってデータが正しい日付と時刻に設定されます。 分析を実行して、列とUI設定に基づいて、送信された日付を対応する UTC 値に変更します。 OData API 操作を使用して日付と時刻の値を送信すると、計算が行われず、原因不明のデータが表示されます。 たとえば、太平洋標準時で4/4 / 2021 12:00 を送信すると、次のようになります。
- 元: 4/4/2021 12:00 の送信者は太平洋時間のタイムゾーンにいます。
- UI を介して送信され、ユーザー ローカルとして取得: 4/4/2021 12:00
- API を介して送信され、ユーザー ローカルとして取得: 4/4/2021 04:00
UI から送信する
UI はユーザー ローカルに設定され、列はユーザー ローカルに設定されます。
- 元の値: 4/4/2021 12:00 の送信者は太平洋時間のタイムゾーンにいます。
- UTC に計算され、Dataverse に保存された値: 4/4/2021 12:00 + 8:00 = 4/4/2021T20:00:00Z。 これは、PST が UTC から -8:00 であるため、保存された値に +8 が追加されるためです。
- 太平洋時間タイムゾーンのユーザーが UI に表示したときの値: 4/4/2021 12:00。 UI は、正しい値のために -8:00 UTC オフセット計算を 4/4/2021T20:00:00Z に適用します。
API から送信する
UI はユーザー ローカルに設定され、列はユーザー ローカルに設定されます。
- 元の値: 4/4/2021T12:00:00 または 4/4/2021T12:00:00Z – オフセットまたは UTC インジケーターは提供されません。 この送信者は太平洋時間のタイムゾーンにいます。
- UTC に計算され、Dataverse に保存された値: OData API からの送信時に UI 計算は行われないため、値は 4/4/2021T12:00:00Z として保存されます。
- 太平洋時間タイムゾーンのユーザーが UI に表示したときの値: 4/4/2021 4:00。 UI は、Dataverse の値に -8:00 UTC オフセット計算を適用します。
API 呼び出しを使用してユーザーのローカル列にデータを入力するときにこの問題を回避するには、データを送信するユーザーのオフセットを計算し、オフセットを適用する必要があります。
上記の例を使用する: 4/4 / 2021 12:00 は 4/4/2021T12:00:00-08:00 のように API を介して送信する必要があります。 元の日時で現在のユーザーのタイム ゾーンのオフセット計算が含まれます。 または、送信者は送信前に計算を実行して 4/4/2021T20:00:00Z を送信することもできます。
オフセット計算を含めることを選択した場合、UTC インジケーターであるZを使用することはできず、オフセットがシステムによって受け入れられなくなります。
日付・時間の列の動作の変更
Dataverse インスタンスでシステム カスタマイザー ロールを所有していて、日時列の DateTimeAttributeMetadata.CanChangeDateTimeBehavior の管理プロパティが True に設定されている場合、日時列を更新してその動作を変更できます。
注意事項
日時の列の動作を変更するには、その前に、業務ルール、ワークフロー、計算フィールド、またはロールアップ列などの列のすべての依存性を検討して、動作の変更によって問題が発生しないことを確認する必要があります。 システム カスタマイザーは、 DateTimeAttributeMetadata.CanChangeDateTimeBehavior マネージド プロパティを使用して、既存の日時の列の動作の変更を制限できます。
少なくとも、日時列の動作を変更した後は、変更した日時列に依存する業務ルール、ワークフロー、計算列、およびロールアップ列の各レコードを開き、情報を確認してからレコードを保存し、最新の列の動作と値が使用されるようにする必要があります。
計算列またはロールアップ列のデータおよび時間の動作を変更した後、計算列またはロールアップ列定義エディタを開き、列定義を保存して、動作変更後も列が有効であることを確認してください。 システム カスタマイザーは、Dataverse のカスタマイズ エリアで フィールドタイプ の横にある 編集 をクリックすると、計算列やロールアップ列の列定義エディタを開くことができます。 詳細情報: 計算列を定義して手動計算を自動化するおよびロールアップ列を定義して値を集計する
既成のテーブルおよびカスタムテーブルの
CreatedOnおよびModifiedOn列の動作はUserLocalに設定されており、DateTimeAttributeMetadata.CanChangeDateTimeBehavior管理プロパティはFalseに設定されているため、これらの列の動作を変更できないことを意味します。 ユーザー定義テーブルのこれらの列のDateTimeAttributeMetadata.CanChangeDateTimeBehavior管理プロパティの値を変更することはできますが、列の動作は変更できません。新しいユーザー定義の日時列の場合は、
DateTimeAttributeMetadata.CanChangeDateTimeBehavior管理プロパティがTrueに設定されています。 このことは、ユーザー定義の日時列の動作を、UserLocalからDateOnlyまたはTimeZoneIndependentのいずれかに変更できることを意味しています。他の動作の移行は使用できません。Dataverse 組織の一部であるカスタムの日付と時刻の列については、その列または親テーブルがカスタマイズできない場合を除き、
DateTimeAttributeMetadata.CanChangeDateTimeBehaviorの管理プロパティがTrueに設定されます。注意
列の
DateTimeAttributeMetadata.DateTimeBehaviorプロパティをUserLocalからDateOnlyに更新する際は、DateTimeAttributeMetadata.Formatプロパティも必ずDateAndTimeからDateOnlyに変更してください。 そうしなければ、例外が発生します。Dataverse の以下のおおよその日付と時刻の列は、既定で
DateOnlyに設定されており、DateTimeAttributeMetadata.CanChangeDateTimeBehaviorの管理プロパティはこれらの列のFalseに設定されています。これは、これらの列の動作を変更できないことを意味しています。日付と時刻の列 親テーブル anniversary 取引先担当者 birthdate 取引先担当者 duedate 請求書 estimatedclosedate リード actualclosedate 営業案件 estimatedclosedate 営業案件 finaldecisiondate 営業案件 validfromdate 製品 validtodate 製品 closedon 見積もり expireson 見積もり これらの列の動作は
UserLocalに、DateTimeAttributeMetadata.CanChangeDateTimeBehaviorの管理プロパティはTrueに設定されていますが、これらの列の動作をDateOnlyのみに変更することができます。 他の動作の移行は使用できません。
列の動作の更新後、変更が有効にするには、カスタマイズを公開する必要があります。 日時列の動作を更新することによって、列の動作の変更 後 に入力または更新されたすべての値が、新しい動作でシステムに格納されるようになります。 これは、データベースにすでに格納されている値には影響を与えず、それらは引き続き UTC 値として保存されます。 ただし、既存の値を SDK を使用して取得したり、UI でそれを表示するときは、既存の値はその列の新しい動作にしたがって表示されます。 たとえば、取引先企業エンティティに関するユーザー定義の列の動作を、 UserLocal から DateOnly に変更し、SDK を使用して既存の取引先企業レコードを取り出した場合、日付と時刻は、 <Date> の後に 12 AM (00:00:00) が続く形式で表示されます。 同様に、 UserLocal から TimeZoneIndependent への動作の変更の場合、データベースにある実際の値は、タイム ゾーンの変換なしに、そのまま表示されます。
次のサンプル コードは、新しい日時の列の動作の更新方法を示しています :
// Retrieve the attribute to update its behavior and format
RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest
{
EntityLogicalName = Account.EntityLogicalName,
LogicalName = "new_sampledatetimeattribute",
RetrieveAsIfPublished = false
};
// Execute the request
RetrieveAttributeResponse attributeResponse =
(RetrieveAttributeResponse)_serviceProxy.Execute(attributeRequest);
Console.WriteLine("Retrieved the attribute '{0}'.",
attributeResponse.AttributeMetadata.SchemaName);
// Modify the values of the retrieved attribute
DateTimeAttributeMetadata retrievedAttributeMetadata =
(DateTimeAttributeMetadata)attributeResponse.AttributeMetadata;
retrievedAttributeMetadata.DateTimeBehavior = DateTimeBehavior.DateOnly;
retrievedAttributeMetadata.Format = DateTimeFormat.DateOnly;
// Update the attribute with the modified value
UpdateAttributeRequest updateRequest = new UpdateAttributeRequest
{
Attribute = retrievedAttributeMetadata,
EntityName = Account.EntityLogicalName,
MergeLabels = false
};
_serviceProxy.Execute(updateRequest);
Console.WriteLine("Updated the behavior and format of '{0}' to DateOnly.",
retrievedAttributeMetadata.SchemaName);
// Publish customizations to the account
PublishXmlRequest pxReq = new PublishXmlRequest
{
ParameterXml = String.Format("<importexportxml><entities><entity>account</entity></entities></importexportxml>")
};
_serviceProxy.Execute(pxReq);
Console.WriteLine("Published customizations to the Account .\n");
データベース内の既存の日時値の動作の変換
日時の列を更新して、属性の動作を UserLocal から DateOnly または TimeZoneIndependent に変更する場合、データベース内の既存の列の値は自動的に変換されません。 動作変更は、動作の変更 後 に列に入力または更新される値にのみ影響します。 システム内の既存の日付および時刻の値は引き続き UTC 形式であり、前のセクションで説明したとおりに、SDK を使用してまたは UI で取得されたときに、新しい動作にしたがって Dataverse によって表示されます。 動作が UserLocal から DateOnly に変更された列については、データベース内の既存の UTC 値を適切な DateOnly 値に変換し、ConvertDateAndTimeBehavior メッセージを使用してデータの異常を回避することができます。
このメッセージを使用すると、UTC から DateOnly への値の変換に使用するタイム ゾーンを選択するための変換ルール (組織サービスと連携する場合、 ConversionRuleを参照してください) を指定できます。 次のいずれかの変換ルールを指定できます。
SpecificTimeZone: 指定された Dataverse のタイム ゾーンに従い、UTC 値を DateOnly 値に変換します。 この場合、 TimeZoneCode パラメーターの値を指定する必要もあります。CreatedByTimeZone: UTC 値を、レコードを作成したユーザーの UI に表示される DateOnly 値に変換します。OwnerTimeZone: UTC値を、レコードを所有するユーザーの UI に表示するDateOnly値に変換します。LastUpdatedByTimeZone: UTC 値を、レコードを最後に更新したユーザーの UI に表示する DateOnly 値に変換します。
DateTimeBehaviorConversionRule クラスの 4 つのメンバーのいずれかを使用して、 ConversionRule パラメーターの有効な値を指定できます。
注意
ConvertDateAndTimeBehaviorRequest メッセージを実行するには、Dataverse インスタンスのシステム管理者ロールが必要です。
ConvertDateAndTimeBehavior (組織サービスと連携する場合、 ConvertDateAndTimeBehaviorRequest メッセージを参照してください)を実行するとき、システム ジョブ (非同期処理) が作成されて、変換要求が実行されます。 メッセージ応答の ConvertDateAndTimeBehaviorResponse.JobId 列には、変換の結果として作成されたシステム ジョブの ID が表示されます。 システム ジョブが完了したら、ジョブの詳細 (AsyncOperation.Message) をチェックして、変換の詳細またはエラーを必要に応じて表示します。
注意
複数の列の変換を 1 つの変換ジョブにまとめて、1 つのジョブを一度に実行することを推奨します。これにより、変換時に競合がなくなり、また最適なシステム パフォーマンスが得られます。
ConvertDateAndTimeBehavior メッセージを使用する際に、以下のいくつかの考慮を必要とする重要な点があります。
- メッセージの実行中は、 Dataverse のソリューションをインポートや、列や親テーブルを削除するなどの大きな変更は避ける必要があります。 これを行うと、予期しない動作が発生することがあります。ただし、データの損失は発生しません。
- メッセージの実行結果としてシステムで行われる更新では、ワークフローとプラグインは実行されません。
- メッセージの実行結果としてシステムで行われる更新では、列の 「最終修正日」 の値は変更されませんが、更新の監査が行われて、管理者が列の変換の時刻および元の値と変更後の値を確認しやすくなります。
次のサンプル コードは、 メッセージの使用方法を示しています。
ConvertDateAndTimeBehaviorRequest request = new ConvertDateAndTimeBehaviorRequest()
{
Attributes = new EntityAttributeCollection()
{
new KeyValuePair<string, StringCollection>("account", new StringCollection()
{ "new_sampledatetimeattribute" })
},
ConversionRule = DateTimeBehaviorConversionRule.SpecificTimeZone.Value,
TimeZoneCode = 190, // Time zone code for India Standard Time (IST) in CRM
AutoConvert = false // Conversion must be done using ConversionRule
};
// Execute the request
ConvertDateAndTimeBehaviorResponse response = (ConvertDateAndTimeBehaviorResponse)_serviceProxy.Execute(request);
タイムゾーンを使用するためのベスト プラクティス
期待していた日付/時刻列 (UTC /ローカル) で、反対の値が表示される
これは、列の設定とアプリのフォームの設定が一致していないことが原因です。 列がタイム ゾーン非依存、またはユーザーローカルに構成されている場合、ストアからデータを取得する際にタイムゾーン オフセットを尊重するかどうかを決定します。 ただし、アプリ フォームには UTC またはローカルの設定もあります。
これは、Dataverse から受け取ったデータをどのように解釈するかをフォームに指示します。 ストアから取得したデータがタイム ゾーンに依存しないが、フォームがローカルに設定されている場合、UTC データはユーザーのタイム ゾーンに基づいてユーザーのローカル タイムとしてプロファイルに表示されます。 この逆も当てはまります。フォームが UTC に設定されている場合、ストアからのユーザー ローカル値は UTC として表示されます。 幸い、フォームの日付タイム ゾーン値は、既存のレコードを中断することなく変更できます。
列に「日付のみ」を指定しても、フォームには日付と一緒に時間が表示される
これは、日付のみの列にタイムゾーンに依存しない動作、またはユーザー ローカルの動作を選択した場合に発生します。 Dataverse の場合、既定では [00:00:00] の時間が保存されますが、この列をフォームに追加すると、時間も設定する必要があるとみなされます。 フォームに時間ピッカーを残した場合、ユーザーは時間を入力でき 00:00:00 以外として保存されます。 こちらがこれを修正する方法です。
- フォームを編集して、時間ピッカーと関連する数式を削除します。 これにより、時刻が 00:00:00 として保存され、タイム ゾーン ベースの日付計算が可能になります。
- 列が現在ユーザー ローカルに設定されていて、日付をタイム ゾーンで計算する必要がない場合は、日付のみに変更できます。 この変更は永続的であり、元に戻すことができません。 この変更は、タイム ゾーン非依存の動作列には行うことができません。 他のアプリ、プラグイン、ワークフローがデータに依存している可能性があるため、動作の変更には常に注意してください。
日付のみの列で、一部のユーザーに対して間違った日付が表示される
このような場合は、日付のみのカラムに設定されている動作を確認してください。 列がタイムゾーンに依存しない、またはユーザー ローカルに設定されている場合、含まれているタイム スタンプにより、ユーザーごとに日付が異なって表示されます。 UTC やローカルのフォーム表示設定により、表示される日付がユーザーのタイム ゾーン設定を使用して計算されるのか、それとも UTC 値として表示されるのかが決まります。 フォームの値をユーザー ローカルではなく UTC に変更すると、タイム ゾーン オフセットの計算ができなくなり、保存されたレコードの UTC での日付が表示されます。 別の方法として、これを変更しない静的な日付にする必要があり、カラムが現在ユーザー ローカルである場合は、カラムの動作を [日付のみ] に変更することができます。 これは元に戻すことはできませんのでご注意ください。
私 (スクリプト/プラグイン) は、ユーザー ローカル変換が発生する前に、ユニバーサル クライアントを使用して送信された日付をインターセプトする必要がありますが、代わりにユーザー ローカル データとして扱われます
UTC とユーザー ローカルの間でデータが変換される場合、Web クライアントとユニバーサル クライアントの動作は少し異なります。 Web クライアントでは、日付がクライアントに入力され、提供されたとおりに API に渡され、後でユーザーのローカル時間に変換されます。 これにより、スクリプト/プラグインがデータを取得し、データがプラットフォーム サービスに渡されてユーザーのローカル時間に変換される前にアクションを実行できるようになりました。 ユニバーサル クライアントでは、データが API に渡される前に日付からユーザーローカル値への変換が行われます。これにより、提供されるデータは UTC 日付ではなく、取得または投稿したユーザーに基づいてユーザー ローカルになります。
これを解決するには、ユーザーは次のいずれかを実行できます。
- フォームを UTC 値を保持するタイムゾーン非依存に変更します。 これは、ユーザーがユーザー ローカル時間でフォームを表示する必要がない場合にのみ機能します。
- スクリプトを変更して、使用されているタイムゾーン オフセットを検出し、スクリプト内で UTC に再計算して、アクションを実行します。
参照
日時の列の動作と形式
列の概要
ConvertDateAndTimeBehaviorRequest
DateTimeAttributeMetadata
ブログ: 日付と時刻のデータの送信方法は重要ですか?
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。
フィードバック
フィードバックの送信と表示