首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从[Char]中提取YYYYMMDD并创建DateTime值

从[Char]中提取YYYYMMDD并创建DateTime值
EN

Stack Overflow用户
提问于 2018-04-09 09:19:38
回答 4查看 180关注 0票数 1

我的字符串包含以下格式"YYYYMMDD“的日期。这是理所当然的,不可能出现错误。

我想从它们创建DateTime。

我设法找到了一些有用的东西,但对于这么小的事情来说,这似乎很复杂:

代码语言:javascript
运行
复制
-- 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函数,但是无法让它工作,因为我找不到它所期望的字符串格式(这里是Data.Dates文档:我们如何知道预期的格式?)

这就是为什么我最终要自己从字符串中创建一个DateTime的函数,为此我必须创建一个函数,用于从Char转换Int,因为我找不到一个已经存在的函数。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-04-09 13:04:50

使用dates包,我认为您需要parseDateFormat

代码语言:javascript
运行
复制
> import Data.Dates
> import Data.Dates.Formats (parseDateFormat)
> parseDateFormat "YYYYMMDD" "20180409"
Right 9 April 2018, 0:0:0

如果您确信您的字符串具有正确的日期格式,则可以使用RightfromRight' of extra包提取结果:

代码语言:javascript
运行
复制
> import Data.Either.Extra
> fromRight' $ parseDateFormat "YYYYMMDD" "20180409"
9 April 2018, 0:0:0
票数 5
EN

Stack Overflow用户

发布于 2018-04-09 09:48:46

为了“正确”地做这些事情,您应该阅读解析器组合器库。使用兆赫秒图书馆的(非常过分的)解决方案

代码语言:javascript
运行
复制
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
代码语言:javascript
运行
复制
> 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")]))

在可能更容易理解的一元表示法中,解析器将这样看:

代码语言:javascript
运行
复制
dateYYYYMMDD = do
    year <- decimalNInt 4
    month <- decimalNInt 2
    day <- decimalNInt 2
    return $ DateTime year month day 0 0 0
票数 2
EN

Stack Overflow用户

发布于 2018-04-09 09:40:01

我认为您必须自己进行切片,但是要从字符串中读取整数,您应该使用函数read,如下所示:

代码语言:javascript
运行
复制
read "1234" :: Int

要使此函数在任何数据类型上工作,它必须是类Read的实例。不幸的是,从文档来看,DateTime不是。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49729524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档