如何在Haskell中将纪元转换为公历日期时间

mil*_*edi 4 time haskell epoch gregorian-calendar

假设我有一个表示大纪元时间的整数,例如epoch = 1499055085,我想将其转换为UTCTimeHaskell。我怎样才能做到这一点?

在其他语言中,这是一项非常琐碎的任务,为什么在haskell中如此困难?

Wil*_*sem 6

谁说很难?

您可以简单地使用fromIntegral :: (Integral a, Num b) => a -> b将纪元(整数)转换为POSIXTime

接下来,我们可以使用posixSecondsToUTCTime :: POSIXTime -> UTCTime获取UTCTime,最后使用utctDay :: UTCTime -> Day来获取的天部分UTCTime

如果您想要一个(年,月,日)元组,则可以使用该toGregorian :: Day -> (Integer,Int,Int)方法。

因此我们可以使用以下方法:

import Data.Time.Calendar(toGregorian)
import Data.Time.Clock(utctDay,UTCTime)
import Data.Time.Clock.POSIX(posixSecondsToUTCTime)

epochToUTC :: Integral a => a -> UTCTime
epochToUTC = posixSecondsToUTCTime . fromIntegral

epochToGregorian :: Integral a => a -> (Integer,Int,Int)
epochToGregorian = toGregorian . utctDay . epochToUTC
Run Code Online (Sandbox Code Playgroud)

然后例如:

Main> epochToGregorian 1234567
(1970,1,15)
Main> epochToGregorian 123456789
(1973,11,29)
Main> epochToGregorian 1234567890
(2009,2,13)
Run Code Online (Sandbox Code Playgroud)

  • 这很困难,因为我必须导入3个模块并确切知道每个模块包含什么,对于像我这样的新手来说,这很麻烦。 (2认同)

p_b*_*ill 5

尽管投了反对票,但这并不是一个坏问题。那么这里相当标准的“strptime”和“strftime”相当于什么?

\n\n

你会发现这相当复杂,我同意,因为我花了相当多的时间来解决这个问题(这里是n00b),所以这里是我的一些发现。这并不简单,因为:

\n\n
    \n
  1. 处理时间很复杂。
  2. \n
  3. Data.Time 库专注于类型安全(与 Haskell 一致),这也意味着不会为您完成自动类型转换。因此,您必须对此事有所了解。
  4. \n
  5. 如何读取纪元取决于它到底代表什么以及它是如何存储的。因此,如果标准库中没有通用函数的实现epoch -> utc,那不是遗漏,而是因为它不可能存在。
  6. \n
\n\n

说Python更简单,因为datetime它带有从您的环境推断出的“相当好的默认值”。“在大多数情况下足够好的默认参数值”的概念不适用于 Haskell。

\n\n

如果纪元值来自某个任意整数,则 Willem Van Onsem 的epochToUTC作品有效。如果它是来自文件 ( EpochTime) 的时间戳,我们需要另一个函数,因为这不完全是一个整数(它看起来像一个整数,它的行为也像一个整数,但它既不是Int\ Integerxe2\x80\x94 那是一些非常深的水)。

\n\n

至于import语句,您可以将其简化为纯粹的import Data.Time,它将从该模块中获取我们需要的所有内容,但 , 除外posixSecondsToUTCTime,因为...我认为它被认为是一种专门的。

\n\n
import System.Posix.Types(EpochTime)\nimport Data.Time\nimport Data.Time.Clock.POSIX(posixSecondsToUTCTime)\n\nepochToUTC :: EpochTime -> UTCTime\nepochToUTC = posixSecondsToUTCTime . realToFrac\n
Run Code Online (Sandbox Code Playgroud)\n\n

ghci 中的示例:(当前工作目录的时间戳)

\n\n
import System.Posix.Files\n\nfStat <- getFileStatus "."\nlet someTime = epochToUTC . modificationTime $ fStat\n
Run Code Online (Sandbox Code Playgroud)\n\n

而我们很好的操纵了这个时间值。请注意,这EpochTime是特定于System.Posix模块的。如果它是从数据库或网页检索的时间戳,则可能是另一个故事(类型安全不是免费的)。

\n\n

正如这个“strptime”操作不是很熟悉一样,类似的情况也发生在类似“strftime”的操作上。这可以用 来完成formatTime。例子:

\n\n
formatTime defaultTimeLocale "%Y-%m-%d" someTime\n\n--equivalent\nformatTime defaultTimeLocale ( iso8601DateFormat Nothing ) someTime\n\n--whichever dateFmt defined in that TimeLocale\nformatTime defaultTimeLocale ( dateFmt defaultTimeLocale ) someTime\n\n--"%a, %_d %b %Y %H:%M:%S %Z"\nformatTime defaultTimeLocale rfc822DateFormat someTime\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果始终打开defaultTimeLocale,那么您可以优雅地缩写为:

\n\n
formatTime\' = formatTime defaultTimeLocale\n
Run Code Online (Sandbox Code Playgroud)\n\n

读物:

\n\n

Haskell 时间库教程(我们需要更多这样的!)

\n\n

时间 - HaskellWiki

\n