How to correctly render a ar-SA date and time string

So, I've got a DateTime value, and I need to render it out using the ar-SA culture (using the Gregorian Calendar).

The format I'd like to use is dd-MMM-yyyy HH:mm.

I'm using this currently to format it -

dateTimeValue.ToString("dd-MMM-yyyy HH:mm", culture)

In en-GB, I'd see -

06-Jun-2017 16:49

In ar-SA, when I use the same method, I see -

06-يونيو-2017 16:49

Now, from what I can work out, I think it's the RTL string that's causing the problem, since it's always on the right-hand side.

How do I render out this date correctly in RTL?


Right, after a bit of digging, I've managed to get a solution that works.

Even though my question was originally about ar-SA, it does apply to any right-to-left culture.

I ended up using unicode characters to explicitly state what parts of the string were left-to-right and right-to-left.

So, using the constants -

private const char LeftToRightCharacter = (char)0x200E;
private const char RightToLeftCharacter = (char)0x200F;

I can then build up a string of the date as follows -

if (culture.TextInfo.IsRightToLeft)
{
    return
        LeftToRightCharacter +
        date.ToString("yyyy-", culture) +
        RightToLeftCharacter +
        date.ToString("MMM", culture) +
        LeftToRightCharacter +
        date.ToString("-dd", culture);
}
return date.ToString("dd-MMM-yyyy", culture);

...where culture is a CultureInfo (with the DateTimeFormat.Calendar set to new GregorianCalendar()) and date is a DateTime.

So, for the date 06-Jun-2017, in en-GB I get -

06-Jun-2017

and in ar-SA I get -

2017-‏يونيو‎-06

Now that I've got that as a string, I can add the time on either side (to the left, if the culture is RTL and on the right if the culture is LTR).

It was useful seeing how Unicode deals with these characters, along with the other characters I could have used instead - http://www.unicode.org/reports/tr9/


CultureInfo CurrentCulture = CultureInfo.GetCultureInfo("ar-AE");
string text = DateTime.Now.ToString("yyyy MMMM dd", CurrentCulture);