You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法用>=比较parseTimeM函数返回的日期?

问题根源:你在比较字符串,而非日期类型!

首先可以明确:parseTimeM函数完全可以处理过去和未来的日期,你的问题和这个函数无关——核心错误是你在代码里错误地比较了字符串,而不是解析后的Day类型值。

为什么>=比较不生效?

让我们拆解你的代码逻辑:

  • date是用户输入的原始字符串(比如"2018-05-31")
  • forecastDay是parseTimeM解析后的Maybe Day,当输入合法时,它的值是Just 2018-05-31(这里的2018-05-31是Day类型)
  • currentTime是show forecastDay的结果,也就是字符串"Just \"2018-05-31\""

你写的条件date >= currentTime是在做字符串字典序比较:

  • 字符串"2018-05-31"的第一个字符是'2'(ASCII码50)
  • 字符串"Just \"2018-05-31\""的第一个字符是'J'(ASCII码74)
  • 因为50 < 74,所以"2018-05-31" >= "Just..."的结果是False,触发了Left InvalidDate

而当你改成<=时,"2018-05-31" <= "Just..."的结果是True,所以进入Right分支,正常返回结果——这完全是字符串比较的特性,和日期逻辑无关。

修正后的代码示例

假设你的真实需求是:解析用户输入的日期,如果解析成功,判断该日期是否大于等于当前日期(你导入了getCurrentTime但没用到,猜测这是你的意图),代码应该这么写:

import Data.Text (pack)
import Data.Time (Day, UTCTime, getCurrentTime, utctDay)
import Data.Time.Format (parseTimeM, defaultTimeLocale)
import Data.Time.Calendar (Day)

-- 假设UserError和Date是你定义的类型
data UserError = InvalidDate deriving (Show)
type Date = Data.Text.Text

getDateFromUser :: IO (Either UserError Date)
getDateFromUser = do
  putStrLn "请输入日期,格式为YYYY-MM-DD:"
  dateStr <- getLine
  case parseTimeM True defaultTimeLocale "%Y-%m-%d" dateStr :: Maybe Day of
    Nothing -> return $ Left InvalidDate  -- 解析失败返回错误
    Just inputDay -> do
      currentUTCTime <- getCurrentTime
      let currentDay = utctDay currentUTCTime  -- 获取当前日期的Day类型
      if inputDay >= currentDay
        then return $ Right $ pack dateStr
        else return $ Left InvalidDate

关于parseTimeM的能力

parseTimeM完全支持解析任何合法的YYYY-MM-DD格式日期,不管是过去(比如2018-05-30)还是未来(比如2030-12-31)的日期,只要字符串格式正确,就能得到对应的Maybe Day值。

内容的提问来源于stack exchange,提问作者Ashot Bes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:53:53