Arabic numbers are not parsed correctly.
You can replace the numeric values with the other Arabic notation (1, 2, 3, ...) and also replace the ص/م
designators, if any, with the AM/PM
alternative form:
Dim nativeDate As String = "١٤٤٢/٠٨/٠٨ ٢:٣٨ ص"
Dim hijriDate = ParseHijriDate(nativeDate, False)
Dim gregorianDate = ParseHijriDate(nativeDate, True)
Which print, respectively:
8/8/1442 2:38:00 AM
3/21/2021 2:38:00 AM
Private Function ParseHijriDate(HijriDate As String, AsGregorianDate As Boolean) As Date
Dim culture = CultureInfo.CreateSpecificCulture("ar-SA")
Dim arSADigitsMap = GetCultureDigitsMap(culture)
For Each map In arSADigitsMap
HijriDate = HijriDate.Replace(map.Key, map.Value)
Next
If AsGregorianDate Then
Return Date.Parse(HijriDate, culture)
Else
Return Date.Parse(HijriDate, CultureInfo.InvariantCulture)
End If
End Function
Private Function GetCultureDigitsMap(culture As CultureInfo) As Dictionary(Of String, String)
Dim digits = culture.NumberFormat.NativeDigits
Dim digitsMap = New Dictionary(Of String, String)()
For n As Integer = 0 To 9
digitsMap.Add(digits(n), n.ToString())
Next
digitsMap.Add(culture.DateTimeFormat.AMDesignator, "AM")
digitsMap.Add(culture.DateTimeFormat.PMDesignator, "PM")
Return digitsMap
End Function
If you want to force that specific format (yyyy/MM/dd H:mm tt
), add the Format to DateTime.ParseExact()
:
Return Date.ParseExact(HijriDate, "yyyy/MM/dd H:mm tt", CultureInfo.InvariantCulture)
Note:
In case the Dictionary used to map the digits fails to achieve the result, you can use a pre-built Dictionary that provides a static representation of the digits in the two forms:
Dim arSAEastWest = New Dictionary(Of String, String)() From {
{"٠", "0"}, {"١", "1"}, {"٢", "2"}, {"٣", "3"}, {"٤", "4"},
{"٥", "5"}, {"٦", "6"}, {"٧", "7"}, {"٨", "8"}, {"٩", "9"},
{"ص", "AM"}, {"م", "PM"}
}