Skip to content

Commit

Permalink
Various fixes to make this build & work on Windows
Browse files Browse the repository at this point in the history
A number of things didn't work on Windows: we were using
gettimeofday() which doesn't exist, localtime_r() doesn't exist, the
tm_zone field in struct tm doesn't exist, etc.

 * timestuff.{c,h} is now cbits/HsTime.c and includes/HsTime.h,
   for consistency with other packages

 * There's a configure script.  Hence, a default Setup.hs will be
   required for using Cabal (I haven't added this yet, I think we
   were going to make some more changes in Cabal to make it optional).

 * fixed various problems in package.conf.in.  I haven't tested
   time.cabal, I expect it doesn't work on Windows, but it might
   still work on Unix.

 * We get the current time from the native Win32 API.  This requires
   the Win32 library, hence a conditional dependency on Win32.

 * some cursory testing on Win32, we can get the local time and the
   timezone looks ok.

darcs-hash:20060529122523-760e2-1707aeb6dcf612f6c7c134b1eab52c1187a8305f
  • Loading branch information
Simon Marlow committed May 29, 2006
1 parent e5ea873 commit 4b425ec
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 29 deletions.
7 changes: 6 additions & 1 deletion Data/Time/Clock/CTimeval.hs
@@ -1,8 +1,11 @@
{-# OPTIONS -ffi -Wall -Werror #-}
{-# OPTIONS -ffi -Wall -Werror -cpp #-}

-- #hide
module Data.Time.Clock.CTimeval where

#ifndef mingw32_HOST_OS
-- All Unix-specific, this

import Foreign
import Foreign.C

Expand All @@ -29,3 +32,5 @@ getCTimeval = with (MkCTimeval 0 0) (\ptval -> do
then peek ptval
else fail ("error in gettimeofday: " ++ (show result))
)

#endif
34 changes: 29 additions & 5 deletions Data/Time/Clock/POSIX.hs
@@ -1,4 +1,4 @@
{-# OPTIONS -Wall -Werror #-}
{-# OPTIONS -Wall -Werror -cpp #-}

-- | POSIX time, if you need to deal with timestamps and the like.
-- Most people won't need this module.
Expand All @@ -7,15 +7,17 @@ module Data.Time.Clock.POSIX
posixDayLength,POSIXTime,posixSecondsToUTCTime,utcTimeToPOSIXSeconds,getPOSIXTime
) where

import Data.Time.Clock.CTimeval
import Data.Time.Clock.UTC
import Data.Time.Calendar.Days
import Data.Fixed

import Control.Monad

ctimevalToPosixSeconds :: CTimeval -> POSIXTime
ctimevalToPosixSeconds (MkCTimeval s mus) = (fromIntegral s) + (fromIntegral mus) / 1000000
#ifdef mingw32_HOST_OS
import Data.Word ( Word64)
import System.Win32.Time
#else
import Data.Time.Clock.CTimeval
#endif

-- | 86400 nominal seconds in every day
posixDayLength :: NominalDiffTime
Expand All @@ -38,4 +40,26 @@ utcTimeToPOSIXSeconds (UTCTime d t) =

-- | Get the current POSIX time from the system clock.
getPOSIXTime :: IO POSIXTime

#ifdef mingw32_HOST_OS
-- On Windows, the equlvalent of POSIX time is "file time", defined as
-- the number of 100-nanosecond intervals that have elapsed since
-- 12:00 A.M. January 1, 1601 (UTC). We can convert this into a POSIX
-- time by adjusting the offset to be relative to the POSIX epoch.

getPOSIXTime = do
FILETIME ft <- System.Win32.Time.getSystemTimeAsFileTime
return (fromIntegral (ft - win32_epoch_adjust) / 10000000)

win32_epoch_adjust :: Word64
win32_epoch_adjust = 116444736000000000

#else

-- Use POSIX time
ctimevalToPosixSeconds :: CTimeval -> POSIXTime
ctimevalToPosixSeconds (MkCTimeval s mus) = (fromIntegral s) + (fromIntegral mus) / 1000000

getPOSIXTime = liftM ctimevalToPosixSeconds getCTimeval

#endif
2 changes: 1 addition & 1 deletion Data/Time/LocalTime/TimeZone.hs
Expand Up @@ -52,7 +52,7 @@ instance Show TimeZone where
utc :: TimeZone
utc = TimeZone 0 False "UTC"

foreign import ccall unsafe "timestuff.h get_current_timezone_seconds" get_current_timezone_seconds :: CTime -> Ptr CInt -> Ptr CString -> IO CLong
foreign import ccall unsafe "HsTime.h get_current_timezone_seconds" get_current_timezone_seconds :: CTime -> Ptr CInt -> Ptr CString -> IO CLong

posixToCTime :: POSIXTime -> CTime
posixToCTime = fromInteger . floor
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -4,6 +4,7 @@ include $(TOP)/mk/boilerplate.mk
SUBDIRS =

ALL_DIRS = \
cbits \
Data \
Data/Time \
Data/Time/Calendar \
Expand All @@ -20,4 +21,6 @@ SRC_CC_OPTS += -Wall -Werror -Iinclude

SRC_HADDOCK_OPTS += -t "Haskell Hierarchical Libraries ($(PACKAGE) package)"

UseGhcForCc = YES

include $(TOP)/mk/target.mk
19 changes: 19 additions & 0 deletions aclocal.m4
@@ -0,0 +1,19 @@
# FP_DECL_ALTZONE
# ---------------
# Defines HAVE_DECL_ALTZONE to 1 if declared, 0 otherwise.
#
# Used by base package.
AC_DEFUN([FP_DECL_ALTZONE],
[AC_REQUIRE([AC_HEADER_TIME])dnl
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_DECLS([altzone], [], [],[#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif])
])# FP_DECL_ALTZONE
54 changes: 54 additions & 0 deletions cbits/HsTime.c
@@ -0,0 +1,54 @@
#include "HsTime.h"
#include <stdio.h>

long int get_current_timezone_seconds (time_t t,int* pdst,char const* * pname)
{
struct tm* ptm;
long gmtoff;
int dst;
char *name;

#if HAVE_LOCALTIME_R
struct tm tmd;
ptm = localtime_r(&t,&tmd);
#else
ptm = localtime(&t);
#endif
// We don't have a better API to use on Windows, the logic to
// decide whether a given data/time falls within DST is
// implemented as part of localtime() in the CRT. This is_dst
// flag is all we need here.

if (ptm)
{
dst = ptm -> tm_isdst;
#if HAVE_TM_ZONE
name = ptm -> tm_zone;
gmtoff = ptm -> tm_gmtoff;
#else

# if mingw32_HOST_OS
name = dst ? _tzname[1] : _tzname[0];
printf("dst: %d, tzname0: %s, tzname1: %s\n", dst, _tzname[0], _tzname[1]);
# elif HAVE_TZNAME
name = *tzname;
# else
# error "Don't know how to get at timezone name on your OS"
# endif

# if mingw32_HOST_OS
gmtoff = dst ? _timezone - 3600 : _timezone;
# elif HAVE_DECL_ALTZONE
gmtoff = dst ? altzone : timezone;
# else
gmtoff = dst ? timezone - 3600 : timezone;
# endif

#endif // HAVE_TM_ZONE
*pdst = dst;
*pname = name;
return gmtoff;

}
else return 0x80000000;
}
15 changes: 15 additions & 0 deletions configure.ac
@@ -0,0 +1,15 @@
AC_INIT([Haskell time package], [0.3.1], [ashley@semantic.org], [time])

# Safety check: Ensure that we are in the correct source directory.
AC_CONFIG_SRCDIR([include/HsTime.h])

AC_CONFIG_HEADERS([include/HsTimeConfig.h])

AC_CHECK_FUNCS([gmtime_r localtime_r])

AC_STRUCT_TM
AC_STRUCT_TIMEZONE

FP_DECL_ALTZONE

AC_OUTPUT
13 changes: 13 additions & 0 deletions include/HsTime.h
@@ -0,0 +1,13 @@
#ifndef __HSTIME_H__
#define __HSTIME_H__

#include "ghcconfig.h"
#include "HsTimeConfig.h"

#if HAVE_TIME_H
#include <time.h>
#endif

long int get_current_timezone_seconds (time_t,int* dst,char const* * name);

#endif
3 changes: 0 additions & 3 deletions include/timestuff.h

This file was deleted.

19 changes: 15 additions & 4 deletions package.conf.in
@@ -1,3 +1,5 @@
#include "ghcconfig.h"

Name: PACKAGE
Version: VERSION
Stability: Beta
Expand All @@ -8,7 +10,13 @@ Maintainer: <ashley@semantic.org>
Homepage: http://semantic.org/TimeLib/
exposed: True
Category:
Build-Depends: base

#if mingw32_HOST_OS
depends: Win32, base
#else
depends: base
#endif

Synopsis: time library
Exposed-modules:
Data.Time.Calendar,
Expand All @@ -23,8 +31,8 @@ Exposed-modules:
Data.Time.LocalTime,
Data.Time
Extensions: ForeignFunctionInterface
C-Sources: timestuff.c
Other-modules:
C-Sources: HsTime.c
Hidden-modules:
Data.Time.Calendar.Private,
Data.Time.Calendar.Days,
Data.Time.Calendar.Gregorian,
Expand All @@ -37,7 +45,10 @@ Other-modules:
Data.Time.LocalTime.TimeOfDay,
Data.Time.LocalTime.LocalTime,
Data.Time.LocalTime.Format
import-dirs: IMPORT_DIR
library-dirs: LIB_DIR
hs-libraries: "HSTime"
include-dirs: INCLUDE_DIR
includes: "timestuff.h"
includes: "HsTime.h"
haddock-interfaces: HADDOCK_IFACE
haddock-html: HTML_DIR
4 changes: 3 additions & 1 deletion time.cabal
Expand Up @@ -22,7 +22,7 @@ Exposed-modules:
Data.Time.LocalTime,
Data.Time
Extensions: ForeignFunctionInterface
C-Sources: timestuff.c
C-Sources: HsTime.c
Other-modules:
Data.Time.Calendar.Private,
Data.Time.Calendar.Days,
Expand All @@ -36,3 +36,5 @@ Other-modules:
Data.Time.LocalTime.TimeOfDay,
Data.Time.LocalTime.LocalTime,
Data.Time.LocalTime.Format
include-dirs: include
includes: "HsTime.h"
14 changes: 0 additions & 14 deletions timestuff.c

This file was deleted.

0 comments on commit 4b425ec

Please sign in to comment.