我一直在使用Haskell的Date.Time模块来解析像12-4-1999或1-31-1999这样的日期。我试过:
12-4-1999
1-31-1999
parseDay :: String -> Day parseDay s = readTime defaultTimeLocale "%m%d%Y" s
我想它希望我的月份和天数正好是两位数,而不是1或2...做这件事的正确方法是什么?另外,我想以这种格式打印出我的一天:12/4/1999的Haskell方法是什么?谢谢你的帮助
12/4/1999
7nbnzgx91#
您可以使用Data.Time.Format中的函数读取日期。我在下面包含了一个简单的程序,它以一种格式读入日期,并以两种不同的格式将该日期写回。若要读取个位数的月份或天数,请在%和格式说明符之间放置一个连字符(-)。换句话说,要解析格式为9-9-2012的日期,则在%和格式字符之间包含一个连字符。因此,要解析“9-9-2012”,您需要格式字符串“%-d-%-m-%Y”。注意:考虑到Haskell包的发展速度,这个答案有点过时了。也许是时候寻找更好的解决方案了。我不再写Haskell了,所以如果其他人创建了另一个答案就好了,因为这个问题在Google结果中排名很高。
Data.Time.Format
自2017年7月起,建议您使用parseTimeOrError。代码变为:
import Data.Time main = do let dateString = "26 Jan 2012 10:54 AM" let timeFromString = parseTimeOrError True defaultTimeLocale "%d %b %Y %l:%M %p" dateString :: UTCTime -- Format YYYY/MM/DD HH:MM print $ formatTime defaultTimeLocale "%Y/%m/%d %H:%M" timeFromString -- Format MM/DD/YYYY hh:MM AM/PM print $ formatTime defaultTimeLocale "%m/%d/%Y %I:%M %p" timeFromString -- now for a string with single digit months and days: let dateString = "9-8-2012 10:54 AM" let timeFromString = parseTimeOrError True defaultTimeLocale "%-d-%-m-%Y %l:%M %p" dateString :: UTCTime -- Format YYYY/MM/DD HH:MM print $ formatTime defaultTimeLocale "%Y/%m/%d %H:%M" timeFromString
.cabal文件中的版本:build-depends:base >=4.9 && <4.10,time >= 1.6.0.1
截至2014年8月,区域设置最好从System.Locale包而不是Haskell 1998 Locale包获得。考虑到这一点,上面的示例代码现在如下:
System.Locale
Locale
import System.Locale import Data.Time import Data.Time.Format main = do let dateString = "26 Jan 2012 10:54 AM" let timeFromString = readTime defaultTimeLocale "%d %b %Y %l:%M %p" dateString :: UTCTime -- Format YYYY/MM/DD HH:MM print $ formatTime defaultTimeLocale "%Y/%m/%d %H:%M" timeFromString -- Format MM/DD/YYYY hh:MM AM/PM print $ formatTime defaultTimeLocale "%m/%d/%Y %I:%M %p" timeFromString -- now for a string with single digit months and days: let dateString = "9-8-2012 10:54 AM" let timeFromString = readTime defaultTimeLocale "%-d-%-m-%Y %l:%M %p" dateString :: UTCTime -- Format YYYY/MM/DD HH:MM print $ formatTime defaultTimeLocale "%Y/%m/%d %H:%M" timeFromString
输出现在看起来像这样:
"2012/01/26 10:54" "01/26/2012 10:54 AM" "2012/08/09 10:54"
原文,2012年1月答复:
import Locale import Data.Time import Data.Time.Format main = do let dateString = "26 Jan 2012 10:54 AM" let timeFromString = readTime defaultTimeLocale "%d %b %Y %l:%M %p" dateString :: UTCTime -- Format YYYY/MM/DD HH:MM print $ formatTime defaultTimeLocale "%Y/%m/%d %H:%M" timeFromString -- Format MM/DD/YYYY hh:MM AM/PM print $ formatTime defaultTimeLocale "%m/%d/%Y %I:%M %p" timeFromString
输出如下所示:
"2012/01/26 10:54" "01/26/2012 10:54 AM"
Data.Time.Format可从time封装中获得。如果你需要解析一位数的月份或天数,换句话说,日期如9-9-2012,那么在%和格式字符之间包含一个连字符。因此,要解析“9-9-2012”,您需要格式字符串“%-d-%-m-%Y”。
time
6ju8rftf2#
使用%-d和%-m而不是%d和%m表示可以使用个位数的日/月,即
parseDay :: String -> Day parseDay s = readTime defaultTimeLocale "%-m%-d%Y" s
这可能是sclv的意思,但他的评论对我来说有点太神秘了。
zphenhs43#
从最近开始,我建议使用strptime包来满足所有日期/时间解析需求。
zhte4eai4#
下面是一些旧代码,其中包含两种类型的自制日期,只有YMD的日期,没有时间或时区等。它展示了如何使用readDec将字符串解析为日期。参见parseDate函数。使用readDec,read 数字,前导空格(因为filter)或前导零无关紧要,解析在第一个非数字处停止。然后使用tail(跳过非数字)来获取日期的下一个数字字段。它展示了几种格式化输出的方法,但最灵活的方法是使用Text.printf。参见instance Show LtDate。有了 printf,一切皆有可能!
readDec
parseDate
filter
tail
Text.printf
instance Show LtDate
import Char import Numeric import Data.Time.Calendar import Data.Time.Clock import Text.Printf -- ================================================================ -- LtDate -- ================================================================ type Date=(Int,Int,Int) data LtDate = LtDate { ltYear :: Int, ltMonth:: Int, ltDay :: Int } instance Show LtDate where show d = printf "%4d-%02d-%02d" (ltYear d) (ltMonth d) (ltDay d) toLtDate :: Date -> LtDate toLtDate (y,m,d)= LtDate y m d -- ============================================================= -- Date -- ============================================================= -- | Parse a String mm/dd/yy into tuple (y,m,d) -- accepted formats -- -- @ -- 12\/01\/2004 -- 12\/ 1\' 4 -- 12-01-99 -- @ parseDate :: String -> Date parseDate s = (y,m,d) where [(m,rest) ] = readDec (filter (not . isSpace) s) [(d,rest1)] = readDec (tail rest) [(y, _) ] = parseDate' rest1 -- | parse the various year formats used by Quicken dates parseDate':: String -> [(Int,String)] parseDate' (y:ys) = let [(iy,rest)] = readDec ys year=case y of '\'' -> iy + 2000 _ -> if iy < 1900 then iy + 1900 else iy in [(year,rest)] -- | Note some functions sort by this format -- | So be careful when changing it. showDate::(Int, Int, Int) -> String showDate (y,m,d)= yy ++ '-':mm ++ '-':dd where dd=zpad (show d) mm = zpad (show m) yy = show y zpad ds@(_:ds') | ds'==[] = '0':ds | otherwise = ds -- | from LtDate to Date fromLtDate :: LtDate -> Date fromLtDate lt = (ltYear lt, ltMonth lt, ltDay lt)
一旦你有了(Y,M,D),就很容易转换成Haskell库类型来进行数据操作。使用完HS库后,可以使用Text.printf化日期以进行显示。
4条答案
按热度按时间7nbnzgx91#
您可以使用
Data.Time.Format
中的函数读取日期。我在下面包含了一个简单的程序,它以一种格式读入日期,并以两种不同的格式将该日期写回。若要读取个位数的月份或天数,请在%和格式说明符之间放置一个连字符(-)。换句话说,要解析格式为9-9-2012的日期,则在%和格式字符之间包含一个连字符。因此,要解析“9-9-2012”,您需要格式字符串“%-d-%-m-%Y”。注意:考虑到Haskell包的发展速度,这个答案有点过时了。也许是时候寻找更好的解决方案了。我不再写Haskell了,所以如果其他人创建了另一个答案就好了,因为这个问题在Google结果中排名很高。
自2017年7月起,建议您使用parseTimeOrError。代码变为:
.cabal文件中的版本:build-depends:base >=4.9 && <4.10,time >= 1.6.0.1
截至2014年8月,区域设置最好从
System.Locale
包而不是Haskell 1998Locale
包获得。考虑到这一点,上面的示例代码现在如下:输出现在看起来像这样:
原文,2012年1月答复:
输出如下所示:
Data.Time.Format
可从time
封装中获得。如果你需要解析一位数的月份或天数,换句话说,日期如9-9-2012,那么在%和格式字符之间包含一个连字符。因此,要解析“9-9-2012”,您需要格式字符串“%-d-%-m-%Y”。6ju8rftf2#
使用%-d和%-m而不是%d和%m表示可以使用个位数的日/月,即
这可能是sclv的意思,但他的评论对我来说有点太神秘了。
zphenhs43#
从最近开始,我建议使用strptime包来满足所有日期/时间解析需求。
zhte4eai4#
下面是一些旧代码,其中包含两种类型的自制日期,只有YMD的日期,没有时间或时区等。
它展示了如何使用
readDec
将字符串解析为日期。参见parseDate
函数。使用readDec
,read 数字,前导空格(因为filter
)或前导零无关紧要,解析在第一个非数字处停止。然后使用tail
(跳过非数字)来获取日期的下一个数字字段。它展示了几种格式化输出的方法,但最灵活的方法是使用
Text.printf
。参见instance Show LtDate
。有了 printf,一切皆有可能!一旦你有了(Y,M,D),就很容易转换成Haskell库类型来进行数据操作。使用完HS库后,可以使用
Text.printf
化日期以进行显示。