【问题标题】:Does DateTime string contain value- wrong format of ToShortDateString?DateTime 字符串是否包含值错误格式的 ToShortDateString?
【发布时间】:2014-10-02 14:04:18
【问题描述】:

背景:我正在尝试实现搜索功能。我的搜索功能的一部分是能够搜索日期(德语格式)。您应该可以输入“2014”,然后您将获得以 2014 为年份的每个日期,或者以德语格式输入整个日期(21.03.2014)。

很遗憾,我的代码不起作用:

_unitOfWork.StammdatenRepository.Get()
           .Where(s => (s.MyDate.HasValue 
                       && s.MyDate.Value.ToShortDateString().Contains(keyword)));

如果'2014''2012' 等是我的关键字,那么它可以工作。如果我以德语格式输入整个日期,我不会得到任何结果。我认为这是因为 ToShortDateString 方法返回的“错误”格式。

更新 1: 对于迟到的回复/更新,我深表歉意。直到今天才能得到代码。 if/else 构造不起作用,因为我的原始代码要复杂得多(这是实体框架的复杂 WHERE 条件)。用户可以输入一个关键字,我在不同的列中查找该关键字。一栏是“BeginnVos”,我的日期栏:

string keyword = inputModel.Keyword.ToLower();
stammdatenEntityModels =
    _unitOfWork.StammdatenRepository.Get()
                .Where(
                    s =>
                    s.Geloescht == false &&
                    ((s.Auftraggeber != null && s.Auftraggeber.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.SerienNummer.Contains(keyword)) ||
                    (s.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.StammdatenKunde != null && s.StammdatenKunde.Name.ToLower().Contains(keyword)) ||
                    (s.BeginnVos.HasValue && s.BeginnVos.Value.ToShortDateString().Contains(keyword)) ||
                    (s.VosDauer != null && s.VosDauer.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.Geraetewert.HasValue && s.Geraetewert.Value.ToString().Contains(keyword))
                    ))
                .OrderBy(orderBy)
                .Skip(inputModel.EntriesToDisplay*(inputModel.Page - 1))
                .Take(inputModel.EntriesToDisplay)
                .ToList();

我尝试了不同的方法,甚至像

s.BeginnVos.Value.ToString("dd.MM.yyyy").Contains(keyword))

但我仍然没有得到合适的结果(列表为空)。

用户输入“22.02.2013”​​(德语格式),但在我的数据库中,它当然是以 sql 日期格式存储的:2013-02-22 00:00:00.000。是否需要对用户输入进行任何转换?

我的解决方案,感谢 Habibi:

string keyword = inputModel.Keyword.ToLower();
DateTime dateTime = new DateTime();
DateTime.TryParseExact(keyword, "d'.'M'.'yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);

stammdatenEntityModels =
    _unitOfWork.StammdatenRepository.Get()
                .Where(
                    s =>
                    s.Geloescht == false &&
                    ((s.Auftraggeber != null && s.Auftraggeber.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.SerienNummer.Contains(keyword)) ||
                    (s.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.StammdatenKunde != null && s.StammdatenKunde.Name.ToLower().Contains(keyword)) ||
                    (s.BeginnVos.HasValue && s.BeginnVos == dateTime) ||
                    (s.VosDauer != null && s.VosDauer.Bezeichnung.ToLower().Contains(keyword)) ||
                    (s.Geraetewert.HasValue && s.Geraetewert.Value.ToString().Contains(keyword))
                    ))
                .OrderBy(orderBy)
                .Skip(inputModel.EntriesToDisplay*(inputModel.Page - 1))
                .Take(inputModel.EntriesToDisplay)
                .ToList();

【问题讨论】:

  • 如果您输入完整的日期、仅该日期的记录或仅匹配年份的记录,您希望返回什么?
  • 您确定Thread.CurrentThread.CurrentCulture 正在返回de-DE
  • 如果输入完整的日期,只需要返回这个日期。我只想比较日期字符串,如果它包含字符串。我认为某种格式是错误的......
  • 你调试过你的代码吗?您的 DateTime 的 ToShortDateString 的值是多少? keyword 是什么?你能展示一个不起作用的示例值吗?

标签: c# asp.net-mvc linq entity-framework linq-to-sql


【解决方案1】:

我认为使用字符串表示比较日期的逻辑是错误的。相反,您应该将关键字转换为 DateTime 类型的对象,然后比较 DateTime 对象。喜欢:

string keyword = "2014";
DateTime parsedDate;
if (DateTime.TryParseExact(keyword, "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
{
    // only year provided
    //Compare only year part
    unitOfWork.StammdatenRepository.Get()
               .Where(s => (s.MyDate.HasValue
                      && s.MyDate.Value.Year == parsedDate.Year));
}
else if (DateTime.TryParseExact(keyword, "d.M.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
{
    //Complete date provided
    //compare complete date
    unitOfWork.StammdatenRepository.Get()
                .Where(s => (s.MyDate.HasValue
                          && s.MyDate.Value.Date == parsedDate.Date));
}
else
{
    //invalid keyword
}

您当前的逻辑可能遇到的另一个问题是,如果您的 LINQ 查询是针对数据提供者(例如实体框架)执行的,那么您最终可能会遇到不支持 ToShortDateString 的异常。因为 ORM 会将 LINQ 查询转换为底层数据源语言,(如果是 SQL Server,可能是 SQL)

您可以使用多种格式。 (注意dM 格式为d.M.yyyy 的单个d.M.yyyy,对于单/双位数的日/月部分就足够了,如果这不是要求,那么您可以使用dd.MM.yyyy 格式)

【讨论】:

  • 非常感谢。你引导我找到我的解决方案。将我的关键字解析为 DateTime 对我帮助很大!
【解决方案2】:

来自MSDN

ToShortDateString 方法返回的字符串是 文化敏感。它反映了当前定义的模式 文化的 DateTimeFormatInfo 对象。例如,对于 en-US 文化,标准的短日期模式是“M/d/yyyy”;对于 de-DE 文化,它是“dd.MM.yyyy”;对于 ja-JP 文化,它是“yyyy/M/d”。 特定计算机上的特定格式字符串也可以是 定制,使其不同于标准的短日期格式 字符串。

所以如果你想严格使用德语格式的关键字,你可以使用显式格式s.MyDate.Value.ToString("dd.MM.yyyy").Contains(keyword)

【讨论】:

    【解决方案3】:

    您确定您设置了正确的文化吗?

    来自DateTime.ToShortDateString

    ToShortDateString 方法返回的字符串是区分区域性的。它反映了当前区域性的 DateTimeFormatInfo 对象定义的模式。例如,对于 en-US 文化,标准的短日期模式是“M/d/yyyy”;对于 de-DE 文化,它是“dd.MM.yyyy”;对于 ja-JP 文化,它是“yyyy/M/d”。特定计算机上的特定格式字符串也可以自定义,使其不同于标准的短日期格式字符串。

    如果您没有将区域性设置为 de-DEToShortDateString 将返回格式为 en-US 区域设置的日期(即 09/30/2014 而不是 30.09.2014)。

    【讨论】:

      猜你喜欢
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 2018-01-06
      • 1970-01-01
      相关资源
      最近更新 更多