0

I have an object of type DateTime like this :

var date = new DateTime(1999,1,18);

then i call ToString method with fa-IR culture info like this :

var strDate = date.ToString("yyyy/MM/dd",CultureInfo.GetCultureInfo("fa-IR"));

i expect strDate to be "1377/10/28" which is equivalent of "1999/1/18" in fa-IR culture . but after calling ToString method i get "1999/1/18" which is not true .

Anyone knows where is the problem and how to solve it?

SoroushNeshat
  • 656
  • 5
  • 11
  • 2
    Your code works fine. I get `1377/10/28` as expected. You need to provide a sample that actually reproduces the error - most likely, the problem is in another part of your code. – Luaan Apr 22 '19 at 06:40
  • 1
    https://dotnetfiddle.net/1GxT0U – TheGeneral Apr 22 '19 at 06:42
  • @Luaan one more question before i provide more details . do you think windows setting might affect the output ? this piece of code works fine in every online c# compiler but doesnt work on my computer . – SoroushNeshat Apr 22 '19 at 06:45
  • It shouldn't depend on Windows settings. However, it might not work on some configurations - maybe it's not supported on Windows XP, or on old versions of .NET framework, on some special localised version of Windows... Try the piece of code in a new, empty C# project, and see if it works or not. – Luaan Apr 22 '19 at 06:50

2 Answers2

1

you need to override culture calendar, and also to receive persian names, you need to override them as well....

It's something like this, more or less:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

namespace Ravis24.Helpers
{
    public class PersianCulture : CultureInfo
    {
        private readonly System.Globalization.Calendar cal;
        private readonly System.Globalization.Calendar[] optionals;

        public PersianCulture()
            : this("fa-IR", true)
        { }

        public PersianCulture(string cultureName, bool useUserOverride)
            : base(cultureName, useUserOverride)
        {
            cal = base.OptionalCalendars[0];
            var optionalCalendars = new List<System.Globalization.Calendar>();
            optionalCalendars.AddRange(base.OptionalCalendars);
            optionalCalendars.Insert(0, new PersianCalendar());
            Type formatType = typeof(DateTimeFormatInfo);
            Type calendarType = typeof(System.Globalization.Calendar);
            PropertyInfo idProperty = calendarType.GetProperty("ID", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo optionalCalendarfield = formatType.GetField("optionalCalendars", BindingFlags.Instance | BindingFlags.NonPublic);
            var newOptionalCalendarIDs = new Int32[optionalCalendars.Count];

            for (int i = 0; i < newOptionalCalendarIDs.Length; i++)
                newOptionalCalendarIDs[i] = (Int32)idProperty.GetValue(optionalCalendars[i], null);

            optionalCalendarfield.SetValue(DateTimeFormat, newOptionalCalendarIDs);

            optionals = optionalCalendars.ToArray();

            cal = optionals[0];

            DateTimeFormat.Calendar = optionals[0];

            DateTimeFormat.MonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            DateTimeFormat.MonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            DateTimeFormat.AbbreviatedMonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            DateTimeFormat.AbbreviatedMonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            DateTimeFormat.AbbreviatedDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
            DateTimeFormat.ShortestDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
            DateTimeFormat.DayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" };
            DateTimeFormat.AMDesignator = "ق.ظ";
            DateTimeFormat.PMDesignator = "ب.ظ";
            DateTimeFormat.ShortDatePattern = "yyyy/MM/dd";
            DateTimeFormat.ShortTimePattern = "HH:mm";
            DateTimeFormat.LongTimePattern = "HH:mm:ss";
            DateTimeFormat.FullDateTimePattern = "yyyy/MM/dd HH:mm:ss";
        }

        public override System.Globalization.Calendar Calendar
        {
            get { return cal; }
        }

        public override System.Globalization.Calendar[] OptionalCalendars
        {
            get { return optionals; }
        }

        public static DateTime PersianToGregorianUS(DateTime faDate)
        {
            return new PersianCalendar().ToDateTime(faDate.Year, faDate.Month, faDate.Day, faDate.Hour, faDate.Minute, faDate.Second, faDate.Millisecond);
        }
    }
}
Hassan Faghihi
  • 1,888
  • 1
  • 37
  • 55
  • thanks for the solution . but it wont solve my problem because our customers are from 5 different countries with 5 different cultures . overriding the calendars would be my last choice . – SoroushNeshat Apr 22 '19 at 07:17
  • We do not actually overriding it in existing class, so we are generating new one, and so: `CultureInfo.GetCultureInfo("fa-IR")` which uses a factory and returns requested culture is different from what we are defined: `PersianCulture`, and it has the benefit of having the correct calendar and the correct month and week naming. most countries uses same language and calendar, but culture mostly relate to how display things and how notation works. that's why it doesn't contain calendar information within itself. – Hassan Faghihi Apr 22 '19 at 07:43
  • BTW, this method is used since long ago, and still many components, and websites are builds upon it. – Hassan Faghihi Apr 22 '19 at 07:44
0

Try this out:

Thread.CurrentThread.CurrentUICulture = new CultureInfo("fa-IR");
var date = new DateTime(1999, 1, 18);
var strDate = date.ToString("yyyy/MM/dd", CultureInfo.GetCultureInfo("fa-IR"));

Console.WriteLine(strDate);
Console.ReadKey();

This gives the output "1377/10/28"

Praneet Nadkar
  • 823
  • 7
  • 16
  • I would suggest have a good look here as well: https://stackoverflow.com/questions/468791/is-there-a-way-of-setting-culture-for-a-whole-application-all-current-threads-a – Praneet Nadkar Apr 22 '19 at 07:10