22

我正在寻找一种在没有工作日的情况下获取长日期时间的区域感知方式。竟然有这样的野兽?

下面是我用来获取包括工作日在内的长日期格式的代码:

DateTime time = ...
String formattedDate = time.ToLongDateString();

编辑

我想看到的例子:

  • zh-cn:2009 年 12 月 5 日
  • 从法国到法国:2009 年 12 月 5 日
  • es-es: 05 de diciembre de 2009

ToLongDateString() 返回以下内容:

  • zh-cn:2009 年 12 月 5 日,星期六
  • fr-fr:samedi 2009 年 12 月 5 日
  • es-es: sábado, 05 de diciembre de 2009
4

16 回答 16

11

这似乎奏效了。

  1. 枚举所有有效的日期时间模式: CultureInfo.DateTimeFormat.GetAllDateTimePatterns
  2. 选择最长的模式(大概这是最好的匹配):
    • 是 CultureInfo.DateTimeFormat.LongDatePattern 的子字符串
    • 不包含“ddd”(短日名称)
    • 不包含“dddd”(长日名称)

这似乎提出了我正在寻找的字符串。

请参见下面的代码:

class DateTest
{
    static private string GetDatePatternWithoutWeekday(CultureInfo cultureInfo)
    {
        string[] patterns = cultureInfo e.DateTimeFormat.GetAllDateTimePatterns();

        string longPattern = cultureInfo.DateTimeFormat.LongDatePattern;

        string acceptablePattern = String.Empty;

        foreach (string pattern in patterns)
        {
            if (longPattern.Contains(pattern) && !pattern.Contains("ddd") && !pattern.Contains("dddd"))
            {
                if (pattern.Length > acceptablePattern.Length)
                {
                    acceptablePattern = pattern;
                }
            }
        }

        if (String.IsNullOrEmpty(acceptablePattern))
        {
            return longPattern;
        }
        return acceptablePattern;
    }

    static private void Test(string locale)
    {
        DateTime dateTime = new DateTime(2009, 12, 5);

        Thread.CurrentThread.CurrentCulture  = new CultureInfo(locale);

        string format = GetDatePatternWithoutWeekday(Thread.CurrentThread.CurrentCulture);

        string result = dateTime.ToString(format);

        MessageBox.Show(result);            
    }
}

从技术上讲,如果长格式将当天的名称夹在中间,它可能不会起作用。为此,我应该选择具有最长公共子字符串而不是最长精确匹配的模式。

于 2009-09-08T18:50:39.910 回答
11
String formattedDate = DateTime.Now.Date.ToLongDateString().Replace(DateTime.Now.DayOfWeek.ToString()+ ", ", "")
于 2013-05-31T19:21:05.407 回答
4

实现此目的的一种非常糟糕、可怕的方法是从现有的 LongDatePattern 中删除您不想要的格式说明符:

public static string CorrectedLongDatePattern(CultureInfo cultureInfo)
{
    var info = cultureInfo.DateTimeFormat;

    // This is bad, mmmkay?
    return Regex.Replace(info.LongDatePattern, "dddd,?",String.Empty).Trim();
}
于 2009-09-08T18:43:44.170 回答
4

这是来自 Reza 的改进答案,它在某些本地化中无法正常工作。

string formattedDate = DateTime.Now.ToLongDateString()
   .Replace(DateTimeFormatInfo.CurrentInfo.GetDayName(DateTime.Now.DayOfWeek), "")
   .TrimStart(", ".ToCharArray());
于 2018-10-10T08:59:24.130 回答
3

改进接受的答案,GetAllDateTimePatterns可以采用参数将结果限制为与标准格式字符串相关的模式,例如长日期模式的“D”。

例如,GetAllDateTimePatterns('D')当前正在为 en-US 返回此:

"dddd, MMMM d, yyyy", "MMMM d, yyyy", "dddd, d MMMM, yyyy", "d MMMM, yyyy" 

这对于 zh-HK:

"yyyy'年'M'月'd'日'", "yyyy'年'MM'月'dd'日'", "yyyy年MMMd日", "yyyy年MMMd日, dddd"

假设它们以某种偏好或流行顺序列出,我们可以选择第一个不包含星期几的选项。

这是扩展方法,因此您可以简单地使用myDateTime.ToLongDateStringWithoutDayOfWeek()and myDateTime.ToLongDateTimeStringWithoutDayOfWeek()

public static string ToLongDateStringWithoutDayOfWeek(this DateTime d)
{
    return d.ToString(
               CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns('D')
                   .FirstOrDefault(a => !a.Contains("ddd") && !a.Contains("dddd")) 
               ?? "D");
}

public static string ToLongDateTimeStringWithoutDayOfWeek(this DateTime d, bool includeSeconds = false)
{
    char format = includeSeconds ? 'F' : 'f';
    return d.ToString(
               CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns(format)
                   .FirstOrDefault(a => !a.Contains("ddd") && !a.Contains("dddd")) 
               ?? format.ToString()); 
}
于 2018-08-02T04:45:19.103 回答
2

如果 LongDate 序列也是特定于文化的,那么恐怕你不走运,你必须为此编写实际代码。否则,一组格式化标签就可以解决问题。

恐怕您需要做的是在当地文化中创建一个包含 7 个字符串(每天一个)的数组,然后从您的 LongDate 格式输出中删除这些字符串。然后确保删除所有重复的 / 的 - 和空格。

希望有更好的方法,但我看不到。

于 2009-09-08T16:50:35.160 回答
2

这是一个古老的、古老的主题,但我遇到了它,因为它与我需要解决的用例完美匹配。我最终编写了一段有效的代码,所以我想我会把它包含在那些需要它的人身上。(它有一些额外的技巧,比如默认为当前日期,并允许文化的完整日期字符串,或者删除星期几):

 public string DateString(DateTime? pDt = null, string lang, bool includeDayOfWeek = true)
 {
    if (pDt == null) pDt = DateTime.Now;
    DateTime dt = (DateTime)pDt;

    System.Globalization.CultureInfo culture = null; 
    try {   culture = new System.Globalization.CultureInfo(lang); } 
       catch{ culture = System.Globalization.CultureInfo.InvariantCulture; }

    string ss = dt.ToString("D", culture);
    if (!includeDayOfWeek)
    {
       //  Find day-of-week string, and remove it from the date string
       //  (including any trailing spaces or punctuation)
       string dow = dt.ToString("dddd", culture);
       int len = dow.Length;
       int pos = ss.IndexOf(dow);
       if (pos >= 0)
       {
          while ( ((len + pos) < ss.Length)  &&  ( !Char.IsLetterOrDigit(ss[len+pos])))
             len++;
          ss = ss.Substring(0, pos) + ss.Substring(len+pos, ss.Length - (len+pos));
       }
    }
   return ss;
 }
于 2015-11-30T06:20:29.240 回答
1

我已经扩展了 Bart Calixto 的建议,以解决 dd MMM yyyy 格式问题(在澳大利亚,我们也使用英国日期格式 dd/mm/yy)

我还经常需要在 Aust 和 US 日期格式之间进行转换。

这段代码解决了问题(我的版本是VB)

Public Shared Function ToLongDateWithoutWeekDayString(source As DateTime, cult As System.Globalization.CultureInfo) As String

Return source.ToString("D", cult).Replace(source.DayOfWeek.ToString(), "").Trim(","c, " "c)

End Function

在调用你需要设置文化的函数之前,我是在从http://ipinfo.io获取访问者的国家后这样做的

Select Case Country.country
            Case "AU"
                cult = New CultureInfo("en-AU")
            Case "US"
                cult = New CultureInfo("en-US")
            Case "GB"
                cult = New CultureInfo("en-GB")
        End Select

Dim date1 As New Date(2010, 8, 18)
lblDate.Text = ToLongDateWithoutWeekDayString(date1, cult)

设置 AU 或 GB 文化后结果为 2010 年 8 月 18 日

设置美国文化后结果为 2010 年 8 月 18 日

亚当您同意这解决了您所指的格式问题吗?

感谢 Bart,这是非常好的代码。

不要忘记Dim cult As System.Globalization.CultureInfo在继承 System.Web.UI.Page 之后添加

于 2017-01-05T14:00:56.400 回答
0

为什么不获取 LongDate 并删除工作日出现的第一部分?

DateTime date = Convert.ToDateTime(content["DisplayDate"]); 
  //-->3/15/2016 2:09:13 PM

string newDate = date.ToString("D", new CultureInfo("es-ES")); 
  //--> martes, 15 de marzo de 2016

var index = newDate.IndexOf(",") + 1;
  //--> 7

string finalDate = newDate.Substring(index);
  //--> 15 de marzo de 2016
于 2016-03-16T20:40:52.573 回答
0

旧帖子,但我正在使用这个:

public static string ToLongDateWithoutWeekDayString(this DateTime source)
{
    return source.ToLongDateString()
                 .Replace(source.DayOfWeek.ToString(), "")
                 .Trim(',', ' ');
}
于 2016-03-21T07:18:12.180 回答
0

我的解决方案:

DateTime date = DateTime.Now;
CultureInfo culture = CultureInfo.CurrentCulture;
string dayName = date.ToString("dddd", culture);
string fullDate = date.ToString("f", culture);
string trim = string.Join(" ", fullDate.Replace(dayName, "").TrimStart(',').TrimStart(' ').Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); 

最后一行:

  1. 在开始时删除剩余的逗号
  2. 在开始时删除剩余空间
  3. 从字符串中的任何位置删除剩余的双空格

对每种文化进行了测试

CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
于 2018-03-02T18:09:42.897 回答
0

您可以将标准月/日模式 (m) 与自定义年份 (yyyy) 连接起来:

string formattedDate = date.ToString("M") + ", " + date.ToString("yyyy");

例子:

2020 年 6 月 15 日 (en-US) 2020 年 6 月 15 日
(da-DK) 2020年 6 月 15 日
(id-ID)

于 2020-08-04T18:40:59.570 回答
0

有点搞笑这个问题有多少答案(而且它仍然是一个问题)。不妨用我的解决方案加入派对:

    CultureInfo culture = CultureInfo.CurrentCulture; // or replace with the culture of your choosing

    string pattern = culture.DateTimeFormat.LongDatePattern
        .Replace("dddd, ", "")
        .Replace(",dddd", "");

    return dt.ToString(pattern, culture);

然后,无论一周中的哪一天在其余时间之前或之后,您都涵盖了这两种情况。

于 2021-07-15T13:58:16.150 回答
-1

尝试:

DateTime time = ....
string formmattedDate = time.Day.ToString() + " " + time.ToString("MMMM");
于 2009-09-08T16:48:50.313 回答
-1

有什么问题:

var ci = CultureInfo.CreateSpecificCulture("nl-NL");
var date1 = DateTime.ParseExact(date, "dd MMM yyyy", ci);
于 2013-11-04T13:56:13.757 回答
-1

只需指定格式:

DateTime.ToString("MMMM dd, yyyy");
于 2014-08-22T11:04:06.913 回答