【问题标题】:Using DateTime.ParseExact to get only the time (without the day)使用 DateTime.ParseExact 仅获取时间(没有日期)
【发布时间】:2023-03-11 12:58:03
【问题描述】:

当我使用 DateTime.ParseExact 时,我得到了意想不到的结果。 这是我的测试代码:

Dim MinVal As DateTime = #12:00:01 AM#
Dim MaxVal As DateTime = #11:59:59 PM#
Dim TooBig1, Equal1 As Boolean
Dim TooBig2, Equal2 As Boolean

Dim dt1 As DateTime = #12:00:01 AM#
Dim dt2 As DateTime = DateTime.ParseExact("12:00:01 AM", "hh:mm:ss tt", Globalization.DateTimeFormatInfo.InvariantInfo)

TooBig1 = (dt1.CompareTo(MaxVal) > 0)
Equal1 = (dt1.CompareTo(MinVal) = 0)

TooBig2 = (dt2.CompareTo(MaxVal) > 0)
Equal2 = (dt2.CompareTo(MinVal) = 0)

dt1 的结果很好:

  • 它在调试器中显示为 #12:00:01 AM#(没有日期)
  • TooBig1 为假
  • Equal1 为真

但结果对于 dt2 来说是(错误的?)意外:

  • 它在调试器中显示为 #9/30/2011 12:00:01 AM#
  • TooBig2 是真的
  • Equal2 为假

看起来是因为 ParseExact 系统地添加了日期,即使我只在格式中指定了时间。

我的问题是:如何使用 DateTime.ParseExact 读取时间?

【问题讨论】:

    标签: .net vb.net


    【解决方案1】:

    Documentation 状态:

    如果 format 定义了一个没有日期元素的时间并且解析操作成功,则生成的 DateTime 值的日期为DateTime.Now.Date

    如果你想要一个没有日期的时间,你可以使用:

    var parsedDate = DateTime.ParseExact(...);
    var timeOnly = parsedDate - parsedDate.Date;
    

    【讨论】:

    • 这变成了 TimeSpan 对象,而不是 DateTime。您忽略这一重要细节的事实再次表明,使用无类型变量是一种糟糕的做法。
    • @Nyerguds:你说得对,结果是TimeSpan。显然这就是 OP 想要的,或者他很快想出了如何从中创建一个新的DateTime。该代码 sn-p 中没有无类型变量;两者都是强类型的,因为当您第一次尝试将timeOnly 用作DateTime 时,编译器会非常清楚。您的意思是说利用类型推断是一件坏事吗?
    • 是的,“未键入”我的意思是“没有专门在代码中键入”,这确实意味着类型推断。这也是一个完美的例子;从代码中根本看不到 DateTime 减去 DateTime 等于 not DateTime
    【解决方案2】:

    使用dt1.TimeOfDaydt2.TimeOfDay 进行此类比较...从而将白天部分排除在等式之外...

    【讨论】:

      【解决方案3】:

      如果您不指定日期,则显然假定为今天。 (如果您正在编写时间跟踪软件,这并非不合理。)

      如果你只想要时间部分,你可以像你已经在做的那样解析它,然后只获取时间部分:

      ' Existing code:
      Dim dt2 As DateTime = DateTime.ParseExact("12:00:01 AM", "hh:mm:ss tt", _
          Globalization.DateTimeFormatInfo.InvariantInfo)
      ' Now grab just the time:
      Dim ts2 As TimeSpan = dt2.TimeOfDay
      

      这将是 TimeSpan 而不是 DateTime,但如果您实际上需要它作为 DateTime,TimeSpan 更适合仅小时/分钟/秒的东西但不是几天。

      (您也可以首先尝试使用 TimeSpan.ParseExact,但它不是为处理 AM/PM 而构建的,并且会将 12:00:01 解析为 12 小时。所以您可能确实需要 DateTime.ParseExact后跟 .TimeOfDay。)


      如果您确实确实需要将其表示为 DateTime(日期部分为 0001 年 1 月 1 日),您始终可以手动将该 TimeSpan 转换回 DateTime:

      Dim dt3 As New DateTime(1, 1, 1, ts2.Hours, ts2.Minutes, ts2.Seconds, ts2.Milliseconds)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-06
        • 1970-01-01
        • 2015-06-12
        • 2021-02-02
        • 2010-10-04
        • 2017-01-17
        • 1970-01-01
        相关资源
        最近更新 更多