コードを使用して、日付と時刻の列の動作と書式を構成する
世界中にユーザーと事務所がある場合、複数のタイム ゾーンで日付と時刻の値を適切に表現することが重要です。 DateTimeAttributeMetadata
(DateTimeAttributeMetadata エンティティ タイプ または DateTimeAttributeMetadata クラス) は、Microsoft Dataverse 内の DateTime
型の列を定義、管理するために使用されます。 DateTimeBehavior
プロパティ (.NET 用 SDK については、DateTimeBehavior プロパティ を参照) を使用して、日付と時刻の値をタイムゾーン情報付きで格納するか、タイムゾーン情報なしで格納するかを定義し、DateTimeAttributeMetadata.Format プロパティ を使用して、これらの列の表示形式を指定します。
また、 Dataverse のカスタマイズ領域を使用して、日時列の動作と形式を定義します。 詳細情報: 日時の列の動作と形式。
注意
Dataverse のすべての日付と時刻の列は、初期値に 1/1/1753 12:00 AM をサポートします。
Date Only または Date Time フィールドがソリューションにある場合、既存の管理対象フィールドの動作を変更できるのは、発行者のみです。 これらのフィールドを変更するには、日付のみ または 日時 列を追加したソリューションをアップグレードする必要があります。 詳細: ソリューションのアップグレードまたは更新
日時列の動作を指定する
DateTimeBehavior
(DateTimeBehavior 複合タイプ または DateTimeBehavior クラス) を使用して、DateTimeAttributeMetadata entity type.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 = "UserLocal"
を直接指定することによって、 DateTimeBehavior
プロパティの値を設定することもできます。
日付と時刻の列の作成時に動作を指定しなかった場合、既定では 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 操作を使用して日付と時刻の値を送信すると、計算が行われず、原因不明のデータが表示されます。 たとえば、太平洋標準時で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 を送信することもできます。
オフセット計算を含めることを選択した場合、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
Product validtodate
Product closedon
見積もり expireson
見積もり これらの列の動作は
UserLocal
に、DateTimeAttributeMetadata.CanChangeDateTimeBehavior
の管理プロパティはTrue
に設定されていますが、これらの列の動作をDateOnly
のみに変更することができます。 他の動作の移行は使用できません。
列の動作の更新後、変更が有効にするには、カスタマイズを公開する必要があります。 日時列の動作を更新することによって、列の動作の変更 後 に入力または更新されたすべての値が、新しい動作でシステムに格納されるようになります。 これは、データベースにすでに格納されている値には影響を与えず、それらは引き続き UTC 値として保存されます。 ただし、既存の値を SDK を使用して取得したり、UI でそれを表示するときは、既存の値はその列の新しい動作にしたがって表示されます。 たとえば、取引先企業エンティティに関するユーザー定義の列の動作を UserLocal
から DateOnly
に変更し、SDK を使用して既存の取引先企業レコードを取り出した場合、日付と時刻は、 <Date> の後に 12 AM (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 形式であり、前のセクションで説明したとおりに、SDK を使用してまたは UI で取得されたときに、新しい動作にしたがって Dataverse によって表示されます。 動作が UserLocal
から DateOnly
に変更された列については、データベース内の既存の UTC 値を適切な DateOnly
値に変換し、ConvertDateAndTimeBehavior
メッセージを使用してデータの異常を回避することができます。
このメッセージを使用すると、UTC から DateOnly への値の変換に使用するタイム ゾーンを選択するための変換ルール (.NET 用 SDK と連携する場合、ConvertDateAndTimeBehaviorRequest.ConversionRule property を参照してください) を指定できます。 次のいずれかの変換ルールを指定できます。
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 クライアントでは、タイムゾーン変換はクライアント側で行われませんでした。 ユーザーがウェブクライアントのフォームに 2018-10-15 07:30
と入力した場合、クライアント API Xrm.Page.getAttribute(<column name>).getValue()
は 2018-10-15 07:30
を返します。 この値はサーバーに送信され、値を保存する際にタイムゾーンの調整が行われます。
統合クライアントでは、タイムゾーン変換はクライアント側で行われません。 タイムゾーン 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 クラス
ブログ: 日付と時刻のデータの送信方法は重要ですか?
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。