我的字符串包含具有以下格式“YYYYMMDD”的日期。这是理所当然的,没有错误的可能性。
我想从他们那里创建DateTime。
我设法让事情有效,但这些小事似乎很复杂:
-- Only works in base 10 , for positive values
stringToInt :: String -> Int
stringToInt [] = 0
stringToInt (x:xs) = (digitToInt x * 10^length xs ) + (stringToInt xs)
-- Expecting format = "YYYYMMDD"
stringToDateTime :: String -> DateTime
stringToDateTime s = DateTime year month day 0 0 0
where year = stringToInt $ take 4 s
month = stringToInt $ take(6-4) . drop 4 $ s
day = stringToInt $ take(8-6) . drop 6 $ s
date1 = stringToDateTime "20180409"
我尝试了parseDate函数,但无法让它工作,因为我无法找到它所期望的String格式(这里是Data.Dates doc:我们怎么知道预期的格式?)
这就是为什么我最终自己从我的String创建一个DateTime的功能,这样做我必须创建一个从[Char]转换Int的函数,因为我找不到一个已经存在的函数。
答案 0 :(得分:5)
使用dates
包,我认为您需要parseDateFormat
:
> import Data.Dates
> import Data.Dates.Formats (parseDateFormat)
> parseDateFormat "YYYYMMDD" "20180409"
Right 9 April 2018, 0:0:0
如果您确定您的字符串具有正确的日期格式,则可以使用Right
fromRight'
包extra
从> import Data.Either.Extra
> fromRight' $ parseDateFormat "YYYYMMDD" "20180409"
9 April 2018, 0:0:0
中提取结果:
services.AddMvc(options =>
{
options.RespectBrowserAcceptHeader = true;
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
}
答案 1 :(得分:2)
为了“正确”完成这些工作,你应该阅读解析器组合库。使用megaparsec library的一个(非常矫枉过正的)解决方案:
import Text.Megaparsec
import Text.Megaparsec.Char
import Control.Monad
type Parser = Parsec String String
decimalNInt :: Int -> Parser Int
decimalNInt nDigits = read <$> replicateM nDigits digitChar
data DateTime = DateTime Int Int Int Int Int Int deriving (Show)
dateYYYYMMDD :: Parser DateTime
dateYYYYMMDD = DateTime <$>
decimalNInt 4 <*> decimalNInt 2 <*> decimalNInt 2
<*> pure 0 <*> pure 0 <*> pure 0
> runParser dateYYYYMMDD "" "20180409"
Right (DateTime 2018 4 9 0 0 0)
> runParser dateYYYYMMDD "" "2018009"
Left (TrivialError (SourcePos {sourceName = "", sourceLine = Pos 1, sourceColumn = Pos 8} :| []) (Just EndOfInput) (fromList [Label ('d' :| "igit")]))
> runParser dateYYYYMMDD "" "abcdefgh"
Left (TrivialError (SourcePos {sourceName = "", sourceLine = Pos 1, sourceColumn = Pos 1} :| []) (Just (Tokens ('a' :| ""))) (fromList [Label ('d' :| "igit")]))
或许更好理解的monadic符号,解析器看起来如此:
dateYYYYMMDD = do
year <- decimalNInt 4
month <- decimalNInt 2
day <- decimalNInt 2
return $ DateTime year month day 0 0 0
答案 2 :(得分:1)
切片我认为你必须自己做,但是要从字符串中读取整数,你应该使用函数read
,如下所示:
read "1234" :: Int
要使此函数处理任何数据类型,它必须是类Read
的实例。不幸的是,查看文档时,DateTime不是。
答案 3 :(得分:1)
使用parseTimeM
,来自唯一真正认真对待日期和时间的Haskell软件包time。这是一个相当全面的图书馆;它唯一真正缺乏的是自然语言处理和生产。
Data.Time> parseTimeM False defaultTimeLocale "%0Y%m%d" "20180409" :: Maybe Day
Just 2018-04-09
上面链接的文档和formatTime
的文档提供了可用格式说明符的完整列表。
如果您确实需要DateTime
并且无法替代,则可以使用toGregorian
从Day
中提取年,月和日。