Главная » Haskell » Модуль Time

0

предоставляет программисту  инструменты для работы с системным временем, включая функциональность для обработки собственно времени, информации о временн?ой  зоне и т. д.  Функциональность модуля следует стандарту RFC 1129 в части обработки времени UTC. Использование модуля:

import System.Time

В модуле содержатся определения нескольких специализированных алгебраических типов данных, а также функций для их обработки.

Тип: ClockTime

Описание: представление внутреннего формата времени. Значения  этого типа могут быть сравниваемы, преобразованы в строки или преобразованы во внешнее представление в типе ClendarTime для дальнейшего использования. Определение:

data  ClockTime = TOD  Integer Integer

Для данного типа определены экземпляры следующих классов: Eq, Ord и Show.

Функция: getClockTime

Описание: возвращает текущее системное время во внутреннем формате.

Определение:

getClockTime  :: IO ClockTime

getClockTime  = do (sec, usec)  < getClockTimePrim

return (TOD (fromIntegral sec)  ((fromIntegral usec)  * 1000000))

Тип: TimeDiff

Описание: представляет разницу между двумя отметками времени.

Определение:

data  TimeDiff

=  TimeDiff

{

tdYear        ::  Int tdMonth      :: Int tdDay          ::  Int tdHour        ::  Int tdMin          ::  Int tdSec          ::  Int

tdPicosec :: Integer

}

Для данного типа определены экземпляры следующих классов: Eq, Ord, Read

и Show.

Функция: noTimeDiff

Описание: константная функция, возвращающая нулевую разницу между двумя отметками времени.

Определение:

noTimeDiff :: TimeDiff

noTimeDiff = TimeDiff 0 0 0 0 0 0 0

Функция: diffClockTimes

Описание: возвращает разницу между двумя заданными отметками времени.

Определение:

diffClockTimes :: ClockTime ->  ClockTime ->  TimeDiff

diffClockTimes (TOD sa pa)  (TOD sb pb)  = noTimeDiff { tdSec  = fromIntegral  (sa  sb), tdPicosec  = pa pb  }

Функция: addToClockTime

Описание: возвращает новую отметку времени, полученную при помощи добавления к заданной отметке времени некоторого временн?ого интервала. Определение:

addToClockTime :: TimeDiff ->  ClockTime ->  ClockTime addToClockTime (TimeDiff year  mon  day hour  min sec  psec)

(TOD c_sec  c_psec)

= let sec_diff =  toInteger sec  +

60 *  toInteger  min + 3600 *  toInteger  hour  +

24 * 3600 * toInteger day

(d_sec, d_psec)  = (c_psec  + psec)  ‘quotRem‘  1000000000000 cal   = toUTCTime (TOD (c_sec  +  sec_diff + d_sec)  d_psec) new_mon = fromEnum  (ctMonth   cal) + r_mon

month’  =  fst  tmp yr_diff  =  snd  tmp

tmp | new_mon  < 0   = (toEnum (12  + new_mon), (-1))

| new_mon  > 11 = (toEnum (new_mon  ‘mod‘  12), 1)

| otherwise      = (toEnum  new_mon,  0) (r_yr, r_mon) =  mon  ‘quotRem‘  12

year’ = ctYear  cal   + year  + r_yr +  yr_diff

in  toClockTime  cal   {ctMonth   = month’, ctYear  = year’}

Функция: normalizeTimeDiff

Описание: преобразует разницу между двумя отметками времени в нормальную форму.

Определение:

normalizeTimeDiff :: TimeDiff ->  TimeDiff normalizeTimeDiff td = let rest0 = toInteger  (tdSec  td) +

60 * (toInteger (tdMin td) +

60 * (toInteger (tdHour td)  +

24 * (toInteger (tdDay  td) +

30 * toInteger (tdMonth  td) +

365 * toInteger (tdYear td))))

(diffYears,   rest1)      = rest0 ‘quotRem‘  (365  * 24  * 3600) (diffMonths, rest2)      = rest1  ‘quotRem‘  (30  * 24 * 3600) (diffDays,    rest3)      = rest2  ‘quotRem‘  (24  * 3600) (diffHours,   rest4)      =  rest3 ‘quotRem‘  3600

(diffMins,    diffSecs) = rest4  ‘quotRem‘  60 in  td { tdYear    =  fromInteger diffYears,

tdMonth  = fromInteger  diffMonths, tdDay     =  fromInteger diffDays, tdHour    = fromInteger  diffHours, tdMin      =  fromInteger diffMins, tdSec     = fromInteger  diffSecs }

Функция: timeDiffToString

Описание: преобразует разницу между двумя отметками времени в строку, используя локальные соглашения о представлении времени.

Определение:

timeDiffToString :: TimeDiff  ->  String

timeDiffToString = formatTimeDiff  defaultTimeLocale "%c"

Функция: formatTimeDiff

Описание: преобразует разницу между двумя отметками времени в строку, используя локальные соглашения о представлении  времени и форматную строку. Результат понимаем функцией strftime языка C.

Определение:

formatTimeDiff :: TimeLocale  ->  String ->  TimeDiff ->  String

formatTimeDiff l fmt  td@(TimeDiff year  month day hour  min sec  _)  = doFmt fmt where

doFmt ""              = ""

doFmt (’%’:’-’:cs) =  doFmt (’%’:cs) doFmt  (’%’:’_’:cs) = doFmt  (’%’:cs)

doFmt (’%’:c:cs)    = decode c  ++ doFmt cs doFmt (c:cs)             =  c  : doFmt cs

decode spec = case spec of

’B’ ->  fst (months  l !!  fromEnum  month) ’b’ ->  snd  (months  l !! fromEnum  month) ’h’ ->  snd (months  l  !! fromEnum  month) ’c’  ->  defaultTimeDiffFmt td

’C’ ->  show2 (year  ‘quot‘ 100) ’D’ ->  doFmt "%m/%d/%y"

’d’  ->  show2  day ’e’  ->  show2’  day ’H’  ->  show2  hour

’I’ ->  show2  (to12 hour) ’k’ ->  show2’  hour

’l’ ->  show2’  (to12 hour) ’M’ ->  show2  min

’m’   ->  show2  (fromEnum  month + 1) ’n’ ->  "\n"

’p’ ->  (if hour  < 12 then  fst else  snd)  (amPm  l) ’R’ ->  doFmt "%H:%M"

’r’ ->  doFmt  (time12Fmt  l) ’T’ ->  doFmt  "%H:%M:%S"

’t’  ->  "\t"

’S’  ->  show2  sec ’s’  ->  show2  sec

’X’ ->  doFmt  (timeFmt  l) ’x’ ->  doFmt  (dateFmt  l) ’Y’ ->  show  year

’y’ ->  show2  (year  ‘rem‘  100) ’%’  ->  "%"

c      ->  [c]

defaultTimeDiffFmt (TimeDiff  year  month day hour  min sec  _)

= foldr (\(v,  s) rest ->  (if v  /=  0

then  show v  ++ ’ ’:(addS v  s) ++ if null  rest

else  "") ++ rest) ""

then  "" else  ",  "

(zip [year, month,  day,  hour, min,  sec]  (intervals l)) addS v  s  = if abs v  == 1

then  fst  s else  snd  s

Тип: CalendarTime

Описание: представляет  время в удобном для пользователя формате.  В единственном конструкторе собраны поля для представления текущих года, месяца, дня, часа, минуты, секунды, пикосекунды, наименования дня недели, номера дня в году, наименования временн?ой зоны, отличие от UTC в секундах и флаг наличия режима летнего времени.

Определение:

data  CalendarTime

=  CalendarTime

{

ctYear        ::  Int  ctMonth      :: Month ctDay         ::  Int ctHour        :: Int ctMin          ::  Int ctSec          ::  Int ctPicosec ::  Integer ctWDay      ::  Day ctYDay        ::  Int ctTZName  ::  String ctTZ           :: Int ctIsDST      ::  Bool

}

Для данного типа определены экземпляры следующих классов: Eq, Ord, Read

и Show.

Тип: Month

Описание: тип-перечисление для представления месяцев.

Определение:

data  Month

= January

| February

| March

| April

| May

| June

| July

|  August

| September

| October

| November

| December

Для данного типа определены экземпляры следующих классов: Bounded, Enum,

Eq, Ix, Ord, Read и Show.

Тип: Day

Описание: тип-перечисление для представления дня недели.

Определение:

data  Day

=  Sunday

|  Monday

| Tuesday

| Wednesday

| Thursday

|  Friday

| Saturday

Для данного типа определены экземпляры следующих классов: Bounded, Enum,

Eq, Ix, Ord, Read и Show.

Функция: toCalendarTime

Описание: преобразует время во внутреннем представлении во внешнее представление типа CalendarTime. Поскольку результат зависит от локальных настроек (а потому недетерминирован), функция возвращает результат в монаде IO. Определение:

toCalendarTime  :: ClockTime ->  IO CalendarTime

Функция определена в виде примитива.

Функция: toUTCTime

Описание: преобразует время во внутреннем представлении во внешнее представление типа CalendarTime в стандартном формате UTC.

Определение:

toUTCTime :: ClockTime ->  CalendarTime

Функция определена в виде примитива.

Функция: toClockTime

Описание: производит обратное преобразование времени во внешнем представлении при помощи типа CalendarTime во внутреннее представление. Определение:

toClockTime  :: CalendarTime  ->  ClockTime

Функция определена в виде примитива.

Функция: calendarTimeToString

Описание: форматирует заданное время в соответствии с локальными соглашениями о формате времени.

Определение:

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

Функция: formatCalendarTime

Описание: форматирует заданное время в соответствии с локальными соглашениями о формате времени и форматной строкой. Результат понимаем функцией strftime языка C.

Определение:

formatCalendarTime :: TimeLocale  ->  String ->  CalendarTime  ->  String formatCalendarTime l fmt  (CalendarTime  year  mon  day  hour  min sec  _

wday yday tzname _ _)  = doFmt fmt

where

doFmt (’%’:’-’:cs) = doFmt  (’%’:cs) doFmt (’%’:’_’:cs)  = doFmt (’%’:cs)

doFmt (’%’:c:cs)    = decode c  ++  doFmt cs doFmt (c:cs) = c  : doFmt  cs

doFmt "" = ""

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’ =  show2  sec

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 :: Int ->  String

show2 x  | x’ < 10     = ’0’: show x’

| otherwise = show x’

where

x’ = x  ‘rem‘  100

show2’  :: Int ->  String

show2’  x  | x’ < 10     = ’ ’: show x’

| otherwise = show x’

where

x’ = x  ‘rem‘  100

show3 :: Int ->  String

show3 x  = show (x ‘quot‘ 100)  ++ show2 (x ‘rem‘ 100)

to12  :: Int ->  Int

to12  h = let h’ = h  ‘mod‘  12 in    if h’ == 0

then  12 else  h’

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии