The Haskell 98 Report
top | back | next | contents | function index


24  日付と時刻


module Time (
ClockTime, 
Month(January,February,March,April,May,June,
      July,August,September,October,November,December),
Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday),
CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin,
     ctSec, ctPicosec, ctWDay, ctYDay, 
                     ctTZName, ctTZ, ctIsDST),
TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, tdHour,
 tdMin, tdSec, tdPicosec),
getClockTime, addToClockTime, diffClockTimes,
        toCalendarTime, toUTCTime, toClockTime,
        calendarTimeToString, formatCalendarTime ) where

import Ix(Ix)

data ClockTime = ... -- Implementation-dependent
instance Ord  ClockTime where ...
instance Eq   ClockTime where ...

data Month =  January   | February | March    | April
           |  May       | June     | July     | August
           |  September | October  | November | December
           deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show)

data Day   =  Sunday | Monday  | Tuesday  | Wednesday | Thursday 
           |  Friday | Saturday
           deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show)

data CalendarTime = CalendarTime {
ctYear   :: Int,
        ctMonth  :: Month,
        ctDay, ctHour, ctMin, ctSec  :: Int,
ctPicosec :: Integer,
ctWDay    :: Day,
ctYDay       :: Int,
ctTZName   :: String,
ctTZ          :: Int,
ctIsDST :: Bool
} deriving (Eq, Ord, Read, Show)

data TimeDiff = TimeDiff {
tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int,
tdPicosec      :: Integer
} deriving (Eq, Ord, Read, Show)

-- Functions on times
getClockTime         :: IO ClockTime
     
addToClockTime       :: TimeDiff  -> ClockTime -> ClockTime
diffClockTimes       :: ClockTime -> ClockTime -> TimeDiff
     
toCalendarTime       :: ClockTime    -> IO CalendarTime
toUTCTime            :: ClockTime    -> CalendarTime
toClockTime          :: CalendarTime -> ClockTime
calendarTimeToString :: CalendarTime -> String
formatCalendarTime   :: TimeLocale -> String -> CalendarTime -> String

Time ライブラリはタイムゾーン情報を含む時刻に対する標準的機 能を提供する。このライブラリは UTC の扱いにたいしては RFC 1129 に従う。

ClockTime は抽象型で、システム内部クロックのために用意されて いる。時刻は直接比較することができ、また、I/O やそのほかの用途のため にカレンダー時刻 CalendarTime に変換することができる。 CalendarTime はユーザが読みとることができ、また、内部的な ClockTime 型の表現として取り扱い可能なものである。それぞれの 数値フィールドの範囲は以下のとおりである。

Value Range Comments
ctYear -maxInt... maxInt グレゴリウス暦以前の日付については不正確である
ctDay 1... 31
ctHour 0... 23
ctMin 0... 59
ctSec 0... 61 2閏秒が可能
ctPicosec 0... (1012)-1
ctYDay 0... 365 平年は364まで
ctTZ -89999... 89999 UTC からの秒変位

ctTZName フィールドはタイムゾーンの名前である。ctIsDST フィールドはサマータイムが有効であれば True であり、さもなけ れば、False である。TimeDiff 型は 2 つの異る時刻の 差をユーザが読んで理解できる形式で記録するものである。

関数 getClockTime は現在の時刻を内部表現で返す。式 addToClockTime d t は時間 d と時刻 t を加算し新しい時刻とする。時間 d は正の場合もあれば、 負の場合もある。式 diffClockTimes t1 t2 は二つ の時刻 t1t2 との差を返す。これは TimeDiff と同様である。

関数 toCalendarTime tt を現地時間に変換し、 タイムゾーンとサマータイムによって変換した時間を変更する。これはロー カルな環境に依存するので toCalendarTimeIO モナ ドの中にある。

関数 toUTCTime tt を標準の UTC 形式の CalendarTime に変換する。toClockTime ll を対応する ClockTime へ変換し、ctWDayctYDayctTZName および ctIsDST フィールドの内容 を無視する。

関数 calendarTimeToString はローカルコンベンションによるカレ ンダータイムを整形し文字列をフォーマットする。

24.1  Time ライブラリ


module Time (
        ClockTime, 
        Month(January,February,March,April,May,June,
              July,August,September,October,November,December),
        Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday),
CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin,
     ctSec, ctPicosec, ctWDay, ctYDay, 
                     ctTZName, ctTZ, ctIsDST),
TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, 
 tdHour, tdMin, tdSec, tdPicosec),
        getClockTime, addToClockTime, diffClockTimes,
        toCalendarTime, toUTCTime, toClockTime,
        calendarTimeToString, formatCalendarTime ) where

import Ix(Ix)
import Locale(TimeLocale(..),defaultTimeLocale)
import Char ( intToDigit )

data ClockTime = ...                    -- Implementation-dependent
instance Ord  ClockTime where ...
instance Eq   ClockTime where ...

data Month =  January   | February | March    | April
           |  May       | June     | July     | August
           |  September | October  | November | December
           deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show)

data Day   =  Sunday | Monday  | Tuesday  | Wednesday | Thursday 
           |  Friday | Saturday
           deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show)

data CalendarTime = CalendarTime {
                ctYear                          :: Int,
                ctMonth                         :: Month,
                ctDay, ctHour, ctMin, ctSec     :: Int,
                ctPicosec                       :: Integer,
                ctWDay                          :: Day,
                ctYDay                          :: Int,
                ctTZName                        :: String,
                ctTZ                            :: Int,
                ctIsDST                         :: Bool
        } deriving (Eq, Ord, Read, Show)

data TimeDiff = TimeDiff {
                tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int,
                tdPicosec                                    :: Integer
        } deriving (Eq, Ord, Read, Show)


getClockTime            :: IO ClockTime
getClockTime            = ...           -- Implementation-dependent

addToClockTime          :: TimeDiff     -> ClockTime -> ClockTime
addToClockTime td ct    =  ...          -- Implementation-dependent

diffClockTimes          :: ClockTime    -> ClockTime -> TimeDiff
diffClockTimes ct1 ct2  =  ...          -- Implementation-dependent

toCalendarTime          :: ClockTime    -> IO CalendarTime
toCalendarTime ct       =  ...          -- Implementation-dependent

toUTCTime               :: ClockTime    -> CalendarTime
toUTCTime ct            =  ...          -- Implementation-dependent

toClockTime             :: CalendarTime -> ClockTime
toClockTime cal         =  ...          -- Implementation-dependent

calendarTimeToString    :: CalendarTime -> String
calendarTimeToString    =  formatCalendarTime defaultTimeLocale "%c"

formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String
formatCalendarTime l fmt ct@(CalendarTime year mon day hour min sec sdec 
                                           wday yday tzname _ _) =
        doFmt fmt
  where doFmt ('%':c:cs) = decode c ++ doFmt cs
        doFmt (c:cs) = c : doFmt cs
        doFmt "" = ""

        to12 :: Int -> Int
        to12 h = let h' = h `mod` 12 in if h' == 0 then 12 else h'

        decode 'A' = fst (wDays l  !! fromEnum wday)
        decode 'a' = snd (wDays l  !! fromEnum wday)
        decode 'B' = fst (months l !! fromEnum mon)
        decode 'b' = snd (months l !! fromEnum mon)
        decode 'h' = snd (months l !! fromEnum mon)
        decode 'C' = show2 (year `quot` 100)
        decode 'c' = doFmt (dateTimeFmt l)
        decode 'D' = doFmt "%m/%d/%y"
        decode 'd' = show2 day
        decode 'e' = show2' day
        decode 'H' = show2 hour
        decode 'I' = show2 (to12 hour)
        decode 'j' = show3 yday
        decode 'k' = show2' hour
        decode 'l' = show2' (to12 hour)
        decode 'M' = show2 min
        decode 'm' = show2 (fromEnum mon+1)
        decode 'n' = "\n"
        decode 'p' = (if hour < 12 then fst else snd) (amPm l)
        decode 'R' = doFmt "%H:%M"
        decode 'r' = doFmt (time12Fmt l)
        decode 'T' = doFmt "%H:%M:%S"
        decode 't' = "\t"
        decode 'S' = show2 sec
        decode 's' = ...                -- Implementation-dependent
        decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7)
        decode 'u' = show (let n = fromEnum wday in 
                           if n == 0 then 7 else n)
        decode 'V' = 
            let (week, days) = 
                   (yday + 7 - if fromEnum wday > 0 then 
                               fromEnum wday - 1 else 6) `divMod` 7
            in  show2 (if days >= 4 then
                          week+1 
                       else if week == 0 then 53 else week)

        decode 'W' = 
            show2 ((yday + 7 - if fromEnum wday > 0 then 
                               fromEnum wday - 1 else 6) `div` 7)
        decode 'w' = show (fromEnum wday)
        decode 'X' = doFmt (timeFmt l)
        decode 'x' = doFmt (dateFmt l)
        decode 'Y' = show year
        decode 'y' = show2 (year `rem` 100)
        decode 'Z' = tzname
        decode '%' = "%"
        decode c   = [c]

show2, show2', show3 :: Int -> String
show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)]

show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x

show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100)

The Haskell 98 Report
top | back | next | contents | function index