C# - 如何在不改变 DateTime 格式的情况下改变文化

Posted

技术标签:

【中文标题】C# - 如何在不改变 DateTime 格式的情况下改变文化【英文标题】:C# - How to change culture without changing DateTime format 【发布时间】:2019-08-18 10:02:37 【问题描述】:

我已经在 ASP,net Web Form 中使用 Resx 文件来实现站点中的多语言。 为了更改语言,我应该更改以下方法:

Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentUICulture

似乎在 Microsoft Windows 10 等新操作系统中,更改文化可能会以相同的方式更改 DateTime。 它给我们带来了很多问题 例如:数据库中 DateTime 的保存格式是 Anno Domini,但它通过更改文化而改变,并以其他格式保存在数据库中。 我应该如何在不更改日期格式的情况下更改文化?

谢谢

【问题讨论】:

如果您将数据库中的 DateTimes 保存为格式化字符串,那么您遇到的问题比这个更大。 @iakobski 我真的不想这样做。我想将它们保存为 DataTime。 ;] 您是否将数据库中的 DateTime 保存为字符串?或作为 DateTime 数据类型。如果您是数据类型,文化不会影响 DateTime 值。如果它是一个字符串,你只需在每次保存/写入数据库之前格式化字符串。 这些对您有帮助吗? 【参考方案1】:

我在母版页的 OnLoad 中添加了以下代码,以防止使用其他文化日历

System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat = New CultureInfo("en-GB").DateTimeFormat

【讨论】:

【参考方案2】:

您应该使用CultureInfo 类实现自定义文化,并从默认或自己的文化派生日期时间模式:

public static class PersianDateExtensionMethods

    private static CultureInfo _culture;

    public static CultureInfo GetPersianCulture()
    
        const string cultureName = "fa-IR";

        if (_culture == null)
        
            _culture = new CultureInfo(cultureName);

            DateTimeFormatInfo formatInfo = _culture.DateTimeFormat;

            formatInfo.AbbreviatedDayNames = new[]  "ی", "د", "س", "چ", "پ", "ج", "ش" ;
            formatInfo.DayNames = new[]  "یکشنبه", "دوشنبه", "سه شنبه", "چهار شنبه", "پنجشنبه", "جمعه", "شنبه" ;
            var monthNames = new[]
            
                "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن",
                "اسفند",
                ""
            ;
            formatInfo.AbbreviatedMonthNames = formatInfo.MonthNames = formatInfo.MonthGenitiveNames = formatInfo.AbbreviatedMonthGenitiveNames = monthNames;

            _culture.DateTimeFormat = new CultureInfo("en-US").DateTimeFormat;

            Calendar persianCalendar = new PersianCalendar();

            FieldInfo fieldInfo = _culture.GetType().GetField("calendar", BindingFlags.NonPublic | BindingFlags.Instance);
            if (fieldInfo != null)
                fieldInfo.SetValue(_culture, persianCalendar);

            FieldInfo info = formatInfo.GetType().GetField("calendar", BindingFlags.NonPublic | BindingFlags.Instance);
            if (info != null)
                info.SetValue(formatInfo, persianCalendar);

            _culture.NumberFormat.NumberDecimalSeparator = "/";
            _culture.NumberFormat.DigitSubstitution = DigitShapes.NativeNational;
            _culture.NumberFormat.NumberNegativePattern = 0;
        
        return _culture;
    

正如您在我们的自定义文化的代码 DateTimeFormat 中看到的那样,设置为“en-US”文化的日期时间格式,最后 _culture 变量包含一种新的文化,该文化适用于波斯语,但日期时间格式继承自美国文化.

您需要像这样配置服务以使用您的文化:

CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture =
            PersianDateExtensionMethods.GetPersianCulture();

我不知道根据您的要求更改代码的问题在哪里,但我希望这段代码能给您一个解决问题的想法。

【讨论】:

以上是关于C# - 如何在不改变 DateTime 格式的情况下改变文化的主要内容,如果未能解决你的问题,请参考以下文章

C#如何将DateTime的12小时格式转换为24小时时间格式????

从奇怪的格式解析C#中的DateTime

Nullable-如何在 C# 中的 DateTime 类型中仅比较没有时间的日期?

C#如何将DateTime的12小时格式转换为24小时时间格式????

在 c# 中将时间字符串转换为不同的 DateTime 格式 [关闭]

C# 将 DateTime 转换为 Sql Server 2005 格式