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 は二つ の時刻 t1 と t2 との差を返す。これは TimeDiff と同様である。

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

関数 toUTCTime t は t を標準の UTC 形式の CalendarTime に変換する。toClockTime l は l を対応する ClockTime へ変換し、ctWDay、 ctYDay、ctTZName および 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