Date Format Based on User Settings
1. DynaMiX.Backend
The date format lives in the Globalization module. Each DateFormat entity has a FormatString stored in DB via [DynaMiX_Globalization].[DateFormats_GetList].
Entity
DynaMiX.Logic/Modules/Globalisation/Entities/DateFormat.cs
public class DateFormat
{
public int DateFormatId { get; set; }
public string FormatString { get; set; } // e.g. "dd/MM/yyyy"
public string Description { get; set; }
}Fetching Available Date Formats
GlobalizationGateway.cs:237
// Via IGlobalizationGateway
GatewayResult<DateFormatListCarrier> result = GlobalizationGateway.GetDateFormats();
// result.Value.DateFormats is a List<DateFormatCarrier>
// each with: DateFormatId, FormatString, DescriptionApplying It to a Date
ZonedDateTimeCarrier.cs:39
// ZonedDateTimeCarrier wraps a DateTime + TimeZone info.
// Call ToString(formatString) with the user's chosen format:
string userDateFormat = /* DateFormatCarrier.FormatString for the user's DateFormatId */;
string displayDate = myZonedDateTimeCarrier.ToString(userDateFormat);
// -> "15/03/2025 10:45:00 (SAST)"Converting for the Client (Mobile API)
MiXFleet.Mobile.Api/Shared/Carriers/Common/Converter.cs:90
// Extension method pattern used throughout the Mobile API:
DateFormatCarrier carrier = globalizationDateFormatCarrier.ToCarrier();
// carrier.FormatString is what you pass down to the clientNote:
UserProfilestoresLocaleId(aCultureInfoLCID int). TheDateFormatandTimeFormatfields were commented out β the locale drives formatting in most places. The full regional settings bundle isRegionalSettingsCarrier, which includesDateFormats,TimeFormats,NumberFormats,TimeZones, etc.
2. MiX.Config.Frangular.UI (Angular)
The format comes from sessionService.loggedInProfile.locale, provided by @mixtel/dynamixframework (the Fleet Client). It exposes shortDatePattern and shortTimePattern from the userβs profile.
Building the Format String
configgroups.component.ts:3902
let dateFormatString: string = "medium"; // Angular default fallback
if (isDateField &&
this.sessionService.loggedInProfile?.locale?.longDatePattern) {
// Combine date + time pattern from the user's locale.
// Note: replace 'tt' -> 'a' converts the .NET AM/PM token to Angular's equivalent.
dateFormatString = this.sessionService.loggedInProfile.locale.shortDatePattern
+ " "
+ this.sessionService.loggedInProfile.locale.shortTimePattern.replace('tt', 'a')
+ ' (ZZZZ)';
}
// Then assign to the column definition:
this.assetsColumns[i] = {
field: column.field,
isDateField: true,
dateFormatString: dateFormatString,
// ...
};Applying It in the Template
configgroups.component.html:328
<!-- Angular date pipe receives the format string from the column definition -->
{{ dataItem[col?.field] | date:(col?.dateFormatString) }}The IColumn Interface
column.interface.ts
export interface IColumn {
isDateField?: boolean;
dateFormatString?: string; // Angular date pipe format string
// ...
}3. Use Case β Timeline Text Summary (Backend API)
The TimelineTextSummary class is a concrete example of UserProfile.LocaleId driving date formatting end-to-end in the API layer.
Flow
-
Module receives request β
TimelineModuleBase.cs:255constructs aTimelineTextSummary, passingCurrentUserProfile(sourced from the authenticated session viaMobileApiModuleBase.cs:440). -
Locale is resolved β At each text-building method (trip depart, trip halt, event start/end), the locale is looked up via:
TimelineTextSummary.cs:155var selectedLocale = GlobalizationGateway.GetLocaleById(_userProfile.LocaleId).Value; -
DateFormatConverterbuilds aDateTimeFormatInfoβDateFormatConverter.cs:37// Singleton. Caches LocaleEntryCarrier by LocaleId. public string GetRegionalDateFormat(DateTime dat, UserProfile userProfile) { LocaleEntryCarrier locale = UserLocale.GetOrAdd( userProfile.LocaleId, CultureSettings.GetLocalCultures().Find(o => o.Id == userProfile.LocaleId)); var newCulture = new CultureInfo(GetUserProfileLanguage(userProfile.LanguageCode), false); newCulture.DateTimeFormat.ShortDatePattern = locale.ShortDatePattern; newCulture.DateTimeFormat.LongTimePattern = locale.LongTimePattern; // ... all patterns applied from locale return dat.ToString(newCulture.DateTimeFormat); } -
Date field in trip summary is formatted β
TimelineTextSummary.cs:218case ClassType.DateTime: var dateFormat = DateFormatConverter.Instance.GetRegionalFormatForDate( selectedLocale.Id, _userProfile.LanguageCode); tripTextSummary.Value = zonedDateTime.DateTime.ToString( dateFormat.ShortDatePattern + " " + dateFormat.LongTimePattern) + " (" + zonedDateTime.TimeZoneShortName + ")"; break;
Key files
| File | Purpose |
|---|---|
Entities/DynaMiX.Entities/Users/UserProfile.cs:15 | Entity β LocaleId defaults to CultureInfo.CurrentCulture.LCID; DateFormat/TimeFormat fields are commented out |
API/DynaMiX.API/Converters/DateFormatConverter.cs:37 | Singleton converter β maps UserProfile.LocaleId β LocaleEntryCarrier β DateTimeFormatInfo |
API/DynaMiX.API/Converters/TimelineTextSummary.cs:155 | Consumer β calls GetLocaleById(_userProfile.LocaleId) and DateFormatConverter per text block |
API/DynaMiX.API/NancyModules/Timeline/TimelineModuleBase.cs:255 | Entry point β passes CurrentUserProfile into TimelineTextSummary |
Note:
DateFormatConverterusesConcurrentDictionaryto cache locale lookups byLocaleId, so the DB/culture resolution only happens once per locale per app lifetime.
Summary
| Layer | Source | Applied Via |
|---|---|---|
| Backend | UserProfile.LocaleId β GlobalizationGateway.GetLocaleById() β LocaleEntryCarrier | DateFormatConverter.GetRegionalDateFormat() β DateTime.ToString(DateTimeFormatInfo) |
| Frontend | sessionService.loggedInProfile.locale.shortDatePattern + shortTimePattern | Angular date pipe |