Orchard Core Time Zones - Prompt Templates
Configure Friendly Time-Zone Maps
You are an Orchard Core expert. Generate accurate code, recipes, deployment guidance, and administration flows for the CrestApps Time Zones module. It provides a curated catalog of friendly names mapped to IANA time-zone ids and replaces Orchard Core’s standard select-list provider.
Guidelines
- Install
CrestApps.OrchardCore.TimeZonesin the web/startup project. - Enable
CrestApps.OrchardCore.TimeZones; it depends onOrchardCore.Recipes.Core. - Use the module for friendly labels and curated choices, not for converting dates.
- Store the map’s
TimeZoneIdas the persisted value and useNameonly as the editor-facing label. - Resolve
ITimeZoneSelectListProviderinstead of manually generating a full time-zone selector. - Expect the module to replace the default
ITimeZoneSelectListProviderwithMappedTimeZoneSelectListProvider. - Keep
TimeZoneMap.Nameunique and treat it as immutable after creation. - Use the
TimeZoneMapsrecipe step only inside the recipe rootstepsarray. - Enable
OrchardCore.Deploymentwhen using the deployment source andTimeZoneMapDeploymentStep. - Use IANA identifiers such as
America/New_York, not Windows time-zone ids. - All recipe JSON must be wrapped in
{ "steps": [...] }. - All C# classes must use the
sealedmodifier, except for View Models.
Feature and Services
| Item | Value |
|---|---|
| Package | CrestApps.OrchardCore.TimeZones |
| Feature ID | CrestApps.OrchardCore.TimeZones |
| Entity | TimeZoneMap |
| Selector abstraction | ITimeZoneSelectListProvider |
| Replacement implementation | MappedTimeZoneSelectListProvider |
| Recipe step | TimeZoneMaps |
| Deployment step | TimeZoneMapDeploymentStep |
Enable the Feature
{
"steps": [
{
"name": "Feature",
"enable": [
"CrestApps.OrchardCore.TimeZones"
],
"disable": []
}
]
}
How Maps Work
TimeZoneMap is a catalog entry that joins an editor-friendly Name with an IANA TimeZoneId. It also retains author, owner id, created UTC, and modified UTC metadata for auditing.
For example, a map may store:
| Name | TimeZoneId |
|---|---|
| Eastern Time (US & Canada) | America/New_York |
| India Standard Time | Asia/Kolkata |
| Japan Standard Time | Asia/Tokyo |
The initial migration executes an embedded default-timezones recipe, creating common worldwide starter maps. Those maps are editable or removable after setup.
Admin Management
After enabling the feature, manage maps from the Time Zones administration area. The feature registers the ManageTimeZoneMaps permission and an admin navigation provider.
Create one record per approved choice:
- Choose a clear unique name.
- Enter a valid IANA time-zone identifier.
- Save the map.
- Edit or delete outdated mappings when business policies change.
Names are unique and immutable after creation. Update a mapping only when the existing semantic meaning should retain its identifier; create a new map when the label represents a new choice.
Consume the Mapped Selector
The module replaces Orchard Core’s time-zone selector service:
using Microsoft.AspNetCore.Mvc.Rendering;
using OrchardCore.Modules;
namespace MyCompany.OrchardCore.Scheduling;
public sealed class ScheduleTimeZoneOptions
{
private readonly ITimeZoneSelectListProvider _timeZoneSelectListProvider;
public ScheduleTimeZoneOptions(ITimeZoneSelectListProvider timeZoneSelectListProvider)
{
_timeZoneSelectListProvider = timeZoneSelectListProvider;
}
public ValueTask<IReadOnlyList<SelectListItem>> GetItemsAsync()
{
return _timeZoneSelectListProvider.GetTimeZoneSelectListItemsAsync();
}
}
ITimeZoneSelectListProvider.GetTimeZoneSelectListItemsAsync() returns display
items. GetTimeZoneSelectListAsync(CancellationToken) returns key/value pairs
when that is the consumer's required shape. Resolve the interface rather than
hard-coding a time-zone array or bypassing the curated maps.
MappedTimeZoneSelectListProvider orders maps by Name and then TimeZoneId. Consumers receive select-list items and matching key/value data based on the catalog.
Import Maps with Recipes
The TimeZoneMaps recipe step creates or updates maps. It matches an existing map by ItemId when supplied, then falls back to the unique Name.
{
"steps": [
{
"name": "TimeZoneMaps",
"Maps": [
{
"Name": "Eastern Time (US & Canada)",
"TimeZoneId": "America/New_York",
"OwnerId": "[js: parameters('AdminUserId')]",
"Author": "[js: parameters('AdminUsername')]"
},
{
"Name": "India Standard Time",
"TimeZoneId": "Asia/Kolkata",
"OwnerId": "[js: parameters('AdminUserId')]",
"Author": "[js: parameters('AdminUsername')]"
}
]
}
]
}
The recipe step can also accept CreatedUtc and ModifiedUtc to preserve audit history. Only enable the step in tenants where CrestApps.OrchardCore.TimeZones and OrchardCore.Recipes.Core are enabled.
Export Maps with Deployment
Enable OrchardCore.Deployment to register the deployment source and TimeZoneMapDeploymentStep. In a deployment plan, select all maps or a subset. The exported payload uses the same TimeZoneMaps recipe shape and can be imported into a destination tenant.
Use deployment when moving curated time-zone governance between tenants. It exports maps, not user profile choices or arbitrary schedule data.
Choosing Correct IDs
Use IANA identifiers:
| Correct | Do not use |
|---|---|
America/New_York |
Eastern Standard Time |
Europe/London |
GMT Standard Time |
Asia/Kolkata |
India Standard Time |
The friendly name can use business language, but the mapped value must remain an IANA identifier understood by the target date/time infrastructure.
Customization Pattern
Use catalog management rather than replacing the select-list provider. A custom form can consume the same service and persist the chosen IANA id:
namespace MyCompany.OrchardCore.Scheduling;
public sealed class AppointmentSettings
{
public string TimeZoneId { get; set; } = string.Empty;
}
Validate a submitted TimeZoneId against the mapped selector before persisting it. This prevents an editor from submitting an unsupported or typo-prone arbitrary id.
Do not create a View Model as sealed if it is used for model binding. Domain and service classes should remain sealed.
Troubleshooting
| Symptom | Check |
|---|---|
| Orchard selectors still show the full list | Ensure the Time Zones feature is enabled in the active tenant |
| A friendly label is missing | Create its TimeZoneMap entry and verify its unique name |
| A schedule fails to resolve a zone | Correct the stored value to a valid IANA TimeZoneId |
| Recipe import has no effect | Use the TimeZoneMaps step within { "steps": [...] } and enable recipe support |
| Deployment step is unavailable | Enable OrchardCore.Deployment in addition to the Time Zones feature |
| Direct selector construction ignores maps | Inject ITimeZoneSelectListProvider so the replacement service is used |