世界中にユーザーと事務所がある場合、複数のタイム ゾーンで日付と時刻の値を適切に表現することが重要です。
DateTimeAttributeMetadata (DateTimeAttributeMetadata エンティティ型または DateTimeAttributeMetadata クラス) を使用して、Microsoft Dataverse でDateTime型の列を定義および管理します。
DateTimeBehavior プロパティ (SDK for .NET の場合は DateTimeBehavior プロパティを参照) を使用して、日付と時刻の値をタイム ゾーン情報の有無にかかわらず格納するかどうかを定義します。
DateTimeAttributeMetadata.Format プロパティを使用して、これらの列の表示形式を指定します。
また、 Dataverse のカスタマイズ領域を使用して、日時列の動作と形式を定義します。 詳細については、「 日付と時刻」列の動作と形式を参照してください。
注意
Dataverse のすべての日付と時刻の列は、初期値に 1/1/1753 12:00 AM をサポートします。
[日付のみ] フィールドまたは [日付時刻] フィールドがソリューション内にある場合は、発行元の場合にのみ、既存の管理フィールドの動作を変更できます。 これらのフィールドを変更するには、[日付のみ] 列または [日付時刻] 列を追加したソリューションをアップグレードする必要があります。 詳細については、「ソリューションの アップグレードまたは更新」を参照してください。
日時列の動作を指定する
DateTimeBehavior型の値を指定するには、 (DateTimeBehavior 複合型または DateTimeBehavior クラス) を使用します。
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 動作の設定方法を示しています :
/// <summary>
/// Create a new DateTime column for the Account table with UserLocal behavior
/// </summary>
/// <param name="service">Authenticated IOrganizationService instance</param>
static void CreateUserLocalDateTimeColumn(IOrganizationService service) {
int _languageCode = 1033; //English
DateTimeAttributeMetadata dtAttribute = new()
{
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 = Microsoft.Xrm.Sdk.Metadata.DateTimeFormat.DateAndTime,
ImeMode = ImeMode.Disabled
};
CreateAttributeRequest request = new()
{
EntityName = Account.EntityLogicalName,
Attribute = dtAttribute
};
service.Execute(request);
}
このサンプル コードでは、文字列値 DateTimeBehavior を直接指定することによって、 DateTimeBehavior = "UserLocal" プロパティの値を設定することもできます。
日付と時刻の列の作成時に動作を指定しなかった場合、既定では UserLocal の動作で列が作成されます。
重要
- 動作が
DateOnlyまたはTimeZoneIndependentに設定された日付と時刻の列を作成すると、列の動作を変更することはできません。 詳細については、「 DateTime 列の動作を変更する」を参照してください。 -
DateOnlyまたはTimeZoneIndependentの動作を持つ日付と時刻の列は、以前のバージョンの Dynamics 365 for Outlook クライアントでオフライン モードで編集した場合のUserLocalの動作と同様に扱われます。 この制限は、クライアントが新しい動作を理解せず、UserLocalとは異なる方法で扱わないためです。 アップグレード時に、日付と時刻の列は新しい動作に変換されません。 この制限を回避するには、カスタマイザーが新しい動作のいずれかを採用する前に、すべての Dataverse クライアントを最新リリースにアップグレードします。 オンラインの場合、新しい動作で列のデータを編集しても問題ありません。
日付・時間の列の形式を指定する
Formatプロパティを使用して、システムが格納する方法に関係なく、列の日付/時刻表示形式を指定します。
DateTimeFormat列挙型 (DateTimeFormat 列挙型または DateTimeFormat 列挙型) を使用して、表示形式 (DateAndTimeまたはDateOnly) を指定します。
DateTimeAttributeMetadata.DateTimeBehavior プロパティを DateOnly に設定した場合、DateTimeAttributeMetadata.Format プロパティの値をDateAndTimeに設定または変更することはできません。
[日付のみ] の動作でサポートされない日付および時刻のクエリ演算子
時刻関連のクエリ演算子は、DateOnly 動作に対してはサポートされません。 ここに表示されている時間固有のクエリ演算子を除いて、すべてのクエリ演算子がサポートされます。
- X分以上経過したもの
- X 時間よりも古い
- 過去X時間
- 次の X 時間
詳細情報: 日付時刻データ演算子
OData API を使用してユーザーのローカルの日付と時刻の値を送信する
Microsoft Power Platform で、ユーザーが UI を介してユーザー固有のタイムゾーンで日付と時刻を送信すると、自動計算によってデータが正しい日付と時刻に設定されます。 分析を実行して、列とUI設定に基づいて、送信された日付を対応する UTC 値に変更します。 Web API 操作を使用して日付と時刻の値を送信しても計算が行われず、原因不明のデータが表示されます。 たとえば、太平洋タイム ゾーンにいて、2021 年 4 月 4 日 12 時 00 分を送信すると、次のようになります。
- 元: 2021年4月4日 12:00 送信者は太平洋時間に属しています。
- UI を介して送信され、ユーザー ローカル形式で取得: 4/4/2021 12:00
- API を介して送信され、ユーザー ローカルとして取得: 4/4/2021 04:00
UI から送信する
UI によって値がユーザー ローカルに設定され、列がユーザー ローカルに設定されます。
- 元の値: 2021年4月4日 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 呼び出しを使用してユーザーのローカル列にデータを入力するときにこの問題を回避するには、データを送信するユーザーのオフセットを計算し、オフセットを適用します。
上記の例を使用して、 2021 年 4 月 4 日 12:00 を API 経由で 4/4/2021T12:00:00-08:00 として送信する必要があります。 元の時刻と日付には、現在のユーザーのタイム ゾーンのオフセット計算が含まれます。 または、送信者は送信前に計算を実行して 4/4/2021T20:00:00Z を送信することもできます。
オフセット計算を含める場合は、Z (UTC インジケーター) は含めないでください。Dataverse ではそれを受け付けないためです。
日付・時間の列の動作の変更
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 時 (00:00:00) として表示されます。 同様に、動作が UserLocal から TimeZoneIndependent に変わる場合、データベース内の実際の値は、タイム ゾーン変換なしでそのまま表示されます。
次のサンプル コードは、日時の列の動作を更新する方法を示しています。
/// <summary>
/// Update the behavior of a DateTime column
/// </summary>
/// <param name="service">Authenticated IOrganizationService instance</param>
static void UpdateBehaviorOfDateTimeColumn(IOrganizationService service) {
// Retrieve the attribute to update its behavior and format
RetrieveAttributeRequest retrieveColumnRequest = new()
{
EntityLogicalName = Account.EntityLogicalName,
LogicalName = "new_sampledatetimeattribute",
RetrieveAsIfPublished = false
};
// Execute the request
RetrieveAttributeResponse attributeResponse =
(RetrieveAttributeResponse)service.Execute(retrieveColumnRequest);
// Modify the values of the retrieved attribute
DateTimeAttributeMetadata retrievedAttributeMetadata =
(DateTimeAttributeMetadata)attributeResponse.AttributeMetadata;
retrievedAttributeMetadata.DateTimeBehavior = DateTimeBehavior.DateOnly;
retrievedAttributeMetadata.Format = Microsoft.Xrm.Sdk.Metadata.DateTimeFormat.DateOnly;
// Update the attribute with the modified value
UpdateAttributeRequest updateRequest = new()
{
Attribute = retrievedAttributeMetadata,
EntityName = Account.EntityLogicalName,
MergeLabels = false
};
service.Execute(updateRequest);
// Publish customizations to the account
PublishXmlRequest pxReq = new()
{
ParameterXml = "<importexportxml><entities><entity>account</entity></entities></importexportxml>"
};
service.Execute(pxReq);
}
データベース内の既存の日時値の動作の変換
日付と時刻の列を更新して動作を UserLocal から DateOnly または TimeZoneIndependentに変更すると、データベース内の既存の列の値は自動的に変換されません。 動作の変更は、動作を変更した 後 に列に入力または更新した値にのみ影響します。 システム内の既存の日付と時刻の値は UTC のままです。 Dataverse では、前のセクションで説明したように、SDK または UI を使用してこれらの値を取得すると、新しい動作に従ってこれらの値が表示されます。 動作が UserLocal から DateOnly に変わる列の場合は、DateOnly メッセージを使用してデータの異常を回避するために、データベース内の既存の UTC 値を適切なConvertDateAndTimeBehavior値に変換できます。
このメッセージを使用すると、変換規則を指定できます (SDK for .NET を使用している場合は、 ConvertDateAndTimeBehaviorRequest.ConversionRule プロパティを参照)、UTC から DateOnly への値の変換に使用するタイム ゾーンを選択できます。 次のいずれかの変換ルールを指定できます。
-
SpecificTimeZone: 指定された Dataverse のタイム ゾーンに従い、UTC 値を DateOnly 値に変換します。 この場合、ConvertDateAndTimeBehaviorRequest.TimeZoneCode パラメーター の値を指定する必要もあります。 -
CreatedByTimeZone: UTC 値を、レコードを作成したユーザーが UI に表示する DateOnly 値に変換します。 -
OwnerTimeZone: UTC 値を、レコードを所有するユーザーが UI に表示する DateOnly 値に変換します。 -
LastUpdatedByTimeZone: UTC 値を、レコードを最後に更新したユーザーが UI に表示する DateOnly 値に変換します。
DateTimeBehaviorConversionRule クラスの 4 つのメンバーのいずれかを使用して、ConversionRule プロパティの有効な値を指定します。
注意
ConvertDateAndTimeBehaviorRequest class メッセージを実行するには、Dataverse インスタンスのシステム管理者ロールが必要です。
ConvertDateAndTimeBehaviorを実行するときに (.NET 用 SDK を使用している場合は、ConvertDateAndTimeBehaviorRequestメッセージを参照)、変換要求を実行するシステム ジョブ (非同期操作) を作成します。 メッセージ応答の ConvertDateAndTimeBehaviorResponse.JobId 列には、変換要求によって作成されるシステム ジョブの ID が表示されます。 システム ジョブが完了したら、ジョブの詳細 (AsyncOperation.Message) をチェックして、変換の詳細またはエラーを必要に応じて表示します。
注意
複数の列の変換を 1 つの変換ジョブにグループ化し、一度に 1 つの変換ジョブを実行して、変換に競合がないことを確認し、最適なシステム パフォーマンスを実現します。
ConvertDateAndTimeBehavior メッセージを使用する場合は、次の点を考慮してください。
- ソリューションのインポートや列または親テーブルの削除など、メッセージの実行中に Dataverse のソリューションに対する大きな変更を避けます。 予期しない動作が発生する可能性があります。 ただし、データ損失は発生しません。
- メッセージの実行結果としてシステムで行われる更新では、ワークフローとプラグインは実行されません。
- メッセージの実行の結果としてシステムで行われた更新では、列の "最終更新日時" の値は変更されません。 ただし、更新プログラムは、管理者が変換の時刻と列の元の値と変更された値を判断するのに役立ちます。
次のサンプル コードは、メッセージの使用方法を示しています。
/// <summary>
/// Demonstrates use of the ConvertDateAndTimeBehavior message
/// </summary>
/// <param name="service">Authenticated IOrganizationService instance</param>
static void ConvertDateAndTimeBehavior(IOrganizationService service)
{
ConvertDateAndTimeBehaviorRequest request = new()
{
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 Dataverse
AutoConvert = false // Conversion must be done using ConversionRule
};
// Execute the request
var response = (ConvertDateAndTimeBehaviorResponse)service.Execute(request);
Console.WriteLine($"Asynchronous Job ID: {response.JobId}");
}
Web クライアントは 統一インターフェイス とは異なるタイム ゾーン変換を処理します
Web クライアントは 2019 年に廃止 されました。 クライアント スクリプト を後継の 統一インターフェイス に移行する場合は、2 つのクライアントがユーザー ローカル列のタイム ゾーン変換を処理する方法の違いに注意してください。
Web クライアントでは、サーバーはタイム ゾーン変換を処理します。 ユーザーが Web クライアント フォームで 2018-10-15 07:30 を入力すると、クライアント API Xrm.Page.getAttribute(<column name>).getValue() は 2018-10-15 07:30を返します。 この値はサーバーに送信され、値を保存する際にタイムゾーンの調整が行われます。
Unified Client では、クライアントはタイム ゾーン変換を処理します。 タイムゾーン UTC+8 のユーザーが統合クライアント フォームに 2018-10-15 07:30 と入力すると、クライアント API formContext.getAttribute(<column name>).getValue() は調整された値 2018-10-14T23:30:00Z を返します。 サーバーは値をそのまま受け入れ、それ以上タイム ゾーン調整を実行しません。
この違いを考慮するには、次のことができます:
- ユーザーのタイムゾーン オフセットを Component Framework UserSettings.getTimeZoneOffsetMinutes メソッド または Xrm.Utility.getGlobalContext().userSettings.getTimeZoneOffsetMinutes メソッド で取得し、それを考慮するようにスクリプトを修正します。
- 入力された時間が調整されないように、列の動作を
UserLocalからTimeZoneIndependentに変更します。 この変更は、タイム ゾーンが列に適用されない場合にのみ可能です。
参照
日時の列の動作と形式
モデル駆動型アプリの日付けに関する問題のトラブルシューティング
列の概要
ConvertDateAndTimeBehaviorRequest クラス
DateTimeAttributeMetadata クラス
ブログ: 日付と時刻のデータの送信方法は重要ですか?