I want to format the time DateTimePicker to 24 hours.
I used the following code and the time is actually changed to 24 hours.
The problem now is that the date format takes an undesirable shape when using an Arabic Region for the device or an English region.
I want the direction of the date to not change no matter how different the region of the device.
I want the direction of the date to be Hours, Minutes and AM/PM as in the picture, regardless of the time zone.
My code:
If Thread.CurrentThread.CurrentCulture.DisplayName.Contains("arab".ToLower) Then
ROSYUPDATE_F.DateTimePicker.Format = System.Windows.Forms.DateTimePickerFormat.Custom
ROSYUPDATE_F.DateTimePicker.CustomFormat = "HH:mm tt"
Else
ROSYUPDATE_F.DateTimePicker.Format = System.Windows.Forms.DateTimePickerFormat.Custom
ROSYUPDATE_F.DateTimePicker.CustomFormat = " tt mm:HH"
End If
Animation that changes the time from the desired format
When you change the Regional settings, Thread.CurrentThread.CurrentCulture
or (CultureInfo.CurrentCulture
) are not automatically updated.
You can call CultureInfo.ClearCachedData() to reset the internal CultureData
stored settings and reload fresh values.
To update your UI when User settings change, you can handle notifications that the System sends when these settings have changed.
A simple way to acknowledge these notifications is to handle the WM_SETTINGCHANGE message that is sent to all top-level Windows when something in the System settings has changed.
These notifications are somewhat generic (read the Docs about it), but you can have a general idea of what has changed inspecting the WParam
and LParam
values.
Override WndProc
in your Form to handle WM_SETTINGCHANGE
messages.
When you get one, verify which settings have changed and act on this information.
In this case, when Regional (User) settings change, WParam
is set to 0
and LParam
points to a string that reads "intl"
.
Then, if the Language is RTL (or a non-specific Arabic language - what you get with CultureInfo.GetCultureInfo("AR")
), set your Custom Format, otherwise you can set the default ShortTimePattern
, or whatever.
(Assume the DateTimePicker control is named DateTimePicker1
)
Private Const WM_SETTINGCHANGE As Integer = &H1A
Protected Overrides Sub WndProc(ByRef m As Message)
Select Case m.Msg
Case WM_SETTINGCHANGE
Dim lparmSetting = Marshal.PtrToStringAuto(m.LParam)
If m.WParam.ToInt32() = 0 AndAlso lparmSetting.Equals("intl") Then
CultureInfo.CurrentCulture.ClearCachedData()
DateTimePicker1.CustomFormat = If(CultureInfo.CurrentCulture.TextInfo.IsRightToLeft,
"tt mm:hh", CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern)
End If
End Select
MyBase.WndProc(m)
End Sub
Secondary:
Since your Custom format is not exactly standard, you may have a different behavior when the Form is first loaded, depending on the current Regional Settings of the machine where your app is run.
You can send a WM_SETTINGCHANGE
message to yourself, with WParam
and LParam
set as described, so you update and format your DateTimePicker automatically on startup.
In Form.Load
(or OnLoad()
or OnShown()
or OnHandleCreated()
), your can add:
Imports System.Runtime.InteropServices
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
SendMessage(Me.Handle, WM_SETTINGCHANGE, IntPtr.Zero, Marshal.StringToHGlobalAuto("intl"))
End Sub
SendMessage declaration:
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Friend Shared Function SendMessage(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
End Function