Skip to content

Commit 53dc33e

Browse files
authored
Merge pull request #754 from microsoft/claude-sample-upgrade
Add modern .NET 6+ RetrieveTimeZone sample
2 parents f122297 + 6c5c541 commit 53dc33e

File tree

5 files changed

+431
-0
lines changed

5 files changed

+431
-0
lines changed
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
using System;
2+
using Microsoft.Crm.Sdk.Messages;
3+
using Microsoft.Extensions.Configuration;
4+
using Microsoft.PowerPlatform.Dataverse.Client;
5+
using Microsoft.Xrm.Sdk;
6+
using Microsoft.Xrm.Sdk.Messages;
7+
using Microsoft.Xrm.Sdk.Query;
8+
9+
namespace PowerPlatform_Dataverse_CodeSamples
10+
{
11+
/// <summary>
12+
/// Demonstrates how to retrieve time zone information from Dataverse.
13+
/// </summary>
14+
/// <remarks>
15+
/// This sample shows various operations for working with time zones:
16+
/// - Retrieving current user's time zone settings
17+
/// - Getting all time zones for a locale
18+
/// - Finding time zones by name and locale
19+
/// - Retrieving time zones by ID
20+
/// - Converting between UTC and local time
21+
///
22+
/// Set the appropriate Url and Username values for your test
23+
/// environment in the appsettings.json file before running this program.
24+
/// </remarks>
25+
/// <see cref="https://learn.microsoft.com/power-apps/developer/data-platform/xrm-tooling/use-connection-strings-xrm-tooling-connect#connection-string-parameters"/>
26+
/// <permission cref="https://github.com/microsoft/PowerApps-Samples/blob/master/LICENSE"/>
27+
class Program
28+
{
29+
private static string _timeZoneName = "Central Standard Time";
30+
private static Guid _timeZoneId = new Guid("42B2880D-BED5-4AA3-BD69-418052D38B7E");
31+
private static int? _localeId;
32+
private static int? _timeZoneCode;
33+
34+
#region Sample demonstration methods
35+
36+
/// <summary>
37+
/// Retrieves the current user's time zone code and locale ID
38+
/// </summary>
39+
private static void RetrieveCurrentUsersSettings(ServiceClient serviceClient)
40+
{
41+
Console.WriteLine("--- Retrieving Current User Settings ---");
42+
43+
var currentUserSettings = serviceClient.RetrieveMultiple(
44+
new QueryExpression("usersettings")
45+
{
46+
ColumnSet = new ColumnSet("localeid", "timezonecode"),
47+
Criteria = new FilterExpression
48+
{
49+
Conditions =
50+
{
51+
new ConditionExpression("systemuserid", ConditionOperator.EqualUserId)
52+
}
53+
}
54+
}).Entities[0];
55+
56+
_localeId = currentUserSettings.GetAttributeValue<int>("localeid");
57+
_timeZoneCode = currentUserSettings.GetAttributeValue<int>("timezonecode");
58+
59+
Console.WriteLine($"Current user's locale ID: {_localeId}");
60+
Console.WriteLine($"Current user's time zone code: {_timeZoneCode}");
61+
Console.WriteLine();
62+
}
63+
64+
/// <summary>
65+
/// Uses the current locale ID to retrieve all the time zones
66+
/// </summary>
67+
private static void RetrieveAllTimeZonesForLocale(ServiceClient serviceClient)
68+
{
69+
if (!_localeId.HasValue)
70+
{
71+
Console.WriteLine("Locale ID is not set. Skipping RetrieveAllTimeZonesForLocale.");
72+
return;
73+
}
74+
75+
Console.WriteLine("--- Retrieving All Time Zones for Locale ---");
76+
Console.WriteLine($"Retrieving time zones for locale ID: {_localeId.Value}");
77+
78+
var response = (GetAllTimeZonesWithDisplayNameResponse)serviceClient.Execute(
79+
new GetAllTimeZonesWithDisplayNameRequest
80+
{
81+
LocaleId = _localeId.Value,
82+
});
83+
84+
Console.WriteLine($"Found {response.EntityCollection.Entities.Count} time zones.");
85+
86+
// Display first 5 time zones as examples
87+
int displayCount = Math.Min(5, response.EntityCollection.Entities.Count);
88+
for (int i = 0; i < displayCount; i++)
89+
{
90+
var timeZone = response.EntityCollection.Entities[i];
91+
string displayName = timeZone.GetAttributeValue<string>("userinterfacename");
92+
Console.WriteLine($" - {displayName}");
93+
}
94+
95+
if (response.EntityCollection.Entities.Count > 5)
96+
{
97+
Console.WriteLine($" ... and {response.EntityCollection.Entities.Count - 5} more");
98+
}
99+
Console.WriteLine();
100+
}
101+
102+
/// <summary>
103+
/// Retrieves a time zone by the name and the locale ID
104+
/// </summary>
105+
private static void GetTimeZoneCodeByLocaleAndName(ServiceClient serviceClient)
106+
{
107+
if (string.IsNullOrWhiteSpace(_timeZoneName) || !_localeId.HasValue)
108+
{
109+
Console.WriteLine("Time zone name or locale ID is not set. Skipping GetTimeZoneCodeByLocaleAndName.");
110+
return;
111+
}
112+
113+
Console.WriteLine("--- Retrieving Time Zone by Name and Locale ---");
114+
115+
var request = new GetTimeZoneCodeByLocalizedNameRequest
116+
{
117+
LocaleId = _localeId.Value,
118+
LocalizedStandardName = _timeZoneName
119+
};
120+
121+
var response = (GetTimeZoneCodeByLocalizedNameResponse)serviceClient.Execute(request);
122+
123+
Console.WriteLine($"Time zone code: {response.TimeZoneCode}");
124+
Console.WriteLine($"Locale ID: {_localeId.Value}");
125+
Console.WriteLine($"Time zone name: {_timeZoneName}");
126+
Console.WriteLine();
127+
}
128+
129+
/// <summary>
130+
/// Retrieve time zone by ID
131+
/// </summary>
132+
private static void RetrieveTimeZoneById(ServiceClient serviceClient)
133+
{
134+
Console.WriteLine("--- Retrieving Time Zone by ID ---");
135+
136+
var request = new RetrieveRequest
137+
{
138+
Target = new EntityReference("timezonedefinition", _timeZoneId),
139+
ColumnSet = new ColumnSet("standardname")
140+
};
141+
142+
var response = (RetrieveResponse)serviceClient.Execute(request);
143+
string standardName = response.Entity.GetAttributeValue<string>("standardname");
144+
145+
Console.WriteLine($"Time zone ID: {_timeZoneId}");
146+
Console.WriteLine($"Standard name: {standardName}");
147+
Console.WriteLine();
148+
}
149+
150+
/// <summary>
151+
/// Retrieve time zones with time zone code less than 50.
152+
/// </summary>
153+
private static void RetrieveTimeZonesLessThan50(ServiceClient serviceClient)
154+
{
155+
Console.WriteLine("--- Retrieving Time Zones with Code < 50 ---");
156+
157+
var request = new RetrieveMultipleRequest
158+
{
159+
Query = new QueryExpression("timezonedefinition")
160+
{
161+
ColumnSet = new ColumnSet("timezonecode", "standardname"),
162+
Criteria = new FilterExpression
163+
{
164+
Conditions =
165+
{
166+
new ConditionExpression("timezonecode",
167+
ConditionOperator.LessThan, 50)
168+
}
169+
}
170+
}
171+
};
172+
173+
var response = (RetrieveMultipleResponse)serviceClient.Execute(request);
174+
175+
Console.WriteLine($"Found {response.EntityCollection.Entities.Count} time zones with code < 50:");
176+
177+
foreach (var entity in response.EntityCollection.Entities)
178+
{
179+
int? timeZoneCode = entity.GetAttributeValue<int?>("timezonecode");
180+
string standardName = entity.GetAttributeValue<string>("standardname");
181+
182+
Console.WriteLine($" - {standardName} (Code: {timeZoneCode?.ToString() ?? "null"})");
183+
}
184+
Console.WriteLine();
185+
}
186+
187+
/// <summary>
188+
/// Retrieve the local time from the UTC time.
189+
/// </summary>
190+
private static void RetrieveLocalTimeFromUTCTime(ServiceClient serviceClient, DateTime utcTime)
191+
{
192+
if (!_timeZoneCode.HasValue)
193+
{
194+
Console.WriteLine("Time zone code is not set. Skipping RetrieveLocalTimeFromUTCTime.");
195+
return;
196+
}
197+
198+
Console.WriteLine("--- Converting UTC Time to Local Time ---");
199+
200+
var request = new LocalTimeFromUtcTimeRequest
201+
{
202+
TimeZoneCode = _timeZoneCode.Value,
203+
UtcTime = utcTime.ToUniversalTime()
204+
};
205+
206+
var response = (LocalTimeFromUtcTimeResponse)serviceClient.Execute(request);
207+
208+
Console.WriteLine($"UTC time: {utcTime:yyyy-MM-dd HH:mm:ss}");
209+
Console.WriteLine($"Local time: {response.LocalTime:yyyy-MM-dd HH:mm:ss}");
210+
Console.WriteLine($"Time zone code: {_timeZoneCode.Value}");
211+
Console.WriteLine();
212+
}
213+
214+
/// <summary>
215+
/// Retrieves the UTC time from the local time
216+
/// </summary>
217+
private static void RetrieveUTCTimeFromLocalTime(ServiceClient serviceClient, DateTime localTime)
218+
{
219+
if (!_timeZoneCode.HasValue)
220+
{
221+
Console.WriteLine("Time zone code is not set. Skipping RetrieveUTCTimeFromLocalTime.");
222+
return;
223+
}
224+
225+
Console.WriteLine("--- Converting Local Time to UTC Time ---");
226+
227+
var request = new UtcTimeFromLocalTimeRequest
228+
{
229+
TimeZoneCode = _timeZoneCode.Value,
230+
LocalTime = localTime
231+
};
232+
233+
var response = (UtcTimeFromLocalTimeResponse)serviceClient.Execute(request);
234+
235+
Console.WriteLine($"Local time: {localTime:yyyy-MM-dd HH:mm:ss}");
236+
Console.WriteLine($"UTC time: {response.UtcTime:yyyy-MM-dd HH:mm:ss}");
237+
Console.WriteLine($"Time zone code: {_timeZoneCode.Value}");
238+
Console.WriteLine();
239+
}
240+
241+
#endregion
242+
243+
#region Application setup and Main method
244+
245+
/// <summary>
246+
/// Contains the application's configuration settings.
247+
/// </summary>
248+
IConfiguration Configuration { get; }
249+
250+
/// <summary>
251+
/// Constructor. Loads the application configuration settings from a JSON file.
252+
/// </summary>
253+
Program()
254+
{
255+
// Get the path to the appsettings file. If the environment variable is set,
256+
// use that file path. Otherwise, use the runtime folder's settings file.
257+
string? path = Environment.GetEnvironmentVariable("DATAVERSE_APPSETTINGS");
258+
if (path == null) path = "appsettings.json";
259+
260+
// Load the app's configuration settings from the JSON file.
261+
Configuration = new ConfigurationBuilder()
262+
.AddJsonFile(path, optional: false, reloadOnChange: true)
263+
.Build();
264+
}
265+
266+
static void Main(string[] args)
267+
{
268+
Program app = new();
269+
270+
// Create a Dataverse service client using the default connection string.
271+
ServiceClient serviceClient =
272+
new(app.Configuration.GetConnectionString("default"));
273+
274+
if (!serviceClient.IsReady)
275+
{
276+
Console.WriteLine("Failed to connect to Dataverse.");
277+
Console.WriteLine("Error: {0}", serviceClient.LastError);
278+
return;
279+
}
280+
281+
Console.WriteLine("Connected to Dataverse.");
282+
Console.WriteLine();
283+
284+
try
285+
{
286+
// Run all time zone demonstrations
287+
RetrieveCurrentUsersSettings(serviceClient);
288+
RetrieveAllTimeZonesForLocale(serviceClient);
289+
GetTimeZoneCodeByLocaleAndName(serviceClient);
290+
RetrieveTimeZoneById(serviceClient);
291+
RetrieveTimeZonesLessThan50(serviceClient);
292+
RetrieveLocalTimeFromUTCTime(serviceClient, new DateTime(1981, 6, 6, 9, 5, 0));
293+
RetrieveUTCTimeFromLocalTime(serviceClient, new DateTime(2012, 1, 1, 0, 0, 0));
294+
}
295+
catch (Exception ex)
296+
{
297+
Console.WriteLine("An error occurred:");
298+
Console.WriteLine(ex.Message);
299+
}
300+
finally
301+
{
302+
// Pause program execution before resource cleanup.
303+
Console.WriteLine();
304+
Console.WriteLine("Press any key to exit.");
305+
Console.ReadKey();
306+
serviceClient.Dispose();
307+
}
308+
}
309+
310+
#endregion
311+
}
312+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Retrieve time zone information
2+
3+
This sample shows how to retrieve time zone information using the modern .NET 6+ SDK.
4+
5+
## How to run this sample
6+
7+
1. Update the connection string in `appsettings.json` in the parent directory with your Dataverse environment URL and credentials.
8+
9+
2. Build and run the sample:
10+
```bash
11+
dotnet build
12+
dotnet run
13+
```
14+
15+
## What this sample does
16+
17+
This sample demonstrates various time zone operations in Dataverse:
18+
19+
- **RetrieveCurrentUsersSettings**: Retrieves the current user's time zone code and locale ID
20+
- **RetrieveAllTimeZonesForLocale**: Uses the current locale ID to retrieve all available time zones
21+
- **GetTimeZoneCodeByLocaleAndName**: Retrieves a time zone by name and locale ID
22+
- **RetrieveTimeZoneById**: Retrieves a specific time zone by its unique identifier
23+
- **RetrieveTimeZonesLessThan50**: Retrieves time zones with a time zone code less than 50
24+
- **RetrieveLocalTimeFromUTCTime**: Converts UTC time to local time for the user's time zone
25+
- **RetrieveUTCTimeFromLocalTime**: Converts local time to UTC time
26+
27+
## How this sample works
28+
29+
The sample connects to Dataverse using the `ServiceClient` class and executes various message requests to work with time zone information:
30+
31+
1. First, it retrieves the current user's time zone settings (locale ID and time zone code)
32+
2. It demonstrates retrieving all time zones for the user's locale
33+
3. It shows how to find a specific time zone by name ("Central Standard Time")
34+
4. It retrieves a time zone by its GUID
35+
5. It queries for time zones with specific criteria (code < 50)
36+
6. It demonstrates time conversions between UTC and local time
37+
38+
## Key APIs Used
39+
40+
- `GetAllTimeZonesWithDisplayNameRequest` / `GetAllTimeZonesWithDisplayNameResponse`
41+
- `GetTimeZoneCodeByLocalizedNameRequest` / `GetTimeZoneCodeByLocalizedNameResponse`
42+
- `LocalTimeFromUtcTimeRequest` / `LocalTimeFromUtcTimeResponse`
43+
- `UtcTimeFromLocalTimeRequest` / `UtcTimeFromLocalTimeResponse`
44+
- `QueryExpression` with `FilterExpression` and `ConditionExpression`
45+
46+
## Configuration
47+
48+
The sample uses `appsettings.json` for configuration. Example:
49+
50+
```json
51+
{
52+
"ConnectionStrings": {
53+
"default": "AuthType=OAuth;Url=https://myorg.crm.dynamics.com;Username=someone@myorg.onmicrosoft.com;RedirectUri=http://localhost;AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;LoginPrompt=Auto"
54+
}
55+
}
56+
```
57+
58+
## More information
59+
60+
- [Time zone entities](https://learn.microsoft.com/power-apps/developer/data-platform/time-zone-entities)
61+
- [ServiceClient class](https://learn.microsoft.com/dotnet/api/microsoft.powerplatform.dataverse.client.serviceclient)
62+
- [Use messages with the SDK for .NET](https://learn.microsoft.com/power-apps/developer/data-platform/org-service/use-messages)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<RootNamespace>PowerPlatform_Dataverse_CodeSamples</RootNamespace>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<Content Include="..\appsettings.json" Link="appsettings.json">
13+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
14+
</Content>
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
19+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
20+
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client" Version="0.6.6" />
21+
</ItemGroup>
22+
23+
</Project>

0 commit comments

Comments
 (0)