diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-TimeLib is Copyright (c) Ashley Yakeley, 2004-2014. All rights reserved.
+TimeLib is Copyright (c) Ashley Yakeley and contributors, 2004-2022. All rights reserved.
 Certain sections are Copyright 2004, The University Court of the University of Glasgow. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,6 @@
-module Main
-    ( main
-    ) where
+module Main (
+    main,
+) where
 
 import Distribution.Simple
 
diff --git a/aclocal.m4 b/aclocal.m4
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,19 +1,17 @@
-# 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
+# FP_DECL_ALTZONE
+# ---------------
+# Defines HAVE_DECL_ALTZONE to 1 if declared, 0 otherwise.
+#
+# Used by base package.
+AC_DEFUN([FP_DECL_ALTZONE],
+[
+  AC_CHECK_HEADERS_ONCE([sys/time.h])
+
+  AC_CHECK_HEADERS([sys/time.h])
+  AC_CHECK_DECLS([altzone], [], [],[
+  #if HAVE_SYS_TIME_H
+  #include <sys/time.h>
+  #endif
+  #include <time.h>
+  ])
+])# FP_DECL_ALTZONE
diff --git a/benchmark/Main.hs b/benchmark/Main.hs
new file mode 100644
--- /dev/null
+++ b/benchmark/Main.hs
@@ -0,0 +1,21 @@
+module Main where
+
+import Criterion.Main
+import Data.Time
+import Data.Time.Clock.POSIX
+import Data.Time.Clock.System
+
+main :: IO ()
+main = do
+    getCurrentTime >>= print
+    getPOSIXTime >>= print . posixSecondsToUTCTime
+    getZonedTime >>= print
+    ct <- getCurrentTime
+    defaultMain
+        [ bench "getCurrentTime" $ nfIO getCurrentTime
+        , bench "getPOSIXTime" $ nfIO getPOSIXTime
+        , bench "getSystemTime" $ nfIO getSystemTime
+        , bench "getTimeZone" $ nfIO $ getTimeZone ct
+        , bench "getCurrentTimeZone" $ nfIO getCurrentTimeZone
+        , bench "getZonedTime" $ nfIO getZonedTime
+        ]
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,86 @@
 # Change Log
 
-## [1.10]
+## [1.16] - 2026-05-03
+
+- add periodIn
+- use template-haskell-lift rather than template-haskell for Lift instances on GHC 9.14 and later
+- support GHC 9.14
+- improve documentation, test, build, CI
+
+## [1.15] - 2025-08-04
+
+- support compiler / GHC backends (with CI):
+  - JavaScript
+  - WebAssembly
+  - MicroHs
+- add diffTimeOfDay
+- add \[add/diff\]\[UTC/Local\]Duration\[Clip/Rollover\]
+- add patterns for DiffTime & NominalDiffTime
+- UNIXish formatting/parsing:
+  - add instance ParseTime DayOfWeek
+  - make use of %s specifiers in parsing various types
+  - instances for Quarter and QuarterOfYear
+  - %v specifier for quarter-of-year
+- ISO8601 formatting/parsing:
+  - loosen up parsing time-zone modifiers
+- add Lift instances to all types (really this time)
+- hide Data.Time.Format.Internal
+- add periodToDayClip
+- fix MonthDay and QuarterDay clipping
+
+## [1.14] - 2024-03-10
+- add Lift instances to all types
+- add Generic instances to all types that have exposed constructors
+- fix show of CalendarDiffTime
+- fix diffGregorianDurationRollOver, diffJulianDurationRollOver
+- Parsing is now maximal munch rather than ambiguous for
+  - digits of %q and %Q specifiers
+  - optional timezone for UTCTime
+  - optional specifiers in ISO8601 formats
+
+## [1.12.2] - 2022-05-14
+- add weekFirstDay, weekLastDay, weekAllDays
+- expose formatting/parsing internals
+- fix: handle +HH format for ISO8601 timeOffsetFormat etc.
+- fix clock_REALTIME for WebAssembly
+
+## [1.12.1] - 2021-10-24
+- add DayPeriod class for periods of days
+- add QuarterDay pattern and DayOfQuarter type synonym
+- add CommonEra and BeforeCommonEra patterns
+
+## [1.12] - 2021-06-12
+- support GHC 8.8, 8.10, 9.0 only
+- add patterns for each month of year
+- fix: don't provide TAI clock where it's unavailable (e.g. FreeBSD)
+- fix: handle time of day 24:00:00 for ISO 8601 parsing (only)
+- fix parsing of %f and %G with negative years
+
+## [1.11.1.2] - 2021-04-24
+- fix cabal file
+- correct "license" field in cabal file
+- add dates to changelog entries
+
+## [1.11.1.1] - 2020-12-09
+- fix module Safe status
+
+## [1.11.1] - 2020-11-23
+- all modules Safe or Trustworthy
+- fix NFData instances for DiffTime, NominalDiffTime, TimeOfDay
+- add missing Ix, Enum, NFData instances to DayOfWeek, CalendarDiffDays, CalendarDiffTime, Month, Quarter, QuarterOfYear
+
+## [1.11] - 2020-10-14
+- new calendrical type synonyms and abstract constructors
+- new Month type, with appropriate functions
+- new QuarterOfYear and Quarter type, with appropriate functions
+- new functions for working with week-based years
+- new parseTimeMultipleM function for a list of (format, input) pairs
+- add instance Ord DayOfWeek
+- add instance Read DiffTime (and NominalDiffTime)
+- change instance Read UTCTime to allow omitted timezone
+- parsing dates rejects ambiguity based on digits, even if there's only one valid date
+
+## [1.10] - 2020-03-13
 - remove deprecated functions parseTime, readTime, readsTime
 - deprecate iso8601DateFormat
 - parsing: fix %_Q %-Q %_q %-q
@@ -9,19 +89,19 @@
 - change internal members of ParseTime to allow newtype-deriving
 - new functions (aliases) pastMidnight & sinceMidnight
 
-## [1.9.3]
+## [1.9.3] - 2019-05-20
 - documentation fixes
 
-## [1.9.2]
+## [1.9.2] - 2018-08-01
 - add Data and Typeable instance for CalendarDiffDays and CalendarDiffTime
 - "@since" annotations for everything after 1.9
 - fix import issue with GHC 8.6
 
-## [1.9.1]
+## [1.9.1] - 2018-02-27
 - new functions secondsToNominalDiffTime & nominalDiffTimeToSeconds
 - expose FormatTime and ParseTime in Data.Time.Format.Internal
 
-## [1.9]
+## [1.9] - 2018-01-25
 - new conversion functions timeToDaysAndTimeOfDay & daysAndTimeOfDayToTime
 - new DayOfWeek type
 - new CalendarDiffDays and CalendarDiffTime types
@@ -34,37 +114,37 @@
 - parsing: reject invalid (and empty) time-zones with %z and %Z
 - parsing: reject invalid hour/minute/second specifiers
 
-## [1.8.0.4]
+## [1.8.0.4] - 2018-01-09
 - Fix "show minBound" bug
 - haddock: example for parseTimeM
 
-## [1.8.0.3]
+## [1.8.0.3] - 2017-08-04
 - Add "Quick start" documentation
 
-## [1.8.0.2]
+## [1.8.0.2] - 2017-05-13
 - Fix behaviour of %Q in format
 
-## [1.8.0.1]
+## [1.8.0.1] - 2017-03-11
 - Get building on 32 bit machine
 
-## [1.8]
+## [1.8] - 2017-02-14
 - Added SystemTime
 - Data.Time.Format: allow padding widths in specifiers for formatting (but not parsing)
 - Test: use tasty, general clean-up
 - Test: separate out UNIX-specific tests, so the others can be run on Windows
 - Clean up haddock.
 
-## [1.7.0.1]
+## [1.7.0.1] - 2016-12-19
 - Fix bounds issue in .cabal file
 
-## [1.7]
+## [1.7] - 2016-11-19
 - Data.Time.Clock.TAI: change LeapSecondTable to LeapSecondMap with Maybe type; remove parseTAIUTCDATFile
 
-## [1.6.0.1]
+## [1.6.0.1] - 2016-05-07
 - Get building with earlier GHC versions
 - Set lower bound of base correctly
 
-## [1.6]
+## [1.6] - 2015-12-20
 
 ### Added
 - FormatTime, ParseTime, Show and Read instances for UniversalTime
@@ -78,4 +158,48 @@
 - Parsing functions now reject invalid dates
 - Various documentation fixes
 
-## [1.5.0.1]
+## [1.5.0.1] - 2014-12-13
+
+## [1.5] - 2014-09-10
+
+## [1.4.2] - 2014-03-03
+
+## [1.4.1] - 2013-06-24
+
+## [1.4.0.2] - 2012-11-25
+
+## [1.4.0.1] - 2011-10-31
+
+## [1.4] - 2011-09-13
+
+## [1.3] - 2011-08-10
+
+## [1.2.0.5] - 2011-05-11
+
+## [1.2.0.4] - 2011-02-03
+
+## [1.2.0.3] - 2010-06-22
+
+## [1.2.0.2] - 2010-04-26
+
+## [1.2.0.1] - 2010-04-11
+
+## [1.2] - 2010-04-11
+
+## [1.1.4] - 2009-07-17
+
+## [1.1.3] - 2009-06-01
+
+## [1.1.2.4] - 2009-04-17
+
+## [1.1.2.3] - 2009-01-17
+
+## [1.1.2.2] - 2008-10-11
+
+## [1.1.2.1] - 2008-06-19
+
+## [1.1.2.0] - 2007-11-03
+
+## [1.1.1] - 2007-04-22
+
+## [1.0] - 2006-11-02
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,4706 +1,4850 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Haskell time package 1.10.
-#
-# Report bugs to <ashley@semantic.org>.
-#
-#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Use a proper internal environment variable to ensure we don't fall
-  # into an infinite loop, continuously re-executing ourselves.
-  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
-    _as_can_reexec=no; export _as_can_reexec;
-    # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
-  fi
-  # We don't want this to propagate to other subprocesses.
-          { _as_can_reexec=; unset _as_can_reexec;}
-if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '\${1+\"\$@\"}'='\"\$@\"'
-  setopt NO_GLOB_SUBST
-else
-  case \`(set -o) 2>/dev/null\` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-"
-  as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
-  exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
-  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
-  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
-  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
-  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  as_found=:
-  case $as_dir in #(
-	 /*)
-	   for as_base in sh bash ksh sh5; do
-	     # Try only shells that exist, to save several forks.
-	     as_shell=$as_dir/$as_base
-	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  CONFIG_SHELL=$as_shell as_have_required=yes
-		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  break 2
-fi
-fi
-	   done;;
-       esac
-  as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
-      if test "x$CONFIG_SHELL" != x; then :
-  export CONFIG_SHELL
-             # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
-fi
-
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
-  else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: ashley@semantic.org about your system, including any
-$0: error possibly output before this message. Then install
-$0: a modern shell, or manually run the script under such a
-$0: shell if you do have one."
-  fi
-  exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
-  as_lineno_1=$LINENO as_lineno_1a=$LINENO
-  as_lineno_2=$LINENO as_lineno_2a=$LINENO
-  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
-  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
-  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
-  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
-  # already done that, so ensure we don't try to do so again and fall
-  # in an infinite loop.  This has already happened in practice.
-  _as_can_reexec=no; export _as_can_reexec
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME='Haskell time package'
-PACKAGE_TARNAME='time'
-PACKAGE_VERSION='1.10'
-PACKAGE_STRING='Haskell time package 1.10'
-PACKAGE_BUGREPORT='ashley@semantic.org'
-PACKAGE_URL=''
-
-ac_unique_file="lib/include/HsTime.h"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-EGREP
-GREP
-CPP
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-runstatedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-with_gcc
-with_compiler
-'
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
-    ac_prev=
-    continue
-  fi
-
-  case $ac_option in
-  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *=)   ac_optarg= ;;
-  *)    ac_optarg=yes ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir=$ac_optarg ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build_alias ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build_alias=$ac_optarg ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file=$ac_optarg ;;
-
-  --config-cache | -C)
-    cache_file=config.cache ;;
-
-  -datadir | --datadir | --datadi | --datad)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
-    datadir=$ac_optarg ;;
-
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
-  -disable-* | --disable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
-
-  -enable-* | --enable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=\$ac_optarg ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix=$ac_optarg ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he | -h)
-    ac_init_help=long ;;
-  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
-    ac_init_help=recursive ;;
-  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
-    ac_init_help=short ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host_alias ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host_alias=$ac_optarg ;;
-
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir=$ac_optarg ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir=$ac_optarg ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir=$ac_optarg ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir=$ac_optarg ;;
-
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
-    localstatedir=$ac_optarg ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir=$ac_optarg ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c | -n)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir=$ac_optarg ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix=$ac_optarg ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix=$ac_optarg ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix=$ac_optarg ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name=$ac_optarg ;;
-
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir=$ac_optarg ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir=$ac_optarg ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site=$ac_optarg ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir=$ac_optarg ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir=$ac_optarg ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target_alias ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target_alias=$ac_optarg ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers | -V)
-    ac_init_version=: ;;
-
-  -with-* | --with-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=\$ac_optarg ;;
-
-  -without-* | --without-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=no ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes=$ac_optarg ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries=$ac_optarg ;;
-
-  -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
-    ;;
-
-  *=*)
-    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
-    # Reject names that are not valid shell variable names.
-    case $ac_envvar in #(
-      '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
-    esac
-    eval $ac_envvar=\$ac_optarg
-    export $ac_envvar ;;
-
-  *)
-    # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
-    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
-  case $enable_option_checking in
-    no) ;;
-    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
-  esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
-		datadir sysconfdir sharedstatedir localstatedir includedir \
-		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
-do
-  eval ac_val=\$$ac_var
-  # Remove trailing slashes.
-  case $ac_val in
-    */ )
-      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
-      eval $ac_var=\$ac_val;;
-  esac
-  # Be sure to have absolute directory names.
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
-  esac
-  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
-  if test "x$build_alias" = x; then
-    cross_compiling=maybe
-  elif test "x$build_alias" != "x$host_alias"; then
-    cross_compiling=yes
-  fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_myself" : 'X\(//\)[^/]' \| \
-	 X"$as_myself" : 'X\(//\)$' \| \
-	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
-	pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
-  # Omit some internal or obsolete options to make the list less imposing.
-  # This message is too long to be a string in the A/UX 3.1 sh.
-  cat <<_ACEOF
-\`configure' configures Haskell time package 1.10 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE.  See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
-  -h, --help              display this help and exit
-      --help=short        display options specific to this package
-      --help=recursive    display the short help of all the included packages
-  -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking ...' messages
-      --cache-file=FILE   cache test results in FILE [disabled]
-  -C, --config-cache      alias for \`--cache-file=config.cache'
-  -n, --no-create         do not create output files
-      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
-
-Installation directories:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
-  --bindir=DIR            user executables [EPREFIX/bin]
-  --sbindir=DIR           system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR        program executables [EPREFIX/libexec]
-  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
-  --libdir=DIR            object code libraries [EPREFIX/lib]
-  --includedir=DIR        C header files [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
-  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR           info documentation [DATAROOTDIR/info]
-  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR            man documentation [DATAROOTDIR/man]
-  --docdir=DIR            documentation root [DATAROOTDIR/doc/time]
-  --htmldir=DIR           html documentation [DOCDIR]
-  --dvidir=DIR            dvi documentation [DOCDIR]
-  --pdfdir=DIR            pdf documentation [DOCDIR]
-  --psdir=DIR             ps documentation [DOCDIR]
-_ACEOF
-
-  cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-  case $ac_init_help in
-     short | recursive ) echo "Configuration of Haskell time package 1.10:";;
-   esac
-  cat <<\_ACEOF
-
-Optional Packages:
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-Gnu C compiler
-Haskell compiler
-
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <ashley@semantic.org>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
-  # If there are subdirs, report their specific --help.
-  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" ||
-      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
-      continue
-    ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
-    else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
-  done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
-  cat <<\_ACEOF
-Haskell time package configure 1.10
-generated by GNU Autoconf 2.69
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
-  exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
-  if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ---------------------------------- ##
-## Report this to ashley@semantic.org ##
-## ---------------------------------- ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
-# ----------------------------------------------------
-# Tries to find if the field MEMBER exists in type AGGR, after including
-# INCLUDES, setting cache variable VAR accordingly.
-ac_fn_c_check_member ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
-$as_echo_n "checking for $2.$3... " >&6; }
-if eval \${$4+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$5
-int
-main ()
-{
-static $2 ac_aggr;
-if (ac_aggr.$3)
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$4=yes"
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$5
-int
-main ()
-{
-static $2 ac_aggr;
-if (sizeof ac_aggr.$3)
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$4=yes"
-else
-  eval "$4=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$4
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_member
-
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  as_decl_name=`echo $2|sed 's/ *(.*//'`
-  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-#ifndef $as_decl_name
-#ifdef __cplusplus
-  (void) $as_decl_use;
-#else
-  (void) $as_decl_name;
-#endif
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_decl
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by Haskell time package $as_me 1.10, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
-
-/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
-/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
-/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
-  done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
-  for ac_arg
-  do
-    case $ac_arg in
-    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-    | -silent | --silent | --silen | --sile | --sil)
-      continue ;;
-    *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    case $ac_pass in
-    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
-    2)
-      as_fn_append ac_configure_args1 " '$ac_arg'"
-      if test $ac_must_keep_next = true; then
-	ac_must_keep_next=false # Got value, back to normal.
-      else
-	case $ac_arg in
-	  *=* | --config-cache | -C | -disable-* | --disable-* \
-	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-	  | -with-* | --with-* | -without-* | --without-* | --x)
-	    case "$ac_configure_args0 " in
-	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-	    esac
-	    ;;
-	  -* ) ac_must_keep_next=true ;;
-	esac
-      fi
-      as_fn_append ac_configure_args " '$ac_arg'"
-      ;;
-    esac
-  done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
-  {
-    echo
-
-    $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
-    echo
-    # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-  (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      sed -n \
-	"s/'\''/'\''\\\\'\'''\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
-    *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-)
-    echo
-
-    $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
-    echo
-    for ac_var in $ac_subst_vars
-    do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      $as_echo "$ac_var='\''$ac_val'\''"
-    done | sort
-    echo
-
-    if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
-      echo
-      for ac_var in $ac_subst_files
-      do
-	eval ac_val=\$$ac_var
-	case $ac_val in
-	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-	esac
-	$as_echo "$ac_var='\''$ac_val'\''"
-      done | sort
-      echo
-    fi
-
-    if test -s confdefs.h; then
-      $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
-      echo
-      cat confdefs.h
-      echo
-    fi
-    test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
-  } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
-    exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
-elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
-else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
-    sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
-  fi
-done
-
-if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special files
-  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
-  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
-    case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
-    esac
-  fi
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
-  >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-	# differences in whitespace do not lead to failure.
-	ac_old_val_w=`echo x $ac_old_val`
-	ac_new_val_w=`echo x $ac_new_val`
-	if test "$ac_old_val_w" != "$ac_new_val_w"; then
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	  ac_cache_corrupted=:
-	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
-	  eval $ac_var=\$ac_old_val
-	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# Safety check: Ensure that we are in the correct source directory.
-
-
-# These are to silence warnings with older Cabal versions
-
-# Check whether --with-gcc was given.
-if test "${with_gcc+set}" = set; then :
-  withval=$with_gcc;
-fi
-
-
-# Check whether --with-compiler was given.
-if test "${with_compiler+set}" = set; then :
-  withval=$with_compiler;
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
-	;;
-    [ab].out )
-	# We found the default executable, but exeext='' is most
-	# certainly right.
-	break;;
-    *.* )
-	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-	then :; else
-	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	fi
-	# We set ac_cv_exeext here because the later test for it is not
-	# safe: cross compilers may not add the suffix if given an `-o'
-	# argument, so we may need to know it at that point already.
-	# Even if this section looks crufty: it has the advantage of
-	# actually working.
-	break;;
-    * )
-	break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
-  ac_file=''
-fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  break;;
-    * ) break;;
-  esac
-done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
-  { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-  if { ac_try='./conftest$ac_cv_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = xyes; then :
-  MINIX=yes
-else
-  MINIX=
-fi
-
-
-  if test "$MINIX" = yes; then
-
-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
-
-
-$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
-
-
-$as_echo "#define _MINIX 1" >>confdefs.h
-
-  fi
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
-$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if ${ac_cv_safe_to_define___extensions__+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#         define __EXTENSIONS__ 1
-          $ac_includes_default
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_safe_to_define___extensions__=yes
-else
-  ac_cv_safe_to_define___extensions__=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
-$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
-  test $ac_cv_safe_to_define___extensions__ = yes &&
-    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
-
-  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
-
-  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
-
-  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
-
-  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
-
-
-
-ac_config_headers="$ac_config_headers lib/include/HsTimeConfig.h"
-
-
-for ac_header in time.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
-if test "x$ac_cv_header_time_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_TIME_H 1
-_ACEOF
-
-fi
-
-done
-
-for ac_func in gmtime_r localtime_r
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-for ac_func in clock_gettime
-do :
-  ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
-if test "x$ac_cv_func_clock_gettime" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_CLOCK_GETTIME 1
-_ACEOF
-
-fi
-done
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
-$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
-if ${ac_cv_struct_tm+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <time.h>
-
-int
-main ()
-{
-struct tm tm;
-				     int *p = &tm.tm_sec;
-				     return !p;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_struct_tm=time.h
-else
-  ac_cv_struct_tm=sys/time.h
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
-$as_echo "$ac_cv_struct_tm" >&6; }
-if test $ac_cv_struct_tm = sys/time.h; then
-
-$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
-
-fi
-
-ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h>
-#include <$ac_cv_struct_tm>
-
-"
-if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_TM_TM_ZONE 1
-_ACEOF
-
-
-fi
-
-if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
-
-$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h
-
-else
-  ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h>
-"
-if test "x$ac_cv_have_decl_tzname" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_TZNAME $ac_have_decl
-_ACEOF
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5
-$as_echo_n "checking for tzname... " >&6; }
-if ${ac_cv_var_tzname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <time.h>
-#if !HAVE_DECL_TZNAME
-extern char *tzname[];
-#endif
-
-int
-main ()
-{
-return tzname[0][0];
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_var_tzname=yes
-else
-  ac_cv_var_tzname=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5
-$as_echo "$ac_cv_var_tzname" >&6; }
-  if test $ac_cv_var_tzname = yes; then
-
-$as_echo "#define HAVE_TZNAME 1" >>confdefs.h
-
-  fi
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-int
-main ()
-{
-if ((struct tm *) 0)
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_time=yes
-else
-  ac_cv_header_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
-
-fi
-
-for ac_header in sys/time.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_time_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SYS_TIME_H 1
-_ACEOF
-
-fi
-
-done
-
-ac_fn_c_check_decl "$LINENO" "altzone" "ac_cv_have_decl_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
-"
-if test "x$ac_cv_have_decl_altzone" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ALTZONE $ac_have_decl
-_ACEOF
-
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems.  If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-
-  (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes: double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \.
-      sed -n \
-	"s/'/'\\\\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-) |
-  sed '
-     /^ac_cv_env_/b end
-     t clear
-     :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
-     t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
-      if test ! -f "$cache_file" || test -h "$cache_file"; then
-	cat confcache >"$cache_file"
-      else
-        case $cache_file in #(
-        */* | ?:*)
-	  mv -f confcache "$cache_file"$$ &&
-	  mv -f "$cache_file"$$ "$cache_file" ;; #(
-        *)
-	  mv -f confcache "$cache_file" ;;
-	esac
-      fi
-    fi
-  else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
-  fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
-  # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: "${CONFIG_STATUS=./config.status}"
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by Haskell time package $as_me 1.10, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  CONFIG_FILES    = $CONFIG_FILES
-  CONFIG_HEADERS  = $CONFIG_HEADERS
-  CONFIG_LINKS    = $CONFIG_LINKS
-  CONFIG_COMMANDS = $CONFIG_COMMANDS
-  $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_headers="$ac_config_headers"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration.  Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
-  -h, --help       print this help, then exit
-  -V, --version    print version number and configuration settings, then exit
-      --config     print configuration, then exit
-  -q, --quiet, --silent
-                   do not print progress messages
-  -d, --debug      don't remove temporary files
-      --recheck    update $as_me by reconfiguring in the same conditions
-      --header=FILE[:TEMPLATE]
-                   instantiate the configuration header FILE
-
-Configuration headers:
-$config_headers
-
-Report bugs to <ashley@semantic.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-Haskell time package config.status 1.10
-configured by $0, generated by GNU Autoconf 2.69,
-  with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
-  case $1 in
-  --*=?*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
-    ac_shift=:
-    ;;
-  --*=)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=
-    ac_shift=:
-    ;;
-  *)
-    ac_option=$1
-    ac_optarg=$2
-    ac_shift=shift
-    ;;
-  esac
-
-  case $ac_option in
-  # Handling of the options.
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
-  --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
-    debug=: ;;
-  --header | --heade | --head | --hea )
-    $ac_shift
-    case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
-    ac_need_defaults=false;;
-  --he | --h)
-    # Conflict between --help and --header
-    as_fn_error $? "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
-  --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil | --si | --s)
-    ac_cs_silent=: ;;
-
-  # This is an error.
-  -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
-  *) as_fn_append ac_config_targets " $1"
-     ac_need_defaults=false ;;
-
-  esac
-  shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
-  exec 6>/dev/null
-  ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
-  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-  shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
-  CONFIG_SHELL='$SHELL'
-  export CONFIG_SHELL
-  exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
-  case $ac_config_target in
-    "lib/include/HsTimeConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/include/HsTimeConfig.h" ;;
-
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
-  esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used.  Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-fi
-
-# Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
-  tmp= ac_tmp=
-  trap 'exit_status=$?
-  : "${ac_tmp:=$tmp}"
-  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
-' 0
-  trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -d "$tmp"
-}  ||
-{
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
-  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_tt"; then
-    break
-  elif $ac_last_try; then
-    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
-  fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any.  Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-  for (key in D) D_is_set[key] = 1
-  FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
-  line = \$ 0
-  split(line, arg, " ")
-  if (arg[1] == "#") {
-    defundef = arg[2]
-    mac1 = arg[3]
-  } else {
-    defundef = substr(arg[1], 2)
-    mac1 = arg[2]
-  }
-  split(mac1, mac2, "(") #)
-  macro = mac2[1]
-  prefix = substr(line, 1, index(line, defundef) - 1)
-  if (D_is_set[macro]) {
-    # Preserve the white space surrounding the "#".
-    print prefix "define", macro P[macro] D[macro]
-    next
-  } else {
-    # Replace #undef with comments.  This is necessary, for example,
-    # in the case of _POSIX_SOURCE, which is predefined and required
-    # on some systems where configure will not decide to define it.
-    if (defundef == "undef") {
-      print "/*", prefix defundef, macro, "*/"
-      next
-    }
-  }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X "    :H $CONFIG_HEADERS    "
-shift
-for ac_tag
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$ac_tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
-	 # because $ac_f cannot contain `:'.
-	 test -f "$ac_f" ||
-	   case $ac_f in
-	   [\\/$]*) false;;
-	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
-      esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
-      as_fn_append ac_file_inputs " '$ac_f'"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input='Generated from '`
-	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
-	`' by configure.'
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
-    fi
-    # Neutralize special characters interpreted by sed in replacement strings.
-    case $configure_input in #(
-    *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
-       sed 's/[\\\\&|]/\\\\&/g'`;; #(
-    *) ac_sed_conf_input=$configure_input;;
-    esac
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
-    esac
-    ;;
-  esac
-
-  ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_file" : 'X\(//\)[^/]' \| \
-	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  as_dir="$ac_dir"; as_fn_mkdir_p
-  ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
-  case $ac_mode in
-
-  :H)
-  #
-  # CONFIG_HEADER
-  #
-  if test x"$ac_file" != x-; then
-    {
-      $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
-    } >"$ac_tmp/config.h" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
-    else
-      rm -f "$ac_file"
-      mv "$ac_tmp/config.h" "$ac_file" \
-	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    fi
-  else
-    $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error $? "could not create -" "$LINENO" 5
-  fi
- ;;
-
-
-  esac
-
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
-  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded.  So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status.  When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
-  ac_cs_success=:
-  ac_config_status_args=
-  test "$silent" = yes &&
-    ac_config_status_args="$ac_config_status_args --quiet"
-  exec 5>/dev/null
-  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
-  exec 5>>config.log
-  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
-  # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
+# Generated by GNU Autoconf 2.71 for Haskell time package 1.16.
+#
+# Report bugs to <ashley@semantic.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else \$as_nop
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
+
+else \$as_nop
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null
+then :
+  as_have_required=yes
+else $as_nop
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
+
+else $as_nop
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
+
+
+      if test "x$CONFIG_SHELL" != x
+then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
+$0: ashley@semantic.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Haskell time package'
+PACKAGE_TARNAME='time'
+PACKAGE_VERSION='1.16'
+PACKAGE_STRING='Haskell time package 1.16'
+PACKAGE_BUGREPORT='ashley@semantic.org'
+PACKAGE_URL=''
+
+ac_unique_file="lib/include/HsTime.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_c_list=
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_gcc
+with_compiler
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Haskell time package 1.16 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/time]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Haskell time package 1.16:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+Gnu C compiler
+Haskell compiler
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <ashley@semantic.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Haskell time package configure 1.16
+generated by GNU Autoconf 2.71
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+   which can conflict with char $2 (); below.  */
+
+#include <limits.h>
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main (void)
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+printf %s "checking for $2.$3... " >&6; }
+if eval test \${$4+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main (void)
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$4=yes"
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main (void)
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$4=yes"
+else $as_nop
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR
+# ------------------------------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR.
+ac_fn_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+printf %s "checking whether $as_decl_name is declared... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  eval ac_save_FLAGS=\$$6
+  as_fn_append $6 " $5"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  eval $6=\$ac_save_FLAGS
+
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_check_decl
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Haskell time package $as_me 1.16, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  $ $0$ac_configure_args_raw
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""	$as_nl"
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    printf "%s\n" "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    printf "%s\n" "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      printf "%s\n" "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	printf "%s\n" "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      printf "%s\n" "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+printf "%s\n" "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  ac_site_files="$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+else
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+fi
+
+for ac_site_file in $ac_site_files
+do
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case '\''s'\'': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case '\''d'\'': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case '\''f'\'': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+
+  return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+	 || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+		   == offsetof (struct anonymous, w.k)),
+		  "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H"
+as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H"
+as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+	    and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Safety check: Ensure that we are in the correct source directory.
+
+
+# These are to silence warnings with older Cabal versions
+
+# Check whether --with-gcc was given.
+if test ${with_gcc+y}
+then :
+  withval=$with_gcc;
+fi
+
+
+# Check whether --with-compiler was given.
+if test ${with_compiler+y}
+then :
+  withval=$with_compiler;
+fi
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else $as_nop
+  ac_file=''
+fi
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main (void)
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+y}
+ac_save_CFLAGS=$CFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+else $as_nop
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
+do
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
+  fi
+done
+
+
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test ${ac_cv_safe_to_define___extensions__+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_safe_to_define___extensions__=yes
+else $as_nop
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; }
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5
+printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; }
+if test ${ac_cv_should_define__xopen_source+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_should_define__xopen_source=no
+    if test $ac_cv_header_wchar_h = yes
+then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #include <wchar.h>
+          mbstate_t x;
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+            #define _XOPEN_SOURCE 500
+            #include <wchar.h>
+            mbstate_t x;
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_should_define__xopen_source=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5
+printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; }
+
+  printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h
+
+  printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h
+
+  printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h
+
+  printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h
+
+  printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+  if test $ac_cv_header_minix_config_h = yes
+then :
+  MINIX=yes
+    printf "%s\n" "#define _MINIX 1" >>confdefs.h
+
+    printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h
+
+    printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+else $as_nop
+  MINIX=
+fi
+  if test $ac_cv_safe_to_define___extensions__ = yes
+then :
+  printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h
+
+fi
+  if test $ac_cv_should_define__xopen_source = yes
+then :
+  printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h
+
+fi
+
+
+ac_config_headers="$ac_config_headers lib/include/HsTimeConfig.h"
+
+
+ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r"
+if test "x$ac_cv_func_gmtime_r" = xyes
+then :
+  printf "%s\n" "#define HAVE_GMTIME_R 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
+if test "x$ac_cv_func_localtime_r" = xyes
+then :
+  printf "%s\n" "#define HAVE_LOCALTIME_R 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes
+then :
+  printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "tzset" "ac_cv_func_tzset"
+if test "x$ac_cv_func_tzset" = xyes
+then :
+  printf "%s\n" "#define HAVE_TZSET 1" >>confdefs.h
+
+fi
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+printf %s "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if test ${ac_cv_struct_tm+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main (void)
+{
+struct tm tm;
+				     int *p = &tm.tm_sec;
+				     return !p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_struct_tm=time.h
+else $as_nop
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+printf "%s\n" "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+printf "%s\n" "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5
+printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; }
+if test ${ac_cv_c_undeclared_builtin_options+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CFLAGS=$CFLAGS
+   ac_cv_c_undeclared_builtin_options='cannot detect'
+   for ac_arg in '' -fno-builtin; do
+     CFLAGS="$ac_save_CFLAGS $ac_arg"
+     # This test program should *not* compile successfully.
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+(void) strchr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  # This test program should compile successfully.
+        # No library function is consistently available on
+        # freestanding implementations, so test against a dummy
+        # declaration.  Include always-available headers on the
+        # off chance that they somehow elicit warnings.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <float.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+extern void ac_decl (int, char *);
+
+int
+main (void)
+{
+(void) ac_decl (0, (char *) 0);
+  (void) ac_decl;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  if test x"$ac_arg" = x
+then :
+  ac_cv_c_undeclared_builtin_options='none needed'
+else $as_nop
+  ac_cv_c_undeclared_builtin_options=$ac_arg
+fi
+          break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    done
+    CFLAGS=$ac_save_CFLAGS
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5
+printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; }
+  case $ac_cv_c_undeclared_builtin_options in #(
+  'cannot detect') :
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot make $CC report undeclared builtins
+See \`config.log' for more details" "$LINENO" 5; } ;; #(
+  'none needed') :
+    ac_c_undeclared_builtin_options='' ;; #(
+  *) :
+    ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;;
+esac
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+"
+if test "x$ac_cv_member_struct_tm_tm_zone" = xyes
+then :
+
+printf "%s\n" "#define HAVE_STRUCT_TM_TM_ZONE 1" >>confdefs.h
+
+
+fi
+
+if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
+
+printf "%s\n" "#define HAVE_TM_ZONE 1" >>confdefs.h
+
+else
+  ac_fn_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h>
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_tzname" = xyes
+then :
+  ac_have_decl=1
+else $as_nop
+  ac_have_decl=0
+fi
+printf "%s\n" "#define HAVE_DECL_TZNAME $ac_have_decl" >>confdefs.h
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5
+printf %s "checking for tzname... " >&6; }
+if test ${ac_cv_var_tzname+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <time.h>
+#if !HAVE_DECL_TZNAME
+extern char *tzname[];
+#endif
+
+int
+main (void)
+{
+return tzname[0][0];
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_var_tzname=yes
+else $as_nop
+  ac_cv_var_tzname=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5
+printf "%s\n" "$ac_cv_var_tzname" >&6; }
+  if test $ac_cv_var_tzname = yes; then
+
+printf "%s\n" "#define HAVE_TZNAME 1" >>confdefs.h
+
+  fi
+fi
+
+
+
+
+
+
+  ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h
+
+fi
+
+  ac_fn_check_decl "$LINENO" "altzone" "ac_cv_have_decl_altzone" "
+  #if HAVE_SYS_TIME_H
+  #include <sys/time.h>
+  #endif
+  #include <time.h>
+
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_altzone" = xyes
+then :
+  ac_have_decl=1
+else $as_nop
+  ac_have_decl=0
+fi
+printf "%s\n" "#define HAVE_DECL_ALTZONE $ac_have_decl" >>confdefs.h
+
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Haskell time package $as_me 1.16, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration headers:
+$config_headers
+
+Report bugs to <ashley@semantic.org>."
+
+_ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config='$ac_cs_config_escaped'
+ac_cs_version="\\
+Haskell time package config.status 1.16
+configured by $0, generated by GNU Autoconf 2.71,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    printf "%s\n" "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    printf "%s\n" "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    printf "%s\n" "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  printf "%s\n" "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "lib/include/HsTimeConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/include/HsTimeConfig.h" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "    :H $CONFIG_HEADERS    "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([Haskell time package], [1.10], [ashley@semantic.org], [time])
+AC_INIT([Haskell time package],[1.16],[ashley@semantic.org],[time])
 
 # Safety check: Ensure that we are in the correct source directory.
 AC_CONFIG_SRCDIR([lib/include/HsTime.h])
@@ -17,6 +17,7 @@
 AC_CHECK_FUNCS([gmtime_r localtime_r])
 
 AC_CHECK_FUNCS([clock_gettime])
+AC_CHECK_FUNCS([tzset])
 
 AC_STRUCT_TM
 AC_STRUCT_TIMEZONE
diff --git a/lib/Data/Format.hs b/lib/Data/Format.hs
--- a/lib/Data/Format.hs
+++ b/lib/Data/Format.hs
@@ -1,32 +1,35 @@
-module Data.Format
-    ( Productish(..)
-    , Summish(..)
-    , parseReader
-    , Format(..)
-    , formatShow
-    , formatParseM
-    , isoMap
-    , mapMFormat
-    , filterFormat
-    , clipFormat
-    , enumMap
-    , literalFormat
-    , specialCaseShowFormat
-    , specialCaseFormat
-    , optionalFormat
-    , casesFormat
-    , optionalSignFormat
-    , mandatorySignFormat
-    , SignOption(..)
-    , integerFormat
-    , decimalFormat
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Format (
+    Productish (..),
+    Summish (..),
+    parseReader,
+    Format (..),
+    formatShow,
+    formatParseM,
+    isoMap,
+    mapMFormat,
+    filterFormat,
+    clipFormat,
+    enumMap,
+    literalFormat,
+    specialCaseShowFormat,
+    specialCaseFormat,
+    specialCaseReadFormat,
+    optionalFormat,
+    casesFormat,
+    optionalSignFormat,
+    mandatorySignFormat,
+    SignOption (..),
+    integerFormat,
+    decimalFormat,
+) where
+
 import Control.Monad.Fail
 import Data.Char
 import Data.Void
-import Prelude hiding (fail)
 import Text.ParserCombinators.ReadP
+import Prelude hiding (fail)
 
 class IsoVariant f where
     isoMap :: (a -> b) -> (b -> a) -> f a -> f b
@@ -50,7 +53,7 @@
     pVoid :: f Void
     (<++>) :: f a -> f b -> f (Either a b)
 
-parseReader :: (MonadFail m) => ReadP t -> String -> m t
+parseReader :: MonadFail m => ReadP t -> String -> m t
 parseReader readp s =
     case [t | (t, "") <- readP_to_S readp s] of
         [t] -> return t
@@ -60,9 +63,9 @@
 -- | A text format for a type
 data Format t = MkFormat
     { formatShowM :: t -> Maybe String
-        -- ^ Show a value in the format, if representable
+    -- ^ Show a value in the format, if representable
     , formatReadP :: ReadP t
-        -- ^ Read a value in the format
+    -- ^ Read a value in the format
     }
 
 -- | Show a value in the format, or error if unrepresentable
@@ -73,7 +76,7 @@
         Nothing -> error "formatShow: bad value"
 
 -- | Parse a value in the format
-formatParseM :: (MonadFail m) => Format t -> String -> m t
+formatParseM :: MonadFail m => Format t -> String -> m t
 formatParseM format = parseReader $ formatReadP format
 
 instance IsoVariant Format where
@@ -90,86 +93,109 @@
 filterFormat :: (a -> Bool) -> Format a -> Format a
 filterFormat test =
     mapMFormat
-        (\a ->
-             if test a
-                 then Just a
-                 else Nothing)
-        (\a ->
-             if test a
-                 then Just a
-                 else Nothing)
+        ( \a ->
+            if test a
+                then Just a
+                else Nothing
+        )
+        ( \a ->
+            if test a
+                then Just a
+                else Nothing
+        )
 
 -- | Limits are inclusive
 clipFormat :: Ord a => (a, a) -> Format a -> Format a
 clipFormat (lo, hi) = filterFormat (\a -> a >= lo && a <= hi)
 
 instance Productish Format where
-    pUnit = MkFormat {formatShowM = \_ -> Just "", formatReadP = return ()}
-    (<**>) (MkFormat sa ra) (MkFormat sb rb) = let
-        sab (a, b) = do
-            astr <- sa a
-            bstr <- sb b
-            return $ astr ++ bstr
-        rab = do
-            a <- ra
-            b <- rb
-            return (a, b)
-        in MkFormat sab rab
-    (MkFormat sa ra) **> (MkFormat sb rb) = let
-        s b = do
-            astr <- sa ()
-            bstr <- sb b
-            return $ astr ++ bstr
-        r = do
-            ra
-            rb
-        in MkFormat s r
-    (MkFormat sa ra) <** (MkFormat sb rb) = let
-        s a = do
-            astr <- sa a
-            bstr <- sb ()
-            return $ astr ++ bstr
-        r = do
-            a <- ra
-            rb
-            return a
-        in MkFormat s r
+    pUnit = MkFormat{formatShowM = \_ -> Just "", formatReadP = return ()}
+    (<**>) (MkFormat sa ra) (MkFormat sb rb) =
+        let
+            sab (a, b) = do
+                astr <- sa a
+                bstr <- sb b
+                return $ astr ++ bstr
+            rab = do
+                a <- ra
+                b <- rb
+                return (a, b)
+        in
+            MkFormat sab rab
+    (MkFormat sa ra) **> (MkFormat sb rb) =
+        let
+            s b = do
+                astr <- sa ()
+                bstr <- sb b
+                return $ astr ++ bstr
+            r = do
+                ra
+                rb
+        in
+            MkFormat s r
+    (MkFormat sa ra) <** (MkFormat sb rb) =
+        let
+            s a = do
+                astr <- sa a
+                bstr <- sb ()
+                return $ astr ++ bstr
+            r = do
+                a <- ra
+                rb
+                return a
+        in
+            MkFormat s r
 
 instance Summish Format where
     pVoid = MkFormat absurd pfail
-    (MkFormat sa ra) <++> (MkFormat sb rb) = let
-        sab (Left a) = sa a
-        sab (Right b) = sb b
-        rab = (fmap Left ra) +++ (fmap Right rb)
-        in MkFormat sab rab
+    (MkFormat sa ra) <++> (MkFormat sb rb) =
+        let
+            sab (Left a) = sa a
+            sab (Right b) = sb b
+            rab = (fmap Left ra) +++ (fmap Right rb)
+        in
+            MkFormat sab rab
 
 literalFormat :: String -> Format ()
-literalFormat s = MkFormat {formatShowM = \_ -> Just s, formatReadP = string s >> return ()}
+literalFormat s = MkFormat{formatShowM = \_ -> Just s, formatReadP = string s >> return ()}
 
 specialCaseShowFormat :: Eq a => (a, String) -> Format a -> Format a
-specialCaseShowFormat (val, str) (MkFormat s r) = let
-    s' t
-        | t == val = Just str
-    s' t = s t
-    in MkFormat s' r
+specialCaseShowFormat (val, str) (MkFormat s r) =
+    let
+        s' t
+            | t == val = Just str
+        s' t = s t
+    in
+        MkFormat s' r
 
 specialCaseFormat :: Eq a => (a, String) -> Format a -> Format a
-specialCaseFormat (val, str) (MkFormat s r) = let
-    s' t
-        | t == val = Just str
-    s' t = s t
-    r' = (string str >> return val) +++ r
-    in MkFormat s' r'
+specialCaseFormat (val, str) (MkFormat s r) =
+    let
+        s' t
+            | t == val = Just str
+        s' t = s t
+        r' = r <++ (string str >> return val)
+    in
+        MkFormat s' r'
 
+specialCaseReadFormat :: (a, String) -> Format a -> Format a
+specialCaseReadFormat (val, str) (MkFormat s r) =
+    let
+        r' = r <++ (string str >> return val)
+    in
+        MkFormat s r'
+
 optionalFormat :: Eq a => a -> Format a -> Format a
 optionalFormat val = specialCaseFormat (val, "")
 
 casesFormat :: Eq a => [(a, String)] -> Format a
-casesFormat pairs = let
-    s t = lookup t pairs
-    r [] = pfail
-    r ((v, str):pp) = (string str >> return v) <++ r pp
-    in MkFormat s $ r pairs
+casesFormat pairs =
+    let
+        s t = lookup t pairs
+        r [] = pfail
+        r ((v, str) : pp) = (string str >> return v) <++ r pp
+    in
+        MkFormat s $ r pairs
 
 optionalSignFormat :: (Eq t, Num t) => Format t
 optionalSignFormat = casesFormat [(1, ""), (1, "+"), (0, ""), (-1, "-")]
@@ -193,43 +219,55 @@
     digits <-
         case mdigitcount of
             Just digitcount -> count digitcount $ satisfy isDigit
-            Nothing -> many1 $ satisfy isDigit
+            Nothing -> munch1 isDigit
     moredigits <-
         case allowDecimal of
             False -> return ""
             True ->
                 option "" $ do
                     _ <- char '.' +++ char ','
-                    dd <- many1 (satisfy isDigit)
+                    dd <- munch1 isDigit
                     return $ '.' : dd
     return $ sign $ read $ digits ++ moredigits
 
-zeroPad :: Maybe Int -> String -> String
-zeroPad Nothing s = s
-zeroPad (Just i) s = replicate (i - length s) '0' ++ s
+zeroPad :: Maybe Int -> String -> Maybe String
+zeroPad Nothing s = Just s
+zeroPad (Just i) s =
+    let
+        padCount = i - length s
+    in
+        if padCount >= 0
+            then Just $ replicate padCount '0' ++ s
+            else Nothing
 
 trimTrailing :: String -> String
-trimTrailing "" = ""
-trimTrailing "." = ""
-trimTrailing s
-    | last s == '0' = trimTrailing $ init s
-trimTrailing s = s
+trimTrailing =
+    (\s -> if s == "." then "" else s)
+        . reverse
+        . dropWhile (== '0')
+        . reverse
 
 showNumber :: Show t => SignOption -> Maybe Int -> t -> Maybe String
-showNumber signOpt mdigitcount t = let
-    showIt str = let
-        (intPart, decPart) = break ((==) '.') str
-        in (zeroPad mdigitcount intPart) ++ trimTrailing decPart
-    in case show t of
-           ('-':str) ->
-               case signOpt of
-                   NoSign -> Nothing
-                   _ -> Just $ '-' : showIt str
-           str ->
-               Just $
-               case signOpt of
-                   PosNegSign -> '+' : showIt str
-                   _ -> showIt str
+showNumber signOpt mdigitcount t =
+    let
+        showIt str = do
+            let
+                (intPart, decPart) = break ((==) '.') str
+            paddedIntPart <- zeroPad mdigitcount intPart
+            return $ paddedIntPart ++ trimTrailing decPart
+    in
+        case show t of
+            ('-' : str) ->
+                case signOpt of
+                    NoSign -> Nothing
+                    _ -> do
+                        s <- showIt str
+                        return $ '-' : s
+            str -> do
+                s <- showIt str
+                return $ case signOpt of
+                    PosNegSign -> '+' : s
+                    _ -> s
 
 integerFormat :: (Show t, Read t, Num t) => SignOption -> Maybe Int -> Format t
 integerFormat signOpt mdigitcount = MkFormat (showNumber signOpt mdigitcount) (readNumber signOpt mdigitcount False)
diff --git a/lib/Data/Time.hs b/lib/Data/Time.hs
--- a/lib/Data/Time.hs
+++ b/lib/Data/Time.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE Safe #-}
+
 {-|
 
 = Quick Start
@@ -11,6 +13,9 @@
 
 * 'Day' for something like June 27th 2017
 * 'DayOfWeek' for something like Tuesday
+* 'Data.Time.Calendar.Month.Month' for something like August 2021
+* 'Data.Time.Calendar.Quarter.QuarterOfYear' for something like Q2
+* 'Data.Time.Calendar.Quarter.Quarter' for something like Q2 of 2023
 * 'TimeOfDay' for something like 5pm
 * 'LocalTime' for a 'Day' with a 'TimeOfDay'
 * 'TimeZone' for a time zone offset (not actually the time zone itself) like -0700
diff --git a/lib/Data/Time/Calendar.hs b/lib/Data/Time/Calendar.hs
--- a/lib/Data/Time/Calendar.hs
+++ b/lib/Data/Time/Calendar.hs
@@ -1,12 +1,78 @@
-module Data.Time.Calendar
-    ( module Data.Time.Calendar.Days
-    , module Data.Time.Calendar.CalendarDiffDays
-    , module Data.Time.Calendar.Gregorian
-    , module Data.Time.Calendar.Week
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Calendar (
+    -- * Days
+    Day (..),
+    addDays,
+    diffDays,
+
+    -- * DayPeriod
+    DayPeriod (..),
+    periodAllDays,
+    periodIn,
+    periodLength,
+    periodFromDay,
+    periodToDay,
+    periodToDayClip,
+    periodToDayValid,
+
+    -- * Calendar Duration
+    module Data.Time.Calendar.CalendarDiffDays,
+
+    -- * Year, month and day
+    Year,
+    pattern CommonEra,
+    pattern BeforeCommonEra,
+    MonthOfYear,
+    pattern January,
+    pattern February,
+    pattern March,
+    pattern April,
+    pattern May,
+    pattern June,
+    pattern July,
+    pattern August,
+    pattern September,
+    pattern October,
+    pattern November,
+    pattern December,
+    DayOfMonth,
+
+    -- * Gregorian calendar
+    toGregorian,
+    fromGregorian,
+    pattern YearMonthDay,
+    fromGregorianValid,
+    showGregorian,
+    gregorianMonthLength,
+    -- calendrical arithmetic
+    -- e.g. "one month after March 31st"
+    addGregorianMonthsClip,
+    addGregorianMonthsRollOver,
+    addGregorianYearsClip,
+    addGregorianYearsRollOver,
+    addGregorianDurationClip,
+    addGregorianDurationRollOver,
+    diffGregorianDurationClip,
+    diffGregorianDurationRollOver,
+    -- re-exported from OrdinalDate
+    isLeapYear,
+
+    -- * Week
+    DayOfWeek (..),
+    dayOfWeek,
+    dayOfWeekDiff,
+    firstDayOfWeekOnAfter,
+    weekAllDays,
+    weekFirstDay,
+    weekLastDay,
+) where
+
 import Data.Time.Calendar.CalendarDiffDays
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.Gregorian
+import Data.Time.Calendar.MonthDay
+import Data.Time.Calendar.OrdinalDate
+import Data.Time.Calendar.Types
 import Data.Time.Calendar.Week
 import Data.Time.Format ()
diff --git a/lib/Data/Time/Calendar/CalendarDiffDays.hs b/lib/Data/Time/Calendar/CalendarDiffDays.hs
--- a/lib/Data/Time/Calendar/CalendarDiffDays.hs
+++ b/lib/Data/Time/Calendar/CalendarDiffDays.hs
@@ -1,30 +1,26 @@
-module Data.Time.Calendar.CalendarDiffDays
-    (
-        -- * Calendar Duration
-        module Data.Time.Calendar.CalendarDiffDays
-    ) where
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
-#if MIN_VERSION_base(4,11,0)
+module Data.Time.Calendar.CalendarDiffDays where
+
+import Control.DeepSeq
+import Data.Data
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
 #else
-import Data.Semigroup hiding (option)
+import qualified Language.Haskell.TH.Syntax as TH
 #endif
-import Data.Typeable
-import Data.Data
 
 data CalendarDiffDays = CalendarDiffDays
     { cdMonths :: Integer
     , cdDays :: Integer
-    } deriving (Eq,
-    Data
-#if __GLASGOW_HASKELL__ >= 802
-    -- ^ @since 1.9.2
-#endif
-    ,Typeable
-#if __GLASGOW_HASKELL__ >= 802
-    -- ^ @since 1.9.2
-#endif
-    )
+    }
+    deriving (Eq, Typeable, Data, Generic, TH.Lift)
 
+instance NFData CalendarDiffDays where
+    rnf (CalendarDiffDays m d) = rnf m `seq` rnf d `seq` ()
+
 -- | Additive
 instance Semigroup CalendarDiffDays where
     CalendarDiffDays m1 d1 <> CalendarDiffDays m2 d2 = CalendarDiffDays (m1 + m2) (d1 + d2)
@@ -33,9 +29,6 @@
 instance Monoid CalendarDiffDays where
     mempty = CalendarDiffDays 0 0
     mappend = (<>)
-
-instance Show CalendarDiffDays where
-    show (CalendarDiffDays m d) = "P" ++ show m ++ "M" ++ show d ++ "D"
 
 calendarDay :: CalendarDiffDays
 calendarDay = CalendarDiffDays 0 1
diff --git a/lib/Data/Time/Calendar/Days.hs b/lib/Data/Time/Calendar/Days.hs
--- a/lib/Data/Time/Calendar/Days.hs
+++ b/lib/Data/Time/Calendar/Days.hs
@@ -1,27 +1,28 @@
-{-# OPTIONS -fno-warn-unused-imports #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
-module Data.Time.Calendar.Days
-    (
-    -- * Days
-      Day(..)
-    , addDays
-    , diffDays
-    ) where
+module Data.Time.Calendar.Days where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Ix
-import Data.Typeable
+import Data.Time.Calendar.Private
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | The Modified Julian Day is a standard count of days, with zero being the day 1858-11-17.
 newtype Day = ModifiedJulianDay
     { toModifiedJulianDay :: Integer
-    } deriving (Eq, Ord, Data, Typeable)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
 instance NFData Day where
     rnf (ModifiedJulianDay a) = rnf a
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Enum Day where
     succ (ModifiedJulianDay a) = ModifiedJulianDay (succ a)
     pred (ModifiedJulianDay a) = ModifiedJulianDay (pred a)
@@ -33,7 +34,6 @@
     enumFromThenTo (ModifiedJulianDay a) (ModifiedJulianDay b) (ModifiedJulianDay c) =
         fmap ModifiedJulianDay (enumFromThenTo a b c)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Ix Day where
     range (ModifiedJulianDay a, ModifiedJulianDay b) = fmap ModifiedJulianDay (range (a, b))
     index (ModifiedJulianDay a, ModifiedJulianDay b) (ModifiedJulianDay c) = index (a, b) c
@@ -45,3 +45,74 @@
 
 diffDays :: Day -> Day -> Integer
 diffDays (ModifiedJulianDay a) (ModifiedJulianDay b) = a - b
+
+-- | The class of types which can be represented as a period of days.
+--
+-- @since 1.12.1
+class Ord p => DayPeriod p where
+    -- | Returns the first 'Day' in a period of days.
+    periodFirstDay :: p -> Day
+
+    -- | Returns the last 'Day' in a period of days.
+    periodLastDay :: p -> Day
+
+    -- | Get the period this day is in.
+    dayPeriod :: Day -> p
+
+-- | A list of all the days in this period.
+--
+-- @since 1.12.1
+periodAllDays :: DayPeriod p => p -> [Day]
+periodAllDays p = [periodFirstDay p .. periodLastDay p]
+
+-- | Test whether a day is in a given period.
+--
+-- @since 1.16
+periodIn :: DayPeriod p => p -> Day -> Bool
+periodIn p d = (d >= periodFirstDay p) && (d <= periodLastDay p)
+
+-- | The number of days in this period.
+--
+-- @since 1.12.1
+periodLength :: DayPeriod p => p -> Int
+periodLength p = succ $ fromInteger $ diffDays (periodLastDay p) (periodFirstDay p)
+
+-- | Get the period this day is in, with the 1-based day number within the period.
+--
+-- @periodFromDay (periodFirstDay p) = (p,1)@
+--
+-- @since 1.12.1
+periodFromDay :: DayPeriod p => Day -> (p, Int)
+periodFromDay d =
+    let
+        p = dayPeriod d
+        dt = succ $ fromInteger $ diffDays d $ periodFirstDay p
+    in
+        (p, dt)
+
+-- | Inverse of 'periodFromDay'.
+--
+-- @since 1.12.1
+periodToDay :: DayPeriod p => p -> Int -> Day
+periodToDay p i = addDays (toInteger $ pred i) $ periodFirstDay p
+
+-- | Inverse of 'periodFromDay', clipping the day number to the period.
+--
+-- @since 1.15
+periodToDayClip :: DayPeriod p => p -> Int -> Day
+periodToDayClip p i = periodToDay p $ clip 1 (periodLength p) i
+
+-- | Validating inverse of 'periodFromDay'.
+--
+-- @since 1.12.1
+periodToDayValid :: DayPeriod p => p -> Int -> Maybe Day
+periodToDayValid p i =
+    let
+        d = periodToDay p i
+    in
+        if fst (periodFromDay d) == p then Just d else Nothing
+
+instance DayPeriod Day where
+    periodFirstDay = id
+    periodLastDay = id
+    dayPeriod = id
diff --git a/lib/Data/Time/Calendar/Easter.hs b/lib/Data/Time/Calendar/Easter.hs
--- a/lib/Data/Time/Calendar/Easter.hs
+++ b/lib/Data/Time/Calendar/Easter.hs
@@ -1,11 +1,13 @@
-module Data.Time.Calendar.Easter
-    ( sundayAfter
-    , orthodoxPaschalMoon
-    , orthodoxEaster
-    , gregorianPaschalMoon
-    , gregorianEaster
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Calendar.Easter (
+    sundayAfter,
+    orthodoxPaschalMoon,
+    orthodoxEaster,
+    gregorianPaschalMoon,
+    gregorianEaster,
+) where
+
 -- formulae from Reingold & Dershowitz, _Calendrical Calculations_, ch. 8.
 import Data.Time.Calendar
 import Data.Time.Calendar.Julian
@@ -15,7 +17,7 @@
 sundayAfter day = addDays (7 - (mod (toModifiedJulianDay day + 3) 7)) day
 
 -- | Given a year, find the Paschal full moon according to Orthodox Christian tradition
-orthodoxPaschalMoon :: Integer -> Day
+orthodoxPaschalMoon :: Year -> Day
 orthodoxPaschalMoon year = addDays (-shiftedEpact) (fromJulian jyear 4 19)
   where
     shiftedEpact = mod (14 + 11 * (mod year 19)) 30
@@ -25,11 +27,11 @@
             else year - 1
 
 -- | Given a year, find Easter according to Orthodox Christian tradition
-orthodoxEaster :: Integer -> Day
+orthodoxEaster :: Year -> Day
 orthodoxEaster = sundayAfter . orthodoxPaschalMoon
 
 -- | Given a year, find the Paschal full moon according to the Gregorian method
-gregorianPaschalMoon :: Integer -> Day
+gregorianPaschalMoon :: Year -> Day
 gregorianPaschalMoon year = addDays (-adjustedEpact) (fromGregorian year 4 19)
   where
     century = (div year 100) + 1
@@ -40,5 +42,5 @@
             else shiftedEpact
 
 -- | Given a year, find Easter according to the Gregorian method
-gregorianEaster :: Integer -> Day
+gregorianEaster :: Year -> Day
 gregorianEaster = sundayAfter . gregorianPaschalMoon
diff --git a/lib/Data/Time/Calendar/Gregorian.hs b/lib/Data/Time/Calendar/Gregorian.hs
--- a/lib/Data/Time/Calendar/Gregorian.hs
+++ b/lib/Data/Time/Calendar/Gregorian.hs
@@ -1,26 +1,8 @@
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.Calendar.Gregorian
-    (
-    -- * Gregorian calendar
-      toGregorian
-    , fromGregorian
-    , fromGregorianValid
-    , showGregorian
-    , gregorianMonthLength
-    -- calendrical arithmetic
-    -- e.g. "one month after March 31st"
-    , addGregorianMonthsClip
-    , addGregorianMonthsRollOver
-    , addGregorianYearsClip
-    , addGregorianYearsRollOver
-    , addGregorianDurationClip
-    , addGregorianDurationRollOver
-    , diffGregorianDurationClip
-    , diffGregorianDurationRollOver
-    -- re-exported from OrdinalDate
-    , isLeapYear
-    ) where
+module Data.Time.Calendar.Gregorian where
 
 import Data.Time.Calendar.CalendarDiffDays
 import Data.Time.Calendar.Days
@@ -28,21 +10,31 @@
 import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.Private
 
--- | Convert to proleptic Gregorian calendar. First element of result is year, second month number (1-12), third day (1-31).
-toGregorian :: Day -> (Integer, Int, Int)
+-- | Convert to proleptic Gregorian calendar.
+toGregorian :: Day -> (Year, MonthOfYear, DayOfMonth)
 toGregorian date = (year, month, day)
   where
     (year, yd) = toOrdinalDate date
     (month, day) = dayOfYearToMonthAndDay (isLeapYear year) yd
 
--- | Convert from proleptic Gregorian calendar. First argument is year, second month number (1-12), third day (1-31).
+-- | Convert from proleptic Gregorian calendar.
 -- Invalid values will be clipped to the correct range, month first, then day.
-fromGregorian :: Integer -> Int -> Int -> Day
+fromGregorian :: Year -> MonthOfYear -> DayOfMonth -> Day
 fromGregorian year month day = fromOrdinalDate year (monthAndDayToDayOfYear (isLeapYear year) month day)
 
--- | Convert from proleptic Gregorian calendar. First argument is year, second month number (1-12), third day (1-31).
+-- | Bidirectional abstract constructor for the proleptic Gregorian calendar.
+-- Invalid values will be clipped to the correct range, month first, then day.
+pattern YearMonthDay :: Year -> MonthOfYear -> DayOfMonth -> Day
+pattern YearMonthDay y m d <-
+    (toGregorian -> (y, m, d))
+    where
+        YearMonthDay y m d = fromGregorian y m d
+
+{-# COMPLETE YearMonthDay #-}
+
+-- | Convert from proleptic Gregorian calendar.
 -- Invalid values will return Nothing
-fromGregorianValid :: Integer -> Int -> Int -> Maybe Day
+fromGregorianValid :: Year -> MonthOfYear -> DayOfMonth -> Maybe Day
 fromGregorianValid year month day = do
     doy <- monthAndDayToDayOfYearValid (isLeapYear year) month day
     fromOrdinalDateValid year doy
@@ -53,14 +45,14 @@
   where
     (y, m, d) = toGregorian date
 
--- | The number of days in a given month according to the proleptic Gregorian calendar. First argument is year, second is month.
-gregorianMonthLength :: Integer -> Int -> Int
+-- | The number of days in a given month according to the proleptic Gregorian calendar.
+gregorianMonthLength :: Year -> MonthOfYear -> DayOfMonth
 gregorianMonthLength year = monthLength (isLeapYear year)
 
-rolloverMonths :: (Integer, Integer) -> (Integer, Int)
+rolloverMonths :: (Year, Integer) -> (Year, MonthOfYear)
 rolloverMonths (y, m) = (y + (div (m - 1) 12), fromIntegral (mod (m - 1) 12) + 1)
 
-addGregorianMonths :: Integer -> Day -> (Integer, Int, Int)
+addGregorianMonths :: Integer -> Day -> (Year, MonthOfYear, DayOfMonth)
 addGregorianMonths n day = (y', m', d)
   where
     (y, m, d) = toGregorian day
@@ -98,45 +90,65 @@
 addGregorianDurationRollOver :: CalendarDiffDays -> Day -> Day
 addGregorianDurationRollOver (CalendarDiffDays m d) day = addDays d $ addGregorianMonthsRollOver m day
 
--- | Calendrical difference, with as many whole months as possible
+-- | Calendrical difference, with as many whole months as possible.
+-- Has the property @addGregorianDurationClip (diffGregorianDurationClip d2 d1) d1 = d2@.
+-- For example, 2027-03-01 - 2027-01-31 = 1 month and 1 day.
 diffGregorianDurationClip :: Day -> Day -> CalendarDiffDays
-diffGregorianDurationClip day2 day1 = let
-    (y1, m1, d1) = toGregorian day1
-    (y2, m2, d2) = toGregorian day2
-    ym1 = y1 * 12 + toInteger m1
-    ym2 = y2 * 12 + toInteger m2
-    ymdiff = ym2 - ym1
-    ymAllowed =
-        if day2 >= day1
-            then if d2 >= d1
-                     then ymdiff
-                     else ymdiff - 1
-            else if d2 <= d1
-                     then ymdiff
-                     else ymdiff + 1
-    dayAllowed = addGregorianDurationClip (CalendarDiffDays ymAllowed 0) day1
-    in CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
+diffGregorianDurationClip day2 day1 =
+    let
+        (y1, m1, d1) = toGregorian day1
+        (y2, m2, d2) = toGregorian day2
+        ym1 = y1 * 12 + toInteger m1
+        ym2 = y2 * 12 + toInteger m2
+        ymdiff = ym2 - ym1
+        ymAllowed =
+            if day2 >= day1
+                then
+                    if d2 >= d1
+                        then ymdiff
+                        else ymdiff - 1
+                else
+                    if d2 <= d1
+                        then ymdiff
+                        else ymdiff + 1
+        dayAllowed = addGregorianDurationClip (CalendarDiffDays ymAllowed 0) day1
+    in
+        CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
 
 -- | Calendrical difference, with as many whole months as possible.
--- Same as 'diffGregorianDurationClip' for positive durations.
+-- Has the property @addGregorianDurationRollOver (diffGregorianDurationRollOver d2 d1) d1 = d2@.
+-- For example, 2027-03-01 - 2027-01-31 = 29 days.
 diffGregorianDurationRollOver :: Day -> Day -> CalendarDiffDays
-diffGregorianDurationRollOver day2 day1 = let
-    (y1, m1, d1) = toGregorian day1
-    (y2, m2, d2) = toGregorian day2
-    ym1 = y1 * 12 + toInteger m1
-    ym2 = y2 * 12 + toInteger m2
-    ymdiff = ym2 - ym1
-    ymAllowed =
+diffGregorianDurationRollOver day2 day1 =
+    let
+        (y1, m1, _) = toGregorian day1
+        (y2, m2, _) = toGregorian day2
+        ym1 = y1 * 12 + toInteger m1
+        ym2 = y2 * 12 + toInteger m2
+        ymdiff = ym2 - ym1
+        findpos mdiff =
+            let
+                dayAllowed = addGregorianDurationRollOver (CalendarDiffDays mdiff 0) day1
+                dd = diffDays day2 dayAllowed
+            in
+                if dd >= 0 then CalendarDiffDays mdiff dd else findpos (pred mdiff)
+        findneg mdiff =
+            let
+                dayAllowed = addGregorianDurationRollOver (CalendarDiffDays mdiff 0) day1
+                dd = diffDays day2 dayAllowed
+            in
+                if dd <= 0 then CalendarDiffDays mdiff dd else findpos (succ mdiff)
+    in
         if day2 >= day1
-            then if d2 >= d1
-                     then ymdiff
-                     else ymdiff - 1
-            else if d2 <= d1
-                     then ymdiff
-                     else ymdiff + 1
-    dayAllowed = addGregorianDurationRollOver (CalendarDiffDays ymAllowed 0) day1
-    in CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
+            then findpos ymdiff
+            else findneg ymdiff
 
 -- orphan instance
 instance Show Day where
     show = showGregorian
+
+-- orphan instance
+instance DayPeriod Year where
+    periodFirstDay y = YearMonthDay y January 1
+    periodLastDay y = YearMonthDay y December 31
+    dayPeriod (YearMonthDay y _ _) = y
diff --git a/lib/Data/Time/Calendar/Julian.hs b/lib/Data/Time/Calendar/Julian.hs
--- a/lib/Data/Time/Calendar/Julian.hs
+++ b/lib/Data/Time/Calendar/Julian.hs
@@ -1,43 +1,75 @@
-module Data.Time.Calendar.Julian
-    ( module Data.Time.Calendar.JulianYearDay
-    , toJulian
-    , fromJulian
-    , fromJulianValid
-    , showJulian
-    , julianMonthLength
+{-# LANGUAGE Safe #-}
+
+module Data.Time.Calendar.Julian (
+    Year,
+    MonthOfYear,
+    pattern January,
+    pattern February,
+    pattern March,
+    pattern April,
+    pattern May,
+    pattern June,
+    pattern July,
+    pattern August,
+    pattern September,
+    pattern October,
+    pattern November,
+    pattern December,
+    DayOfMonth,
+    DayOfYear,
+
+    -- * Year and day format
+    module Data.Time.Calendar.JulianYearDay,
+    toJulian,
+    fromJulian,
+    pattern JulianYearMonthDay,
+    fromJulianValid,
+    showJulian,
+    julianMonthLength,
     -- calendrical arithmetic
     -- e.g. "one month after March 31st"
-    , addJulianMonthsClip
-    , addJulianMonthsRollOver
-    , addJulianYearsClip
-    , addJulianYearsRollOver
-    , addJulianDurationClip
-    , addJulianDurationRollOver
-    , diffJulianDurationClip
-    , diffJulianDurationRollOver
-    ) where
+    addJulianMonthsClip,
+    addJulianMonthsRollOver,
+    addJulianYearsClip,
+    addJulianYearsRollOver,
+    addJulianDurationClip,
+    addJulianDurationRollOver,
+    diffJulianDurationClip,
+    diffJulianDurationRollOver,
+) where
 
 import Data.Time.Calendar.CalendarDiffDays
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.JulianYearDay
 import Data.Time.Calendar.MonthDay
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
 
--- | Convert to proleptic Julian calendar. First element of result is year, second month number (1-12), third day (1-31).
-toJulian :: Day -> (Integer, Int, Int)
+-- | Convert to proleptic Julian calendar.
+toJulian :: Day -> (Year, MonthOfYear, DayOfMonth)
 toJulian date = (year, month, day)
   where
     (year, yd) = toJulianYearAndDay date
     (month, day) = dayOfYearToMonthAndDay (isJulianLeapYear year) yd
 
--- | Convert from proleptic Julian calendar. First argument is year, second month number (1-12), third day (1-31).
+-- | Convert from proleptic Julian calendar.
 -- Invalid values will be clipped to the correct range, month first, then day.
-fromJulian :: Integer -> Int -> Int -> Day
+fromJulian :: Year -> MonthOfYear -> DayOfMonth -> Day
 fromJulian year month day = fromJulianYearAndDay year (monthAndDayToDayOfYear (isJulianLeapYear year) month day)
 
--- | Convert from proleptic Julian calendar. First argument is year, second month number (1-12), third day (1-31).
+-- | Bidirectional abstract constructor for the proleptic Julian calendar.
+-- Invalid values will be clipped to the correct range, month first, then day.
+pattern JulianYearMonthDay :: Year -> MonthOfYear -> DayOfMonth -> Day
+pattern JulianYearMonthDay y m d <-
+    (toJulian -> (y, m, d))
+    where
+        JulianYearMonthDay y m d = fromJulian y m d
+
+{-# COMPLETE JulianYearMonthDay #-}
+
+-- | Convert from proleptic Julian calendar.
 -- Invalid values will return Nothing.
-fromJulianValid :: Integer -> Int -> Int -> Maybe Day
+fromJulianValid :: Year -> MonthOfYear -> DayOfMonth -> Maybe Day
 fromJulianValid year month day = do
     doy <- monthAndDayToDayOfYearValid (isJulianLeapYear year) month day
     fromJulianYearAndDayValid year doy
@@ -48,14 +80,14 @@
   where
     (y, m, d) = toJulian date
 
--- | The number of days in a given month according to the proleptic Julian calendar. First argument is year, second is month.
-julianMonthLength :: Integer -> Int -> Int
+-- | The number of days in a given month according to the proleptic Julian calendar.
+julianMonthLength :: Year -> MonthOfYear -> DayOfMonth
 julianMonthLength year = monthLength (isJulianLeapYear year)
 
-rolloverMonths :: (Integer, Integer) -> (Integer, Int)
+rolloverMonths :: (Year, Integer) -> (Year, MonthOfYear)
 rolloverMonths (y, m) = (y + (div (m - 1) 12), fromIntegral (mod (m - 1) 12) + 1)
 
-addJulianMonths :: Integer -> Day -> (Integer, Int, Int)
+addJulianMonths :: Integer -> Day -> (Year, MonthOfYear, DayOfMonth)
 addJulianMonths n day = (y', m', d)
   where
     (y, m, d) = toJulian day
@@ -95,39 +127,49 @@
 
 -- | Calendrical difference, with as many whole months as possible
 diffJulianDurationClip :: Day -> Day -> CalendarDiffDays
-diffJulianDurationClip day2 day1 = let
-    (y1, m1, d1) = toJulian day1
-    (y2, m2, d2) = toJulian day2
-    ym1 = y1 * 12 + toInteger m1
-    ym2 = y2 * 12 + toInteger m2
-    ymdiff = ym2 - ym1
-    ymAllowed =
-        if day2 >= day1
-            then if d2 >= d1
-                     then ymdiff
-                     else ymdiff - 1
-            else if d2 <= d1
-                     then ymdiff
-                     else ymdiff + 1
-    dayAllowed = addJulianDurationClip (CalendarDiffDays ymAllowed 0) day1
-    in CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
+diffJulianDurationClip day2 day1 =
+    let
+        (y1, m1, d1) = toJulian day1
+        (y2, m2, d2) = toJulian day2
+        ym1 = y1 * 12 + toInteger m1
+        ym2 = y2 * 12 + toInteger m2
+        ymdiff = ym2 - ym1
+        ymAllowed =
+            if day2 >= day1
+                then
+                    if d2 >= d1
+                        then ymdiff
+                        else ymdiff - 1
+                else
+                    if d2 <= d1
+                        then ymdiff
+                        else ymdiff + 1
+        dayAllowed = addJulianDurationClip (CalendarDiffDays ymAllowed 0) day1
+    in
+        CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
 
 -- | Calendrical difference, with as many whole months as possible.
--- Same as 'diffJulianDurationClip' for positive durations.
 diffJulianDurationRollOver :: Day -> Day -> CalendarDiffDays
-diffJulianDurationRollOver day2 day1 = let
-    (y1, m1, d1) = toJulian day1
-    (y2, m2, d2) = toJulian day2
-    ym1 = y1 * 12 + toInteger m1
-    ym2 = y2 * 12 + toInteger m2
-    ymdiff = ym2 - ym1
-    ymAllowed =
+diffJulianDurationRollOver day2 day1 =
+    let
+        (y1, m1, _) = toJulian day1
+        (y2, m2, _) = toJulian day2
+        ym1 = y1 * 12 + toInteger m1
+        ym2 = y2 * 12 + toInteger m2
+        ymdiff = ym2 - ym1
+        findpos mdiff =
+            let
+                dayAllowed = addJulianDurationRollOver (CalendarDiffDays mdiff 0) day1
+                dd = diffDays day2 dayAllowed
+            in
+                if dd >= 0 then CalendarDiffDays mdiff dd else findpos (pred mdiff)
+        findneg mdiff =
+            let
+                dayAllowed = addJulianDurationRollOver (CalendarDiffDays mdiff 0) day1
+                dd = diffDays day2 dayAllowed
+            in
+                if dd <= 0 then CalendarDiffDays mdiff dd else findpos (succ mdiff)
+    in
         if day2 >= day1
-            then if d2 >= d1
-                     then ymdiff
-                     else ymdiff - 1
-            else if d2 <= d1
-                     then ymdiff
-                     else ymdiff + 1
-    dayAllowed = addJulianDurationRollOver (CalendarDiffDays ymAllowed 0) day1
-    in CalendarDiffDays ymAllowed $ diffDays day2 dayAllowed
+            then findpos ymdiff
+            else findneg ymdiff
diff --git a/lib/Data/Time/Calendar/JulianYearDay.hs b/lib/Data/Time/Calendar/JulianYearDay.hs
--- a/lib/Data/Time/Calendar/JulianYearDay.hs
+++ b/lib/Data/Time/Calendar/JulianYearDay.hs
@@ -1,15 +1,13 @@
-module Data.Time.Calendar.JulianYearDay
-    (
-    -- * Year and day format
-      module Data.Time.Calendar.JulianYearDay
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Calendar.JulianYearDay where
+
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
 
--- | Convert to proleptic Julian year and day format. First element of result is year (proleptic Julian calendar),
--- second is the day of the year, with 1 for Jan 1, and 365 (or 366 in leap years) for Dec 31.
-toJulianYearAndDay :: Day -> (Integer, Int)
+-- | Convert to proleptic Julian year and day format.
+toJulianYearAndDay :: Day -> (Year, DayOfYear)
 toJulianYearAndDay (ModifiedJulianDay mjd) = (year, yd)
   where
     a = mjd + 678577
@@ -21,32 +19,36 @@
 
 -- | Convert from proleptic Julian year and day format.
 -- Invalid day numbers will be clipped to the correct range (1 to 365 or 366).
-fromJulianYearAndDay :: Integer -> Int -> Day
+fromJulianYearAndDay :: Year -> DayOfYear -> Day
 fromJulianYearAndDay year day = ModifiedJulianDay mjd
   where
     y = year - 1
     mjd =
-        (fromIntegral
-             (clip
-                  1
-                  (if isJulianLeapYear year
-                       then 366
-                       else 365)
-                  day)) +
-        (365 * y) +
-        (div y 4) -
-        678578
+        ( fromIntegral
+            ( clip
+                1
+                ( if isJulianLeapYear year
+                    then 366
+                    else 365
+                )
+                day
+            )
+        )
+            + (365 * y)
+            + (div y 4)
+            - 678578
 
 -- | Convert from proleptic Julian year and day format.
 -- Invalid day numbers will return Nothing
-fromJulianYearAndDayValid :: Integer -> Int -> Maybe Day
+fromJulianYearAndDayValid :: Year -> DayOfYear -> Maybe Day
 fromJulianYearAndDayValid year day = do
     day' <-
         clipValid
             1
-            (if isJulianLeapYear year
-                 then 366
-                 else 365)
+            ( if isJulianLeapYear year
+                then 366
+                else 365
+            )
             day
     let
         y = year - 1
@@ -60,5 +62,5 @@
     (y, d) = toJulianYearAndDay date
 
 -- | Is this year a leap year according to the proleptic Julian calendar?
-isJulianLeapYear :: Integer -> Bool
+isJulianLeapYear :: Year -> Bool
 isJulianLeapYear year = (mod year 4 == 0)
diff --git a/lib/Data/Time/Calendar/Month.hs b/lib/Data/Time/Calendar/Month.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Time/Calendar/Month.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
+-- | An absolute count of common calendar months.
+module Data.Time.Calendar.Month (
+    Month (..),
+    addMonths,
+    diffMonths,
+    pattern YearMonth,
+    fromYearMonthValid,
+    pattern MonthDay,
+    fromMonthDayValid,
+) where
+
+import Control.DeepSeq
+import Data.Data
+import Data.Fixed
+import Data.Ix
+import Data.Time.Calendar.Days
+import Data.Time.Calendar.Gregorian
+import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
+import Text.ParserCombinators.ReadP
+import Text.Read
+
+-- | An absolute count of common calendar months.
+-- Number is equal to @(year * 12) + (monthOfYear - 1)@.
+newtype Month = MkMonth Integer deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
+
+instance NFData Month where
+    rnf (MkMonth m) = rnf m
+
+instance Enum Month where
+    succ (MkMonth a) = MkMonth (succ a)
+    pred (MkMonth a) = MkMonth (pred a)
+    toEnum = MkMonth . toEnum
+    fromEnum (MkMonth a) = fromEnum a
+    enumFrom (MkMonth a) = fmap MkMonth (enumFrom a)
+    enumFromThen (MkMonth a) (MkMonth b) = fmap MkMonth (enumFromThen a b)
+    enumFromTo (MkMonth a) (MkMonth b) = fmap MkMonth (enumFromTo a b)
+    enumFromThenTo (MkMonth a) (MkMonth b) (MkMonth c) =
+        fmap MkMonth (enumFromThenTo a b c)
+
+instance Ix Month where
+    range (MkMonth a, MkMonth b) = fmap MkMonth (range (a, b))
+    index (MkMonth a, MkMonth b) (MkMonth c) = index (a, b) c
+    inRange (MkMonth a, MkMonth b) (MkMonth c) = inRange (a, b) c
+    rangeSize (MkMonth a, MkMonth b) = rangeSize (a, b)
+
+-- | Show as @yyyy-mm@.
+instance Show Month where
+    show (YearMonth y m) = show4 y ++ "-" ++ show2 m
+
+-- | Read as @yyyy-mm@.
+instance Read Month where
+    readPrec = do
+        y <- readPrec
+        _ <- lift $ char '-'
+        m <- readPrec
+        return $ YearMonth y m
+
+instance DayPeriod Month where
+    periodFirstDay (YearMonth y m) = YearMonthDay y m 1
+    periodLastDay (YearMonth y m) = YearMonthDay y m 31 -- clips to correct day
+    dayPeriod (YearMonthDay y my _) = YearMonth y my
+
+addMonths :: Integer -> Month -> Month
+addMonths n (MkMonth a) = MkMonth $ a + n
+
+diffMonths :: Month -> Month -> Integer
+diffMonths (MkMonth a) (MkMonth b) = a - b
+
+-- | Bidirectional abstract constructor.
+-- Invalid months of year will be clipped to the correct range.
+pattern YearMonth :: Year -> MonthOfYear -> Month
+pattern YearMonth y my <-
+    MkMonth ((\m -> divMod' m 12) -> (y, (succ . fromInteger -> my)))
+    where
+        YearMonth y my = MkMonth $ (y * 12) + toInteger (pred $ clip 1 12 my)
+
+fromYearMonthValid :: Year -> MonthOfYear -> Maybe Month
+fromYearMonthValid y my = do
+    my' <- clipValid 1 12 my
+    return $ YearMonth y my'
+
+{-# COMPLETE YearMonth #-}
+
+-- | Bidirectional abstract constructor.
+-- Invalid days of month will be clipped to the correct range.
+pattern MonthDay :: Month -> DayOfMonth -> Day
+pattern MonthDay m dm <-
+    (periodFromDay -> (m, dm))
+    where
+        MonthDay = periodToDayClip
+
+fromMonthDayValid :: Month -> DayOfMonth -> Maybe Day
+fromMonthDayValid = periodToDayValid
+
+{-# COMPLETE MonthDay #-}
diff --git a/lib/Data/Time/Calendar/MonthDay.hs b/lib/Data/Time/Calendar/MonthDay.hs
--- a/lib/Data/Time/Calendar/MonthDay.hs
+++ b/lib/Data/Time/Calendar/MonthDay.hs
@@ -1,15 +1,33 @@
-module Data.Time.Calendar.MonthDay
-    ( monthAndDayToDayOfYear
-    , monthAndDayToDayOfYearValid
-    , dayOfYearToMonthAndDay
-    , monthLength
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Calendar.MonthDay (
+    MonthOfYear,
+    pattern January,
+    pattern February,
+    pattern March,
+    pattern April,
+    pattern May,
+    pattern June,
+    pattern July,
+    pattern August,
+    pattern September,
+    pattern October,
+    pattern November,
+    pattern December,
+    DayOfMonth,
+    DayOfYear,
+    monthAndDayToDayOfYear,
+    monthAndDayToDayOfYearValid,
+    dayOfYearToMonthAndDay,
+    monthLength,
+) where
+
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
 
 -- | Convert month and day in the Gregorian or Julian calendars to day of year.
 -- First arg is leap year flag.
-monthAndDayToDayOfYear :: Bool -> Int -> Int -> Int
+monthAndDayToDayOfYear :: Bool -> MonthOfYear -> DayOfMonth -> DayOfYear
 monthAndDayToDayOfYear isLeap month day = (div (367 * month'' - 362) 12) + k + day'
   where
     month' = clip 1 12 month
@@ -18,13 +36,14 @@
     k =
         if month' <= 2
             then 0
-            else if isLeap
-                     then -1
-                     else -2
+            else
+                if isLeap
+                    then -1
+                    else -2
 
 -- | Convert month and day in the Gregorian or Julian calendars to day of year.
 -- First arg is leap year flag.
-monthAndDayToDayOfYearValid :: Bool -> Int -> Int -> Maybe Int
+monthAndDayToDayOfYearValid :: Bool -> MonthOfYear -> DayOfMonth -> Maybe DayOfYear
 monthAndDayToDayOfYearValid isLeap month day = do
     month' <- clipValid 1 12 month
     day' <- clipValid 1 (monthLength' isLeap month') day
@@ -34,43 +53,46 @@
         k =
             if month' <= 2
                 then 0
-                else if isLeap
-                         then -1
-                         else -2
+                else
+                    if isLeap
+                        then -1
+                        else -2
     return ((div (367 * month'' - 362) 12) + k + day'')
 
 -- | Convert day of year in the Gregorian or Julian calendars to month and day.
 -- First arg is leap year flag.
-dayOfYearToMonthAndDay :: Bool -> Int -> (Int, Int)
+dayOfYearToMonthAndDay :: Bool -> DayOfYear -> (MonthOfYear, DayOfMonth)
 dayOfYearToMonthAndDay isLeap yd =
     findMonthDay
         (monthLengths isLeap)
-        (clip
-             1
-             (if isLeap
-                  then 366
-                  else 365)
-             yd)
+        ( clip
+            1
+            ( if isLeap
+                then 366
+                else 365
+            )
+            yd
+        )
 
 findMonthDay :: [Int] -> Int -> (Int, Int)
-findMonthDay (n:ns) yd
+findMonthDay (n : ns) yd
     | yd > n = (\(m, d) -> (m + 1, d)) (findMonthDay ns (yd - n))
 findMonthDay _ yd = (1, yd)
 
 -- | The length of a given month in the Gregorian or Julian calendars.
 -- First arg is leap year flag.
-monthLength :: Bool -> Int -> Int
+monthLength :: Bool -> MonthOfYear -> DayOfMonth
 monthLength isLeap month' = monthLength' isLeap (clip 1 12 month')
 
-monthLength' :: Bool -> Int -> Int
+monthLength' :: Bool -> MonthOfYear -> DayOfMonth
 monthLength' isLeap month' = (monthLengths isLeap) !! (month' - 1)
 
-monthLengths :: Bool -> [Int]
+monthLengths :: Bool -> [DayOfMonth]
 monthLengths isleap =
     [ 31
     , if isleap
-          then 29
-          else 28
+        then 29
+        else 28
     , 31
     , 30
     , 31
@@ -82,4 +104,5 @@
     , 30
     , 31
     ]
-    --J        F                   M  A  M  J  J  A  S  O  N  D
+
+-- J        F                   M  A  M  J  J  A  S  O  N  D
diff --git a/lib/Data/Time/Calendar/OrdinalDate.hs b/lib/Data/Time/Calendar/OrdinalDate.hs
--- a/lib/Data/Time/Calendar/OrdinalDate.hs
+++ b/lib/Data/Time/Calendar/OrdinalDate.hs
@@ -1,12 +1,14 @@
+{-# LANGUAGE Safe #-}
+
 -- | ISO 8601 Ordinal Date format
-module Data.Time.Calendar.OrdinalDate where
+module Data.Time.Calendar.OrdinalDate (Day, Year, DayOfYear, WeekOfYear, module Data.Time.Calendar.OrdinalDate) where
 
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
 
--- | Convert to ISO 8601 Ordinal Date format. First element of result is year (proleptic Gregoran calendar),
--- second is the day of the year, with 1 for Jan 1, and 365 (or 366 in leap years) for Dec 31.
-toOrdinalDate :: Day -> (Integer, Int)
+-- | Convert to ISO 8601 Ordinal Date format.
+toOrdinalDate :: Day -> (Year, DayOfYear)
 toOrdinalDate (ModifiedJulianDay mjd) = (year, yd)
   where
     a = mjd + 678575
@@ -22,34 +24,48 @@
 
 -- | Convert from ISO 8601 Ordinal Date format.
 -- Invalid day numbers will be clipped to the correct range (1 to 365 or 366).
-fromOrdinalDate :: Integer -> Int -> Day
+fromOrdinalDate :: Year -> DayOfYear -> Day
 fromOrdinalDate year day = ModifiedJulianDay mjd
   where
     y = year - 1
     mjd =
-        (fromIntegral
-             (clip
-                  1
-                  (if isLeapYear year
-                       then 366
-                       else 365)
-                  day)) +
-        (365 * y) +
-        (div y 4) -
-        (div y 100) +
-        (div y 400) -
-        678576
+        ( fromIntegral
+            ( clip
+                1
+                ( if isLeapYear year
+                    then 366
+                    else 365
+                )
+                day
+            )
+        )
+            + (365 * y)
+            + (div y 4)
+            - (div y 100)
+            + (div y 400)
+            - 678576
 
+-- | Bidirectional abstract constructor for ISO 8601 Ordinal Date format.
+-- Invalid day numbers will be clipped to the correct range (1 to 365 or 366).
+pattern YearDay :: Year -> DayOfYear -> Day
+pattern YearDay y d <-
+    (toOrdinalDate -> (y, d))
+    where
+        YearDay y d = fromOrdinalDate y d
+
+{-# COMPLETE YearDay #-}
+
 -- | Convert from ISO 8601 Ordinal Date format.
 -- Invalid day numbers return 'Nothing'
-fromOrdinalDateValid :: Integer -> Int -> Maybe Day
+fromOrdinalDateValid :: Year -> DayOfYear -> Maybe Day
 fromOrdinalDateValid year day = do
     day' <-
         clipValid
             1
-            (if isLeapYear year
-                 then 366
-                 else 365)
+            ( if isLeapYear year
+                then 366
+                else 365
+            )
             day
     let
         y = year - 1
@@ -63,13 +79,13 @@
     (y, d) = toOrdinalDate date
 
 -- | Is this year a leap year according to the proleptic Gregorian calendar?
-isLeapYear :: Integer -> Bool
+isLeapYear :: Year -> Bool
 isLeapYear year = (mod year 4 == 0) && ((mod year 400 == 0) || not (mod year 100 == 0))
 
 -- | Get the number of the Monday-starting week in the year and the day of the week.
 -- The first Monday is the first day of week 1, any earlier days in the year are week 0 (as @%W@ in 'Data.Time.Format.formatTime').
 -- Monday is 1, Sunday is 7 (as @%u@ in 'Data.Time.Format.formatTime').
-mondayStartWeek :: Day -> (Int, Int)
+mondayStartWeek :: Day -> (WeekOfYear, Int)
 mondayStartWeek date = (fromInteger ((div d 7) - (div k 7)), fromInteger (mod d 7) + 1)
   where
     yd = snd (toOrdinalDate date)
@@ -79,7 +95,7 @@
 -- | Get the number of the Sunday-starting week in the year and the day of the week.
 -- The first Sunday is the first day of week 1, any earlier days in the year are week 0 (as @%U@ in 'Data.Time.Format.formatTime').
 -- Sunday is 0, Saturday is 6 (as @%w@ in 'Data.Time.Format.formatTime').
-sundayStartWeek :: Day -> (Int, Int)
+sundayStartWeek :: Day -> (WeekOfYear, Int)
 sundayStartWeek date = (fromInteger ((div d 7) - (div k 7)), fromInteger (mod d 7))
   where
     yd = snd (toOrdinalDate date)
@@ -91,30 +107,38 @@
 -- The first Monday is the first day of week 1, any earlier days in the year
 -- are week 0 (as @%W@ in 'Data.Time.Format.formatTime').
 fromMondayStartWeek ::
-       Integer -- ^ Year.
-    -> Int -- ^ Monday-starting week number (as @%W@ in 'Data.Time.Format.formatTime').
-    -> Int -- ^ Day of week.
-                               -- Monday is 1, Sunday is 7 (as @%u@ in 'Data.Time.Format.formatTime').
-    -> Day
-fromMondayStartWeek year w d = let
-    -- first day of the year
-    firstDay = fromOrdinalDate year 1
-    -- 0-based year day of first monday of the year
-    zbFirstMonday = (5 - toModifiedJulianDay firstDay) `mod` 7
-    -- 0-based week of year
-    zbWeek = w - 1
-    -- 0-based day of week
-    zbDay = d - 1
-    -- 0-based day in year
-    zbYearDay = zbFirstMonday + 7 * toInteger zbWeek + toInteger zbDay
-    in addDays zbYearDay firstDay
+    -- | Year.
+    Year ->
+    -- | Monday-starting week number (as @%W@ in 'Data.Time.Format.formatTime').
+    WeekOfYear ->
+    -- | Day of week.
+    -- Monday is 1, Sunday is 7 (as @%u@ in 'Data.Time.Format.formatTime').
+    Int ->
+    Day
+fromMondayStartWeek year w d =
+    let
+        -- first day of the year
+        firstDay = fromOrdinalDate year 1
+        -- 0-based year day of first monday of the year
+        zbFirstMonday = (5 - toModifiedJulianDay firstDay) `mod` 7
+        -- 0-based week of year
+        zbWeek = w - 1
+        -- 0-based day of week
+        zbDay = d - 1
+        -- 0-based day in year
+        zbYearDay = zbFirstMonday + 7 * toInteger zbWeek + toInteger zbDay
+    in
+        addDays zbYearDay firstDay
 
 fromMondayStartWeekValid ::
-       Integer -- ^ Year.
-    -> Int -- ^ Monday-starting week number (as @%W@ in 'Data.Time.Format.formatTime').
-    -> Int -- ^ Day of week.
-                               -- Monday is 1, Sunday is 7 (as @%u@ in 'Data.Time.Format.formatTime').
-    -> Maybe Day
+    -- | Year.
+    Year ->
+    -- | Monday-starting week number (as @%W@ in 'Data.Time.Format.formatTime').
+    WeekOfYear ->
+    -- | Day of week.
+    -- Monday is 1, Sunday is 7 (as @%u@ in 'Data.Time.Format.formatTime').
+    Int ->
+    Maybe Day
 fromMondayStartWeekValid year w d = do
     d' <- clipValid 1 7 d
     let
@@ -131,9 +155,10 @@
     zbYearDay' <-
         clipValid
             0
-            (if isLeapYear year
-                 then 365
-                 else 364)
+            ( if isLeapYear year
+                then 365
+                else 364
+            )
             zbYearDay
     return $ addDays zbYearDay' firstDay
 
@@ -142,30 +167,38 @@
 -- The first Sunday is the first day of week 1, any earlier days in the
 -- year are week 0 (as @%U@ in 'Data.Time.Format.formatTime').
 fromSundayStartWeek ::
-       Integer -- ^ Year.
-    -> Int -- ^ Sunday-starting week number (as @%U@ in 'Data.Time.Format.formatTime').
-    -> Int -- ^ Day of week
-                               -- Sunday is 0, Saturday is 6 (as @%w@ in 'Data.Time.Format.formatTime').
-    -> Day
-fromSundayStartWeek year w d = let
-    -- first day of the year
-    firstDay = fromOrdinalDate year 1
-    -- 0-based year day of first monday of the year
-    zbFirstSunday = (4 - toModifiedJulianDay firstDay) `mod` 7
-    -- 0-based week of year
-    zbWeek = w - 1
-    -- 0-based day of week
-    zbDay = d
-    -- 0-based day in year
-    zbYearDay = zbFirstSunday + 7 * toInteger zbWeek + toInteger zbDay
-    in addDays zbYearDay firstDay
+    -- | Year.
+    Year ->
+    -- | Sunday-starting week number (as @%U@ in 'Data.Time.Format.formatTime').
+    WeekOfYear ->
+    -- | Day of week
+    -- Sunday is 0, Saturday is 6 (as @%w@ in 'Data.Time.Format.formatTime').
+    Int ->
+    Day
+fromSundayStartWeek year w d =
+    let
+        -- first day of the year
+        firstDay = fromOrdinalDate year 1
+        -- 0-based year day of first monday of the year
+        zbFirstSunday = (4 - toModifiedJulianDay firstDay) `mod` 7
+        -- 0-based week of year
+        zbWeek = w - 1
+        -- 0-based day of week
+        zbDay = d
+        -- 0-based day in year
+        zbYearDay = zbFirstSunday + 7 * toInteger zbWeek + toInteger zbDay
+    in
+        addDays zbYearDay firstDay
 
 fromSundayStartWeekValid ::
-       Integer -- ^ Year.
-    -> Int -- ^ Sunday-starting week number (as @%U@ in 'Data.Time.Format.formatTime').
-    -> Int -- ^ Day of week.
-                               -- Sunday is 0, Saturday is 6 (as @%w@ in 'Data.Time.Format.formatTime').
-    -> Maybe Day
+    -- | Year.
+    Year ->
+    -- | Sunday-starting week number (as @%U@ in 'Data.Time.Format.formatTime').
+    WeekOfYear ->
+    -- | Day of week.
+    -- Sunday is 0, Saturday is 6 (as @%w@ in 'Data.Time.Format.formatTime').
+    Int ->
+    Maybe Day
 fromSundayStartWeekValid year w d = do
     d' <- clipValid 0 6 d
     let
@@ -182,8 +215,9 @@
     zbYearDay' <-
         clipValid
             0
-            (if isLeapYear year
-                 then 365
-                 else 364)
+            ( if isLeapYear year
+                then 365
+                else 364
+            )
             zbYearDay
     return $ addDays zbYearDay' firstDay
diff --git a/lib/Data/Time/Calendar/Private.hs b/lib/Data/Time/Calendar/Private.hs
--- a/lib/Data/Time/Calendar/Private.hs
+++ b/lib/Data/Time/Calendar/Private.hs
@@ -1,10 +1,13 @@
+{-# LANGUAGE Safe #-}
+
 module Data.Time.Calendar.Private where
 
 import Data.Fixed
 
 data PadOption
-    = Pad Int
-          Char
+    = Pad
+        Int
+        Char
     | NoPad
 
 showPadded :: PadOption -> String -> String
@@ -33,29 +36,29 @@
     | x < 10 = '0' : (showFixed True x)
 show2Fixed x = showFixed True x
 
-show2 :: (ShowPadded t) => t -> String
+show2 :: ShowPadded t => t -> String
 show2 = showPaddedNum $ Pad 2 '0'
 
-show3 :: (ShowPadded t) => t -> String
+show3 :: ShowPadded t => t -> String
 show3 = showPaddedNum $ Pad 3 '0'
 
-show4 :: (ShowPadded t) => t -> String
+show4 :: ShowPadded t => t -> String
 show4 = showPaddedNum $ Pad 4 '0'
 
-mod100 :: (Integral i) => i -> i
+mod100 :: Integral i => i -> i
 mod100 x = mod x 100
 
-div100 :: (Integral i) => i -> i
+div100 :: Integral i => i -> i
 div100 x = div x 100
 
-clip :: (Ord t) => t -> t -> t -> t
+clip :: Ord t => t -> t -> t -> t
 clip a _ x
     | x < a = a
 clip _ b x
     | x > b = b
 clip _ _ x = x
 
-clipValid :: (Ord t) => t -> t -> t -> Maybe t
+clipValid :: Ord t => t -> t -> t -> Maybe t
 clipValid a _ x
     | x < a = Nothing
 clipValid _ b x
@@ -71,6 +74,8 @@
     f = quotBy d n
 
 quotRemBy :: (Real a, Integral b) => a -> a -> (b, a)
-quotRemBy d n = let
-    f = quotBy d n
-    in (f, n - (fromIntegral f) * d)
+quotRemBy d n =
+    let
+        f = quotBy d n
+    in
+        (f, n - (fromIntegral f) * d)
diff --git a/lib/Data/Time/Calendar/Quarter.hs b/lib/Data/Time/Calendar/Quarter.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Time/Calendar/Quarter.hs
@@ -0,0 +1,152 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
+-- | Year quarters.
+module Data.Time.Calendar.Quarter (
+    QuarterOfYear (..),
+    addQuarters,
+    diffQuarters,
+    Quarter (..),
+    pattern YearQuarter,
+    monthOfYearQuarter,
+    monthQuarter,
+    dayQuarter,
+    DayOfQuarter,
+    pattern QuarterDay,
+) where
+
+import Control.DeepSeq
+import Data.Data
+import Data.Fixed
+import Data.Ix
+import Data.Time.Calendar.Days
+import Data.Time.Calendar.Month
+import Data.Time.Calendar.Private
+import Data.Time.Calendar.Types
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
+import Text.ParserCombinators.ReadP
+import Text.Read
+
+-- | Quarters of each year. Each quarter corresponds to three months.
+data QuarterOfYear = Q1 | Q2 | Q3 | Q4 deriving (Eq, Ord, Read, Show, Ix, Typeable, Data, Generic, TH.Lift)
+
+-- | maps Q1..Q4 to 1..4
+instance Enum QuarterOfYear where
+    toEnum i =
+        case mod' i 4 of
+            1 -> Q1
+            2 -> Q2
+            3 -> Q3
+            _ -> Q4
+    fromEnum Q1 = 1
+    fromEnum Q2 = 2
+    fromEnum Q3 = 3
+    fromEnum Q4 = 4
+
+instance Bounded QuarterOfYear where
+    minBound = Q1
+    maxBound = Q4
+
+instance NFData QuarterOfYear where
+    rnf Q1 = ()
+    rnf Q2 = ()
+    rnf Q3 = ()
+    rnf Q4 = ()
+
+-- | An absolute count of year quarters.
+-- Number is equal to @(year * 4) + (quarterOfYear - 1)@.
+newtype Quarter = MkQuarter Integer deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
+
+instance NFData Quarter where
+    rnf (MkQuarter m) = rnf m
+
+instance Enum Quarter where
+    succ (MkQuarter a) = MkQuarter (succ a)
+    pred (MkQuarter a) = MkQuarter (pred a)
+    toEnum = MkQuarter . toEnum
+    fromEnum (MkQuarter a) = fromEnum a
+    enumFrom (MkQuarter a) = fmap MkQuarter (enumFrom a)
+    enumFromThen (MkQuarter a) (MkQuarter b) = fmap MkQuarter (enumFromThen a b)
+    enumFromTo (MkQuarter a) (MkQuarter b) = fmap MkQuarter (enumFromTo a b)
+    enumFromThenTo (MkQuarter a) (MkQuarter b) (MkQuarter c) =
+        fmap MkQuarter (enumFromThenTo a b c)
+
+instance Ix Quarter where
+    range (MkQuarter a, MkQuarter b) = fmap MkQuarter (range (a, b))
+    index (MkQuarter a, MkQuarter b) (MkQuarter c) = index (a, b) c
+    inRange (MkQuarter a, MkQuarter b) (MkQuarter c) = inRange (a, b) c
+    rangeSize (MkQuarter a, MkQuarter b) = rangeSize (a, b)
+
+-- | Show as @yyyy-Qn@.
+instance Show Quarter where
+    show (YearQuarter y qy) = show4 y ++ "-" ++ show qy
+
+-- | Read as @yyyy-Qn@.
+instance Read Quarter where
+    readPrec = do
+        y <- readPrec
+        _ <- lift $ char '-'
+        m <- readPrec
+        return $ YearQuarter y m
+
+instance DayPeriod Quarter where
+    periodFirstDay (YearQuarter y q) =
+        case q of
+            Q1 -> periodFirstDay $ YearMonth y January
+            Q2 -> periodFirstDay $ YearMonth y April
+            Q3 -> periodFirstDay $ YearMonth y July
+            Q4 -> periodFirstDay $ YearMonth y October
+    periodLastDay (YearQuarter y q) =
+        case q of
+            Q1 -> periodLastDay $ YearMonth y March
+            Q2 -> periodLastDay $ YearMonth y June
+            Q3 -> periodLastDay $ YearMonth y September
+            Q4 -> periodLastDay $ YearMonth y December
+    dayPeriod (MonthDay m _) = monthQuarter m
+
+addQuarters :: Integer -> Quarter -> Quarter
+addQuarters n (MkQuarter a) = MkQuarter $ a + n
+
+diffQuarters :: Quarter -> Quarter -> Integer
+diffQuarters (MkQuarter a) (MkQuarter b) = a - b
+
+-- | Bidirectional abstract constructor.
+pattern YearQuarter :: Year -> QuarterOfYear -> Quarter
+pattern YearQuarter y qy <-
+    MkQuarter ((\q -> divMod' q 4) -> (y, (toEnum . succ . fromInteger -> qy)))
+    where
+        YearQuarter y qy = MkQuarter $ (y * 4) + toInteger (pred $ fromEnum qy)
+
+{-# COMPLETE YearQuarter #-}
+
+-- | The 'QuarterOfYear' this 'MonthOfYear' is in.
+monthOfYearQuarter :: MonthOfYear -> QuarterOfYear
+monthOfYearQuarter my | my <= 3 = Q1
+monthOfYearQuarter my | my <= 6 = Q2
+monthOfYearQuarter my | my <= 9 = Q3
+monthOfYearQuarter _ = Q4
+
+-- | The 'Quarter' this 'Month' is in.
+monthQuarter :: Month -> Quarter
+monthQuarter (YearMonth y my) = YearQuarter y $ monthOfYearQuarter my
+
+-- | The 'Quarter' this 'Day' is in.
+dayQuarter :: Day -> Quarter
+dayQuarter = dayPeriod
+
+-- | Bidirectional abstract constructor.
+-- Invalid days of quarter will be clipped to the correct range.
+--
+-- @since 1.12.1
+pattern QuarterDay :: Quarter -> DayOfQuarter -> Day
+pattern QuarterDay q dq <-
+    (periodFromDay -> (q, dq))
+    where
+        QuarterDay = periodToDayClip
+
+{-# COMPLETE QuarterDay #-}
diff --git a/lib/Data/Time/Calendar/Types.hs b/lib/Data/Time/Calendar/Types.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Time/Calendar/Types.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE Safe #-}
+
+module Data.Time.Calendar.Types where
+
+-- | Year of Common Era (when positive).
+type Year = Integer
+
+-- | Also known as Anno Domini.
+pattern CommonEra :: Integer -> Year
+pattern CommonEra n <-
+    ((\y -> if y > 0 then Just y else Nothing) -> Just n)
+    where
+        CommonEra n = n
+
+-- | Also known as Before Christ.
+-- Note that Year 1 = 1 CE, and the previous Year 0 = 1 BCE.
+-- 'CommonEra' and 'BeforeCommonEra' form a @COMPLETE@ set.
+pattern BeforeCommonEra :: Integer -> Year
+pattern BeforeCommonEra n <-
+    ((\y -> if y <= 0 then Just (1 - y) else Nothing) -> Just n)
+    where
+        BeforeCommonEra n = 1 - n
+
+{-# COMPLETE CommonEra, BeforeCommonEra #-}
+
+-- | Month of year, in range 1 (January) to 12 (December).
+type MonthOfYear = Int
+
+pattern January :: MonthOfYear
+pattern January = 1
+
+pattern February :: MonthOfYear
+pattern February = 2
+
+pattern March :: MonthOfYear
+pattern March = 3
+
+pattern April :: MonthOfYear
+pattern April = 4
+
+pattern May :: MonthOfYear
+pattern May = 5
+
+pattern June :: MonthOfYear
+pattern June = 6
+
+pattern July :: MonthOfYear
+pattern July = 7
+
+pattern August :: MonthOfYear
+pattern August = 8
+
+pattern September :: MonthOfYear
+pattern September = 9
+
+pattern October :: MonthOfYear
+pattern October = 10
+
+pattern November :: MonthOfYear
+pattern November = 11
+
+-- | The twelve 'MonthOfYear' patterns form a @COMPLETE@ set.
+pattern December :: MonthOfYear
+pattern December = 12
+
+{-# COMPLETE January, February, March, April, May, June, July, August, September, October, November, December #-}
+
+-- | Day of month, in range 1 to 31.
+type DayOfMonth = Int
+
+-- | Day of quarter, in range 1 to 92.
+type DayOfQuarter = Int
+
+-- | Day of year, in range 1 (January 1st) to 366.
+-- December 31st is 365 in a common year, 366 in a leap year.
+type DayOfYear = Int
+
+-- | Week of year, by various reckonings, generally in range 0-53 depending on reckoning.
+type WeekOfYear = Int
diff --git a/lib/Data/Time/Calendar/Week.hs b/lib/Data/Time/Calendar/Week.hs
--- a/lib/Data/Time/Calendar/Week.hs
+++ b/lib/Data/Time/Calendar/Week.hs
@@ -1,12 +1,19 @@
-module Data.Time.Calendar.Week
-    (
-      -- * Week
-      DayOfWeek(..)
-    , dayOfWeek
-    ) where
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Calendar.Week where
+
+import Control.DeepSeq
 import Data.Data
+import Data.Fixed
+import Data.Ix
 import Data.Time.Calendar.Days
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 data DayOfWeek
     = Monday
@@ -16,20 +23,28 @@
     | Friday
     | Saturday
     | Sunday
-    deriving (Eq, Show, Read, Data, Typeable)
+    deriving (Eq, Ord, Ix, Show, Read, Typeable, Data, Generic, TH.Lift)
 
+instance NFData DayOfWeek where
+    rnf Monday = ()
+    rnf Tuesday = ()
+    rnf Wednesday = ()
+    rnf Thursday = ()
+    rnf Friday = ()
+    rnf Saturday = ()
+    rnf Sunday = ()
+
 -- | \"Circular\", so for example @[Tuesday ..]@ gives an endless sequence.
 -- Also: 'fromEnum' gives [1 .. 7] for [Monday .. Sunday], and 'toEnum' performs mod 7 to give a cycle of days.
 instance Enum DayOfWeek where
-    toEnum i =
-        case mod i 7 of
-            0 -> Sunday
-            1 -> Monday
-            2 -> Tuesday
-            3 -> Wednesday
-            4 -> Thursday
-            5 -> Friday
-            _ -> Saturday
+    toEnum i = case mod i 7 of
+        0 -> Sunday
+        1 -> Monday
+        2 -> Tuesday
+        3 -> Wednesday
+        4 -> Thursday
+        5 -> Friday
+        _ -> Saturday
     fromEnum Monday = 1
     fromEnum Tuesday = 2
     fromEnum Wednesday = 3
@@ -46,3 +61,64 @@
 
 dayOfWeek :: Day -> DayOfWeek
 dayOfWeek (ModifiedJulianDay d) = toEnum $ fromInteger $ d + 3
+
+-- | @dayOfWeekDiff a b = a - b@ in range 0 to 6.
+-- The number of days from b to the next a.
+dayOfWeekDiff :: DayOfWeek -> DayOfWeek -> Int
+dayOfWeekDiff a b = mod' (fromEnum a - fromEnum b) 7
+
+-- | The first day-of-week on or after some day
+firstDayOfWeekOnAfter :: DayOfWeek -> Day -> Day
+firstDayOfWeekOnAfter dw d = addDays (toInteger $ dayOfWeekDiff dw $ dayOfWeek d) d
+
+-- | Returns a week containing the given 'Day' where the first day is the
+-- 'DayOfWeek' specified.
+--
+-- Examples:
+--
+-- >>> weekAllDays Sunday (YearMonthDay 2022 02 21)
+-- [YearMonthDay 2022 2 20 .. YearMonthDay 2022 2 26]
+--
+-- >>> weekAllDays Monday (YearMonthDay 2022 02 21)
+-- [YearMonthDay 2022 2 21 .. YearMonthDay 2022 2 27]
+--
+-- >>> weekAllDays Tuesday (YearMonthDay 2022 02 21)
+-- [YearMonthDay 2022 2 15 .. YearMonthDay 2022 2 21]
+--
+-- @since 1.12.2
+weekAllDays :: DayOfWeek -> Day -> [Day]
+weekAllDays firstDay day = [weekFirstDay firstDay day .. weekLastDay firstDay day]
+
+-- | Returns the first day of a week containing the given 'Day'.
+--
+-- Examples:
+--
+-- >>> weekFirstDay Sunday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 20
+--
+-- >>> weekFirstDay Monday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 21
+--
+-- >>> weekFirstDay Tuesday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 15
+--
+-- @since 1.12.2
+weekFirstDay :: DayOfWeek -> Day -> Day
+weekFirstDay firstDay day = addDays (negate 7) $ firstDayOfWeekOnAfter firstDay $ succ day
+
+-- | Returns the last day of a week containing the given 'Day'.
+--
+-- Examples:
+--
+-- >>> weekLastDay Sunday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 26
+--
+-- >>> weekLastDay Monday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 27
+--
+-- >>> weekLastDay Tuesday (YearMonthDay 2022 02 21)
+-- YearMonthDay 2022 2 21
+--
+-- @since 1.12.2
+weekLastDay :: DayOfWeek -> Day -> Day
+weekLastDay firstDay day = pred $ firstDayOfWeekOnAfter firstDay $ succ day
diff --git a/lib/Data/Time/Calendar/WeekDate.hs b/lib/Data/Time/Calendar/WeekDate.hs
--- a/lib/Data/Time/Calendar/WeekDate.hs
+++ b/lib/Data/Time/Calendar/WeekDate.hs
@@ -1,73 +1,146 @@
--- | ISO 8601 Week Date format
-module Data.Time.Calendar.WeekDate where
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
+-- | Week-based calendars
+module Data.Time.Calendar.WeekDate (
+    Year,
+    WeekOfYear,
+    DayOfWeek (..),
+    dayOfWeek,
+    FirstWeekType (..),
+    toWeekCalendar,
+    fromWeekCalendar,
+    fromWeekCalendarValid,
+
+    -- * ISO 8601 Week Date format
+    toWeekDate,
+    fromWeekDate,
+    pattern YearWeekDay,
+    fromWeekDateValid,
+    showWeekDate,
+) where
+
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Week
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
+data FirstWeekType
+    = -- | first week is the first whole week of the year
+      FirstWholeWeek
+    | -- | first week is the first week with four days in the year
+      FirstMostWeek
+    deriving (Eq, TH.Lift)
+
+firstDayOfWeekCalendar :: FirstWeekType -> DayOfWeek -> Year -> Day
+firstDayOfWeekCalendar wt dow year =
+    let
+        jan1st = fromOrdinalDate year 1
+    in
+        case wt of
+            FirstWholeWeek -> firstDayOfWeekOnAfter dow jan1st
+            FirstMostWeek -> firstDayOfWeekOnAfter dow $ addDays (-3) jan1st
+
+-- | Convert to the given kind of "week calendar".
+-- Note that the year number matches the weeks, and so is not always the same as the Gregorian year number.
+toWeekCalendar ::
+    -- | how to reckon the first week of the year
+    FirstWeekType ->
+    -- | the first day of each week
+    DayOfWeek ->
+    Day ->
+    (Year, WeekOfYear, DayOfWeek)
+toWeekCalendar wt ws d =
+    let
+        dw = dayOfWeek d
+        (y0, _) = toOrdinalDate d
+        j1p = firstDayOfWeekCalendar wt ws $ pred y0
+        j1 = firstDayOfWeekCalendar wt ws y0
+        j1s = firstDayOfWeekCalendar wt ws $ succ y0
+    in
+        if d < j1
+            then (pred y0, succ $ div (fromInteger $ diffDays d j1p) 7, dw)
+            else
+                if d < j1s
+                    then (y0, succ $ div (fromInteger $ diffDays d j1) 7, dw)
+                    else (succ y0, succ $ div (fromInteger $ diffDays d j1s) 7, dw)
+
+-- | Convert from the given kind of "week calendar".
+-- Invalid week and day values will be clipped to the correct range.
+fromWeekCalendar ::
+    -- | how to reckon the first week of the year
+    FirstWeekType ->
+    -- | the first day of each week
+    DayOfWeek ->
+    Year ->
+    WeekOfYear ->
+    DayOfWeek ->
+    Day
+fromWeekCalendar wt ws y wy dw =
+    let
+        d1 :: Day
+        d1 = firstDayOfWeekCalendar wt ws y
+        wy' = clip 1 53 wy
+        getday :: WeekOfYear -> Day
+        getday wy'' = addDays (toInteger $ (pred wy'' * 7) + (dayOfWeekDiff dw ws)) d1
+        d1s = firstDayOfWeekCalendar wt ws $ succ y
+        day = getday wy'
+    in
+        if wy' == 53 then if day >= d1s then getday 52 else day else day
+
+-- | Convert from the given kind of "week calendar".
+-- Invalid week and day values will return Nothing.
+fromWeekCalendarValid ::
+    -- | how to reckon the first week of the year
+    FirstWeekType ->
+    -- | the first day of each week
+    DayOfWeek ->
+    Year ->
+    WeekOfYear ->
+    DayOfWeek ->
+    Maybe Day
+fromWeekCalendarValid wt ws y wy dw =
+    let
+        d = fromWeekCalendar wt ws y wy dw
+    in
+        if toWeekCalendar wt ws d == (y, wy, dw) then Just d else Nothing
+
 -- | Convert to ISO 8601 Week Date format. First element of result is year, second week number (1-53), third day of week (1 for Monday to 7 for Sunday).
 -- Note that \"Week\" years are not quite the same as Gregorian years, as the first day of the year is always a Monday.
 -- The first week of a year is the first week to contain at least four days in the corresponding Gregorian year.
-toWeekDate :: Day -> (Integer, Int, Int)
-toWeekDate date@(ModifiedJulianDay mjd) = (y1, fromInteger (w1 + 1), fromInteger d_mod_7 + 1)
-  where
-    (d_div_7, d_mod_7) = d `divMod` 7
-    (y0, yd) = toOrdinalDate date
-    d = mjd + 2
-    foo :: Integer -> Integer
-    foo y = bar (toModifiedJulianDay (fromOrdinalDate y 6))
-    bar k = d_div_7 - k `div` 7
-    (y1, w1) =
-        case bar (d - toInteger yd + 4) of
-            -1 -> (y0 - 1, foo (y0 - 1))
-            52 ->
-                if foo (y0 + 1) == 0
-                    then (y0 + 1, 0)
-                    else (y0, 52)
-            w0 -> (y0, w0)
+toWeekDate :: Day -> (Year, WeekOfYear, Int)
+toWeekDate d =
+    let
+        (y, wy, dw) = toWeekCalendar FirstMostWeek Monday d
+    in
+        (y, wy, fromEnum dw)
 
 -- | Convert from ISO 8601 Week Date format. First argument is year, second week number (1-52 or 53), third day of week (1 for Monday to 7 for Sunday).
 -- Invalid week and day values will be clipped to the correct range.
-fromWeekDate :: Integer -> Int -> Int -> Day
-fromWeekDate y w d =
-    ModifiedJulianDay
-        (k - (mod k 7) +
-         (toInteger
-              (((clip
-                     1
-                     (if longYear
-                          then 53
-                          else 52)
-                     w) *
-                7) +
-               (clip 1 7 d))) -
-         10)
-  where
-    k = toModifiedJulianDay (fromOrdinalDate y 6)
-    longYear =
-        case toWeekDate (fromOrdinalDate y 365) of
-            (_, 53, _) -> True
-            _ -> False
+fromWeekDate :: Year -> WeekOfYear -> Int -> Day
+fromWeekDate y wy dw = fromWeekCalendar FirstMostWeek Monday y wy (toEnum $ clip 1 7 dw)
 
+-- | Bidirectional abstract constructor for ISO 8601 Week Date format.
+-- Invalid week values will be clipped to the correct range.
+pattern YearWeekDay :: Year -> WeekOfYear -> DayOfWeek -> Day
+pattern YearWeekDay y wy dw <-
+    (toWeekDate -> (y, wy, (toEnum -> dw)))
+    where
+        YearWeekDay y wy dw = fromWeekDate y wy (fromEnum dw)
+
+{-# COMPLETE YearWeekDay #-}
+
 -- | Convert from ISO 8601 Week Date format. First argument is year, second week number (1-52 or 53), third day of week (1 for Monday to 7 for Sunday).
 -- Invalid week and day values will return Nothing.
-fromWeekDateValid :: Integer -> Int -> Int -> Maybe Day
-fromWeekDateValid y w d = do
-    d' <- clipValid 1 7 d
-    let
-        longYear =
-            case toWeekDate (fromOrdinalDate y 365) of
-                (_, 53, _) -> True
-                _ -> False
-    w' <-
-        clipValid
-            1
-            (if longYear
-                 then 53
-                 else 52)
-            w
-    let k = toModifiedJulianDay (fromOrdinalDate y 6)
-    return (ModifiedJulianDay (k - (mod k 7) + (toInteger ((w' * 7) + d')) - 10))
+fromWeekDateValid :: Year -> WeekOfYear -> Int -> Maybe Day
+fromWeekDateValid y wy dwr = do
+    dw <- clipValid 1 7 dwr
+    fromWeekCalendarValid FirstMostWeek Monday y wy (toEnum dw)
 
 -- | Show in ISO 8601 Week Date format as yyyy-Www-d (e.g. \"2006-W46-3\").
 showWeekDate :: Day -> String
diff --git a/lib/Data/Time/Clock.hs b/lib/Data/Time/Clock.hs
--- a/lib/Data/Time/Clock.hs
+++ b/lib/Data/Time/Clock.hs
@@ -1,13 +1,42 @@
+{-# LANGUAGE Safe #-}
+
 -- | Types and functions for UTC and UT1
-module Data.Time.Clock
-    ( module Data.Time.Clock.Internal.UniversalTime
-    , module Data.Time.Clock.Internal.DiffTime
-    , module Data.Time.Clock.Internal.UTCTime
-    , module Data.Time.Clock.Internal.NominalDiffTime
-    , module Data.Time.Clock.Internal.UTCDiff
-    , getCurrentTime
-    , getTime_resolution
-    ) where
+module Data.Time.Clock (
+    -- * Universal Time
+
+    -- | Time as measured by the Earth.
+    UniversalTime (..),
+
+    -- * Absolute intervals
+    DiffTime,
+    pattern Picoseconds,
+    pattern Seconds,
+    pattern Minutes,
+    pattern Hours,
+    secondsToDiffTime,
+    picosecondsToDiffTime,
+    diffTimeToPicoseconds,
+
+    -- * UTC
+
+    -- | UTC is time as measured by a clock, corrected to keep pace with the earth by adding or removing
+    -- occasional seconds, known as \"leap seconds\".
+    -- These corrections are not predictable and are announced with six month's notice.
+    -- No table of these corrections is provided, as any program compiled with it would become
+    -- out of date in six months.
+    --
+    -- If you don't care about leap seconds, use 'UTCTime' and 'NominalDiffTime' for your clock calculations,
+    -- and you'll be fine.
+    UTCTime (..),
+    NominalDiffTime,
+    pattern Nominal,
+    secondsToNominalDiffTime,
+    nominalDiffTimeToSeconds,
+    nominalDay,
+    module Data.Time.Clock.Internal.UTCDiff,
+    getCurrentTime,
+    getTime_resolution,
+) where
 
 import Data.Time.Clock.Internal.DiffTime
 import Data.Time.Clock.Internal.NominalDiffTime
diff --git a/lib/Data/Time/Clock/Internal/AbsoluteTime.hs b/lib/Data/Time/Clock/Internal/AbsoluteTime.hs
--- a/lib/Data/Time/Clock/Internal/AbsoluteTime.hs
+++ b/lib/Data/Time/Clock/Internal/AbsoluteTime.hs
@@ -1,23 +1,23 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
 -- | TAI and leap-second maps for converting to UTC: most people won't need this module.
-module Data.Time.Clock.Internal.AbsoluteTime
-    (
-    -- TAI arithmetic
-      AbsoluteTime
-    , taiEpoch
-    , addAbsoluteTime
-    , diffAbsoluteTime
-    , taiNominalDayStart
-    ) where
+module Data.Time.Clock.Internal.AbsoluteTime where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Time.Calendar.Days
 import Data.Time.Clock.Internal.DiffTime
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | AbsoluteTime is TAI, time as measured by a clock.
-newtype AbsoluteTime =
-    MkAbsoluteTime DiffTime
-    deriving (Eq, Ord, Data, Typeable)
+newtype AbsoluteTime
+    = MkAbsoluteTime DiffTime
+    deriving (Eq, Ord, Typeable, Data, TH.Lift)
 
 instance NFData AbsoluteTime where
     rnf (MkAbsoluteTime a) = rnf a
diff --git a/lib/Data/Time/Clock/Internal/CTimespec.hsc b/lib/Data/Time/Clock/Internal/CTimespec.hsc
--- a/lib/Data/Time/Clock/Internal/CTimespec.hsc
+++ b/lib/Data/Time/Clock/Internal/CTimespec.hsc
@@ -1,16 +1,21 @@
+#if !defined(javascript_HOST_ARCH)
+{-# LANGUAGE CApiFFI #-}
+#endif
+
 module Data.Time.Clock.Internal.CTimespec where
 
 #include "HsTimeConfig.h"
 
-#if !defined(mingw32_HOST_OS) && HAVE_CLOCK_GETTIME
+#if !defined(mingw32_HOST_OS) && HAVE_CLOCK_GETTIME && !defined(__MHS__)
 
 import Foreign
 import Foreign.C
 import System.IO.Unsafe
+import System.Posix.Types
 
 #include <time.h>
 
-type ClockID = #{type clockid_t}
+type ClockID = CClockId
 
 data CTimespec = MkCTimespec CTime CLong
 
@@ -25,13 +30,37 @@
         #{poke struct timespec, tv_sec } p s
         #{poke struct timespec, tv_nsec} p ns
 
+#if defined(javascript_HOST_ARCH)
+
 foreign import ccall unsafe "time.h clock_gettime"
     clock_gettime :: ClockID -> Ptr CTimespec -> IO CInt
-foreign import ccall unsafe "time.h clock_getres"
+
+#else /* defined(javascript_HOST_ARCH) */
+
+foreign import capi unsafe "time.h clock_gettime"
+    clock_gettime :: ClockID -> Ptr CTimespec -> IO CInt
+
+#endif /* defined(javascript_HOST_ARCH) */
+
+-- | Get the current time from the given clock.
+clockGetTime :: ClockID -> IO CTimespec
+clockGetTime clockid = alloca (\ptspec -> do
+    throwErrnoIfMinus1_ "clock_gettime" $ clock_gettime clockid ptspec
+    peek ptspec
+    )
+
+#if defined(javascript_HOST_ARCH)
+
+clockGetRes :: ClockID -> IO (Either Errno CTimespec)
+clockGetRes _ = return $ Right $ MkCTimespec 0 0
+
+#else /* defined(javascript_HOST_ARCH) */
+
+foreign import capi unsafe "time.h clock_getres"
     clock_getres :: ClockID -> Ptr CTimespec -> IO CInt
 
 -- | Get the resolution of the given clock.
-clockGetRes :: #{type clockid_t} -> IO (Either Errno CTimespec)
+clockGetRes :: ClockID -> IO (Either Errno CTimespec)
 clockGetRes clockid = alloca $ \ptspec -> do
     rc <- clock_getres clockid ptspec
     case rc of
@@ -42,18 +71,23 @@
             errno <- getErrno
             return $ Left errno
 
--- | Get the current time from the given clock.
-clockGetTime :: ClockID -> IO CTimespec
-clockGetTime clockid = alloca (\ptspec -> do
-    throwErrnoIfMinus1_ "clock_gettime" $ clock_gettime clockid ptspec
-    peek ptspec
-    )
+#endif /* defined(javascript_HOST_ARCH) */
 
+#if defined(javascript_HOST_ARCH)
+-- JS backend doesn't support foreign imports with capi convention
 clock_REALTIME :: ClockID
 clock_REALTIME = #{const CLOCK_REALTIME}
+#else /* defined(javascript_HOST_ARCH) */
+foreign import capi unsafe "HsTime.h value HS_CLOCK_REALTIME" clock_REALTIME :: ClockID
+#endif /* defined(javascript_HOST_ARCH) */
 
-clock_TAI :: ClockID
-clock_TAI = #{const 11}
+clock_TAI :: Maybe ClockID
+clock_TAI =
+#if defined(CLOCK_TAI)
+    Just #{const CLOCK_TAI}
+#else /* defined(CLOCK_TAI) */
+    Nothing
+#endif /* defined(CLOCK_TAI) */
 
 realtimeRes :: CTimespec
 realtimeRes = unsafePerformIO $ do
@@ -69,4 +103,5 @@
         Left _ -> return Nothing
         Right res -> return $ Just res
 
-#endif
+#endif /* !defined(mingw32_HOST_OS) && HAVE_CLOCK_GETTIME */
+
diff --git a/lib/Data/Time/Clock/Internal/CTimeval.hs b/lib/Data/Time/Clock/Internal/CTimeval.hs
--- a/lib/Data/Time/Clock/Internal/CTimeval.hs
+++ b/lib/Data/Time/Clock/Internal/CTimeval.hs
@@ -1,4 +1,11 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+#if !defined(javascript_HOST_ARCH)
+{-# LANGUAGE CApiFFI #-}
+#endif
+
 module Data.Time.Clock.Internal.CTimeval where
+
 #ifndef mingw32_HOST_OS
 -- All Unix-specific, this
 import Foreign
@@ -19,7 +26,15 @@
         pokeElemOff (castPtr p) 0 s
         pokeElemOff (castPtr p) 1 mus
 
-foreign import ccall unsafe "time.h gettimeofday" gettimeofday :: Ptr CTimeval -> Ptr () -> IO CInt
+#if defined(javascript_HOST_ARCH) || defined(__MHS__)
+
+foreign import ccall unsafe "sys/time.h gettimeofday" gettimeofday :: Ptr CTimeval -> Ptr () -> IO CInt
+
+#else
+
+foreign import capi unsafe "sys/time.h gettimeofday" gettimeofday :: Ptr CTimeval -> Ptr () -> IO CInt
+
+#endif
 
 -- | Get the current POSIX time from the system clock.
 getCTimeval :: IO CTimeval
diff --git a/lib/Data/Time/Clock/Internal/DiffTime.hs b/lib/Data/Time/Clock/Internal/DiffTime.hs
--- a/lib/Data/Time/Clock/Internal/DiffTime.hs
+++ b/lib/Data/Time/Clock/Internal/DiffTime.hs
@@ -1,34 +1,34 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Trustworthy #-}
-{-# OPTIONS -fno-warn-unused-imports #-}
 
-module Data.Time.Clock.Internal.DiffTime
-    (
-    -- * Absolute intervals
-      DiffTime
-    , secondsToDiffTime
-    , picosecondsToDiffTime
-    , diffTimeToPicoseconds
-    ) where
+module Data.Time.Clock.Internal.DiffTime where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Fixed
-import Data.Ratio ((%))
-import Data.Typeable
+#ifdef __GLASGOW_HASKELL__
+import GHC.Read
+#endif
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
+import Text.ParserCombinators.ReadP
+import Text.Read
 
 -- | This is a length of time, as measured by a clock.
--- Conversion functions will treat it as seconds.
--- It has a precision of 10^-12 s.
-newtype DiffTime =
-    MkDiffTime Pico
-    deriving (Eq, Ord, Data, Typeable)
+-- Conversion functions such as 'fromInteger' and 'realToFrac' will treat it as seconds.
+-- For example, @(0.010 :: DiffTime)@ corresponds to 10 milliseconds.
+--
+-- It has a precision of one picosecond (= 10^-12 s). Enumeration functions will treat it as picoseconds.
+newtype DiffTime
+    = MkDiffTime Pico
+    deriving (Eq, Ord, Typeable, Data, TH.Lift)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
-instance NFData DiffTime -- FIXME: Data.Fixed had no NFData instances yet at time of writing
-                                                                                             where
-    rnf dt = seq dt ()
+instance NFData DiffTime where
+    rnf (MkDiffTime t) = rnf t
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Enum DiffTime where
     succ (MkDiffTime a) = MkDiffTime (succ a)
     pred (MkDiffTime a) = MkDiffTime (pred a)
@@ -42,7 +42,12 @@
 instance Show DiffTime where
     show (MkDiffTime t) = (showFixed True t) ++ "s"
 
--- necessary because H98 doesn't have "cunning newtype" derivation
+instance Read DiffTime where
+    readPrec = do
+        t <- readPrec
+        _ <- lift $ char 's'
+        return $ MkDiffTime t
+
 instance Num DiffTime where
     (MkDiffTime a) + (MkDiffTime b) = MkDiffTime (a + b)
     (MkDiffTime a) - (MkDiffTime b) = MkDiffTime (a - b)
@@ -52,26 +57,51 @@
     signum (MkDiffTime a) = MkDiffTime (signum a)
     fromInteger i = MkDiffTime (fromInteger i)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Real DiffTime where
     toRational (MkDiffTime a) = toRational a
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Fractional DiffTime where
     (MkDiffTime a) / (MkDiffTime b) = MkDiffTime (a / b)
     recip (MkDiffTime a) = MkDiffTime (recip a)
     fromRational r = MkDiffTime (fromRational r)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance RealFrac DiffTime where
-    properFraction (MkDiffTime a) = let
-        (b', a') = properFraction a
-        in (b', MkDiffTime a')
+    properFraction (MkDiffTime a) =
+        let
+            (b', a') = properFraction a
+        in
+            (b', MkDiffTime a')
     truncate (MkDiffTime a) = truncate a
     round (MkDiffTime a) = round a
     ceiling (MkDiffTime a) = ceiling a
     floor (MkDiffTime a) = floor a
 
+pattern Picoseconds :: Integer -> DiffTime
+pattern Picoseconds a <- (diffTimeToPicoseconds -> a)
+    where
+        Picoseconds a = picosecondsToDiffTime a
+
+{-# COMPLETE Picoseconds #-}
+
+pattern Seconds :: Pico -> DiffTime
+pattern Seconds a = MkDiffTime a
+
+{-# COMPLETE Seconds #-}
+
+pattern Minutes :: Pico -> DiffTime
+pattern Minutes a <- Seconds ((/ 60) -> a)
+    where
+        Minutes a = Seconds $ a * 60
+
+{-# COMPLETE Minutes #-}
+
+pattern Hours :: Pico -> DiffTime
+pattern Hours a <- Minutes ((/ 60) -> a)
+    where
+        Hours a = Minutes $ a * 60
+
+{-# COMPLETE Hours #-}
+
 -- | Create a 'DiffTime' which represents an integral number of seconds.
 secondsToDiffTime :: Integer -> DiffTime
 secondsToDiffTime = fromInteger
@@ -85,6 +115,6 @@
 diffTimeToPicoseconds (MkDiffTime (MkFixed x)) = x
 
 {-# RULES
-"realToFrac/DiffTime->Pico" realToFrac = \ (MkDiffTime ps) -> ps
+"realToFrac/DiffTime->Pico" realToFrac = \(MkDiffTime ps) -> ps
 "realToFrac/Pico->DiffTime" realToFrac = MkDiffTime
- #-}
+    #-}
diff --git a/lib/Data/Time/Clock/Internal/NominalDiffTime.hs b/lib/Data/Time/Clock/Internal/NominalDiffTime.hs
--- a/lib/Data/Time/Clock/Internal/NominalDiffTime.hs
+++ b/lib/Data/Time/Clock/Internal/NominalDiffTime.hs
@@ -1,32 +1,46 @@
-{-# OPTIONS -fno-warn-unused-imports #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Trustworthy #-}
 
-module Data.Time.Clock.Internal.NominalDiffTime
-    ( NominalDiffTime
-    , secondsToNominalDiffTime
-    , nominalDiffTimeToSeconds
-    , nominalDay
-    ) where
+module Data.Time.Clock.Internal.NominalDiffTime where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Fixed
-import Data.Time.Calendar.Days
-import Data.Typeable
+#ifdef __GLASGOW_HASKELL__
+import GHC.Read
+#endif
+import Data.Time.Clock.Internal.DiffTime
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
+import Text.ParserCombinators.ReadP
+import Text.ParserCombinators.ReadPrec
 
 -- | This is a length of time, as measured by UTC.
--- It has a precision of 10^-12 s.
+-- It has a precision of one picosecond (10^-12 s).
 --
--- Conversion functions will treat it as seconds.
+-- Conversion functions such as 'fromInteger' and 'realToFrac' will treat it as seconds.
 -- For example, @(0.010 :: NominalDiffTime)@ corresponds to 10 milliseconds.
 --
+-- Enumeration functions will treat it as picoseconds.
+--
 -- It ignores leap-seconds, so it's not necessarily a fixed amount of clock time.
 -- For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 day),
 -- regardless of whether a leap-second intervened.
-newtype NominalDiffTime =
-    MkNominalDiffTime Pico
-    deriving (Eq, Ord, Data, Typeable)
+newtype NominalDiffTime
+    = MkNominalDiffTime Pico
+    deriving (Eq, Ord, Typeable, Data, TH.Lift)
 
+-- | convert from DiffTime
+pattern Nominal :: DiffTime -> NominalDiffTime
+pattern Nominal dt <- MkNominalDiffTime (realToFrac -> dt)
+    where
+        Nominal dt = MkNominalDiffTime $ realToFrac dt
+
+{-# COMPLETE Nominal #-}
+
 -- | Create a 'NominalDiffTime' from a number of seconds.
 --
 -- @since 1.9.1
@@ -39,10 +53,8 @@
 nominalDiffTimeToSeconds :: NominalDiffTime -> Pico
 nominalDiffTimeToSeconds (MkNominalDiffTime t) = t
 
--- necessary because H98 doesn't have "cunning newtype" derivation
-instance NFData NominalDiffTime -- FIXME: Data.Fixed had no NFData instances yet at time of writing
-                                                                                                    where
-    rnf ndt = seq ndt ()
+instance NFData NominalDiffTime where
+    rnf (MkNominalDiffTime t) = rnf t
 
 instance Enum NominalDiffTime where
     succ (MkNominalDiffTime a) = MkNominalDiffTime (succ a)
@@ -58,7 +70,12 @@
 instance Show NominalDiffTime where
     show (MkNominalDiffTime t) = (showFixed True t) ++ "s"
 
--- necessary because H98 doesn't have "cunning newtype" derivation
+instance Read NominalDiffTime where
+    readPrec = do
+        t <- readPrec
+        _ <- lift $ char 's'
+        return $ MkNominalDiffTime t
+
 instance Num NominalDiffTime where
     (MkNominalDiffTime a) + (MkNominalDiffTime b) = MkNominalDiffTime (a + b)
     (MkNominalDiffTime a) - (MkNominalDiffTime b) = MkNominalDiffTime (a - b)
@@ -68,17 +85,14 @@
     signum (MkNominalDiffTime a) = MkNominalDiffTime (signum a)
     fromInteger i = MkNominalDiffTime (fromInteger i)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Real NominalDiffTime where
     toRational (MkNominalDiffTime a) = toRational a
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance Fractional NominalDiffTime where
     (MkNominalDiffTime a) / (MkNominalDiffTime b) = MkNominalDiffTime (a / b)
     recip (MkNominalDiffTime a) = MkNominalDiffTime (recip a)
     fromRational r = MkNominalDiffTime (fromRational r)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance RealFrac NominalDiffTime where
     properFraction (MkNominalDiffTime a) = (i, MkNominalDiffTime f)
       where
@@ -89,14 +103,17 @@
     floor (MkNominalDiffTime a) = floor a
 
 {-# RULES
-"realToFrac/DiffTime->NominalDiffTime" realToFrac =
-                                       \ dt -> MkNominalDiffTime (realToFrac dt)
-"realToFrac/NominalDiffTime->DiffTime" realToFrac =
-                                       \ (MkNominalDiffTime ps) -> realToFrac ps
-"realToFrac/NominalDiffTime->Pico" realToFrac =
-                                   \ (MkNominalDiffTime ps) -> ps
+"realToFrac/DiffTime->NominalDiffTime"
+    realToFrac =
+        \dt -> MkNominalDiffTime (realToFrac dt)
+"realToFrac/NominalDiffTime->DiffTime"
+    realToFrac =
+        \(MkNominalDiffTime ps) -> realToFrac ps
+"realToFrac/NominalDiffTime->Pico"
+    realToFrac =
+        \(MkNominalDiffTime ps) -> ps
 "realToFrac/Pico->NominalDiffTime" realToFrac = MkNominalDiffTime
- #-}
+    #-}
 
 -- | One day in 'NominalDiffTime'.
 nominalDay :: NominalDiffTime
diff --git a/lib/Data/Time/Clock/Internal/POSIXTime.hs b/lib/Data/Time/Clock/Internal/POSIXTime.hs
--- a/lib/Data/Time/Clock/Internal/POSIXTime.hs
+++ b/lib/Data/Time/Clock/Internal/POSIXTime.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE Safe #-}
+
 module Data.Time.Clock.Internal.POSIXTime where
 
 import Data.Time.Clock.Internal.NominalDiffTime
@@ -9,5 +11,4 @@
 -- | POSIX time is the nominal time since 1970-01-01 00:00 UTC
 --
 -- To convert from a 'Foreign.C.Types.CTime' or @System.Posix.EpochTime@, use 'realToFrac'.
---
 type POSIXTime = NominalDiffTime
diff --git a/lib/Data/Time/Clock/Internal/SystemTime.hs b/lib/Data/Time/Clock/Internal/SystemTime.hs
--- a/lib/Data/Time/Clock/Internal/SystemTime.hs
+++ b/lib/Data/Time/Clock/Internal/SystemTime.hs
@@ -1,23 +1,37 @@
-{-# OPTIONS -fno-warn-trustworthy-safe #-}
+{-# LANGUAGE CPP #-}
+
+#if !defined(__MHS__)
+#include "HsTimeConfig.h"
+#endif
+
+#if defined(mingw32_HOST_OS) || !defined(HAVE_CLOCK_GETTIME)
+{-# LANGUAGE Safe #-}
+#else
 {-# LANGUAGE Trustworthy #-}
+#endif
 
-module Data.Time.Clock.Internal.SystemTime
-    ( SystemTime(..)
-    , getSystemTime
-    , getTime_resolution
-    , getTAISystemTime
-    ) where
+module Data.Time.Clock.Internal.SystemTime (
+    SystemTime (..),
+    getSystemTime,
+    getTime_resolution,
+    getTAISystemTime,
+) where
 
-import Data.Data
 import Control.DeepSeq
+import Data.Data
 import Data.Int (Int64)
 import Data.Time.Clock.Internal.DiffTime
 import Data.Word
-#include "HsTimeConfig.h"
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 #ifdef mingw32_HOST_OS
 import qualified System.Win32.Time as Win32
-#elif defined(HAVE_CLOCK_GETTIME)
+#elif defined(HAVE_CLOCK_GETTIME) && !defined(__MHS__)
 import Data.Time.Clock.Internal.CTimespec
 import Foreign.C.Types (CLong(..), CTime(..))
 #else
@@ -30,9 +44,10 @@
 -- Its semantics depends on the clock function, but the epoch is typically the beginning of 1970.
 -- Note that 'systemNanoseconds' of 1E9 to 2E9-1 can be used to represent leap seconds.
 data SystemTime = MkSystemTime
-    { systemSeconds :: {-# UNPACK #-}!Int64
-    , systemNanoseconds :: {-# UNPACK #-}!Word32
-    } deriving (Eq, Ord, Show, Data, Typeable)
+    { systemSeconds :: {-# UNPACK #-} !Int64
+    , systemNanoseconds :: {-# UNPACK #-} !Word32
+    }
+    deriving (Eq, Ord, Show, Typeable, Data, Generic, TH.Lift)
 
 instance NFData SystemTime where
     rnf a = a `seq` ()
@@ -40,13 +55,17 @@
 -- | Get the system time, epoch start of 1970 UTC, leap-seconds ignored.
 -- 'getSystemTime' is typically much faster than 'getCurrentTime'.
 getSystemTime :: IO SystemTime
--- | The resolution of 'getSystemTime', 'getCurrentTime', 'getPOSIXTime'
+
+-- | The resolution of 'getSystemTime', 'getCurrentTime', 'getPOSIXTime'.
+-- On UNIX systems this uses @clock_getres@, which may be <https://github.com/microsoft/WSL/issues/6029 wrong on WSL2>.
 getTime_resolution :: DiffTime
+
 -- | If supported, get TAI time, epoch start of 1970 TAI, with resolution.
 -- This is supported only on UNIX systems, and only those with CLOCK_TAI available at run-time.
 getTAISystemTime :: Maybe (DiffTime, IO SystemTime)
+
 #ifdef mingw32_HOST_OS
--- On Windows, the equlvalent of POSIX time is "file time", defined as
+-- On Windows, the equivalent 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.
@@ -61,7 +80,7 @@
 getTime_resolution = 100E-9 -- 100ns
 
 getTAISystemTime = Nothing
-#elif defined(HAVE_CLOCK_GETTIME)
+#elif defined(HAVE_CLOCK_GETTIME) && !defined(__MHS__)
 -- Use hi-res clock_gettime
 timespecToSystemTime :: CTimespec -> SystemTime
 timespecToSystemTime (MkCTimespec (CTime s) (CLong ns)) = (MkSystemTime (fromIntegral s) (fromIntegral ns))
@@ -76,8 +95,10 @@
 
 getTime_resolution = timespecToDiffTime realtimeRes
 
-getTAISystemTime =
-    fmap (\resolution -> (timespecToDiffTime resolution, clockGetSystemTime clock_TAI)) $ clockResolution clock_TAI
+getTAISystemTime = do
+    clockID <- clock_TAI
+    resolution <- clockResolution clockID
+    return $ (timespecToDiffTime resolution, clockGetSystemTime clockID)
 #else
 -- Use gettimeofday
 getSystemTime = do
diff --git a/lib/Data/Time/Clock/Internal/UTCDiff.hs b/lib/Data/Time/Clock/Internal/UTCDiff.hs
--- a/lib/Data/Time/Clock/Internal/UTCDiff.hs
+++ b/lib/Data/Time/Clock/Internal/UTCDiff.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE Safe #-}
+
 module Data.Time.Clock.Internal.UTCDiff where
 
 import Data.Time.Clock.Internal.NominalDiffTime
diff --git a/lib/Data/Time/Clock/Internal/UTCTime.hs b/lib/Data/Time/Clock/Internal/UTCTime.hs
--- a/lib/Data/Time/Clock/Internal/UTCTime.hs
+++ b/lib/Data/Time/Clock/Internal/UTCTime.hs
@@ -1,38 +1,29 @@
-module Data.Time.Clock.Internal.UTCTime
-    (
-    -- * UTC
-    -- | UTC is time as measured by a clock, corrected to keep pace with the earth by adding or removing
-    -- occasional seconds, known as \"leap seconds\".
-    -- These corrections are not predictable and are announced with six month's notice.
-    -- No table of these corrections is provided, as any program compiled with it would become
-    -- out of date in six months.
-    --
-    -- If you don't care about leap seconds, use 'UTCTime' and 'NominalDiffTime' for your clock calculations,
-    -- and you'll be fine.
-      UTCTime(..)
-    ) where
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Clock.Internal.UTCTime where
+
 import Control.DeepSeq
 import Data.Data
 import Data.Time.Calendar.Days
 import Data.Time.Clock.Internal.DiffTime
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | This is the simplest representation of UTC.
 -- It consists of the day number, and a time offset from midnight.
 -- Note that if a day has a leap second added to it, it will have 86401 seconds.
 data UTCTime = UTCTime
-    { utctDay :: Day -- ^ the day
-    , utctDayTime :: DiffTime -- ^ the time from midnight, 0 <= t < 86401s (because of leap-seconds)
-    } deriving (Data, Typeable)
+    { utctDay :: Day
+    -- ^ the day
+    , utctDayTime :: DiffTime
+    -- ^ the time from midnight, 0 <= t < 86401s (because of leap-seconds)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
 instance NFData UTCTime where
     rnf (UTCTime d t) = rnf d `seq` rnf t `seq` ()
-
-instance Eq UTCTime where
-    (UTCTime da ta) == (UTCTime db tb) = (da == db) && (ta == tb)
-
-instance Ord UTCTime where
-    compare (UTCTime da ta) (UTCTime db tb) =
-        case (compare da db) of
-            EQ -> compare ta tb
-            cmp -> cmp
diff --git a/lib/Data/Time/Clock/Internal/UniversalTime.hs b/lib/Data/Time/Clock/Internal/UniversalTime.hs
--- a/lib/Data/Time/Clock/Internal/UniversalTime.hs
+++ b/lib/Data/Time/Clock/Internal/UniversalTime.hs
@@ -1,19 +1,23 @@
-module Data.Time.Clock.Internal.UniversalTime
-    (
-    -- * Universal Time
-    -- | Time as measured by the Earth.
-      UniversalTime(..)
-    ) where
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Clock.Internal.UniversalTime where
+
 import Control.DeepSeq
 import Data.Data
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | The Modified Julian Date is the day with the fraction of the day, measured from UT midnight.
 -- It's used to represent UT1, which is time as measured by the earth's rotation, adjusted for various wobbles.
 newtype UniversalTime = ModJulianDate
     { getModJulianDate :: Rational
-    } deriving (Eq, Ord, Data, Typeable)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
--- necessary because H98 doesn't have "cunning newtype" derivation
 instance NFData UniversalTime where
     rnf (ModJulianDate a) = rnf a
diff --git a/lib/Data/Time/Clock/POSIX.hs b/lib/Data/Time/Clock/POSIX.hs
--- a/lib/Data/Time/Clock/POSIX.hs
+++ b/lib/Data/Time/Clock/POSIX.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE Safe #-}
+
 -- | POSIX time, if you need to deal with timestamps and the like.
 -- Most people won't need this module.
 --
@@ -15,15 +17,15 @@
 -- > main = do
 -- >     u <- getCurrentTime
 -- >     print $ nanosSinceEpoch u
-module Data.Time.Clock.POSIX
-    ( posixDayLength
-    , POSIXTime
-    , posixSecondsToUTCTime
-    , utcTimeToPOSIXSeconds
-    , getPOSIXTime
-    , getCurrentTime
-    , systemToPOSIXTime
-    ) where
+module Data.Time.Clock.POSIX (
+    posixDayLength,
+    POSIXTime,
+    posixSecondsToUTCTime,
+    utcTimeToPOSIXSeconds,
+    getPOSIXTime,
+    getCurrentTime,
+    systemToPOSIXTime,
+) where
 
 import Data.Fixed
 import Data.Time.Calendar.Days
@@ -32,9 +34,11 @@
 import Data.Time.Clock.System
 
 posixSecondsToUTCTime :: POSIXTime -> UTCTime
-posixSecondsToUTCTime i = let
-    (d, t) = divMod' i posixDayLength
-    in UTCTime (addDays d systemEpochDay) (realToFrac t)
+posixSecondsToUTCTime i =
+    let
+        (d, t) = divMod' i posixDayLength
+    in
+        UTCTime (addDays d systemEpochDay) (realToFrac t)
 
 utcTimeToPOSIXSeconds :: UTCTime -> POSIXTime
 utcTimeToPOSIXSeconds (UTCTime d t) =
diff --git a/lib/Data/Time/Clock/System.hs b/lib/Data/Time/Clock/System.hs
--- a/lib/Data/Time/Clock/System.hs
+++ b/lib/Data/Time/Clock/System.hs
@@ -1,13 +1,15 @@
+{-# LANGUAGE Safe #-}
+
 -- | Fast access to the system clock.
-module Data.Time.Clock.System
-    ( systemEpochDay
-    , SystemTime(..)
-    , truncateSystemTimeLeapSecond
-    , getSystemTime
-    , systemToUTCTime
-    , utcToSystemTime
-    , systemToTAITime
-    ) where
+module Data.Time.Clock.System (
+    systemEpochDay,
+    SystemTime (..),
+    truncateSystemTimeLeapSecond,
+    getSystemTime,
+    systemToUTCTime,
+    utcToSystemTime,
+    systemToTAITime,
+) where
 
 import Data.Int (Int64)
 import Data.Time.Calendar.Days
@@ -25,48 +27,54 @@
 
 -- | Convert 'SystemTime' to 'UTCTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' UTC.
 systemToUTCTime :: SystemTime -> UTCTime
-systemToUTCTime (MkSystemTime seconds nanoseconds) = let
-    days :: Int64
-    timeSeconds :: Int64
-    (days, timeSeconds) = seconds `divMod` 86400
-    day :: Day
-    day = addDays (fromIntegral days) systemEpochDay
-    timeNanoseconds :: Int64
-    timeNanoseconds = timeSeconds * 1000000000 + (fromIntegral nanoseconds)
-    timePicoseconds :: Int64
-    timePicoseconds = timeNanoseconds * 1000
-    time :: DiffTime
-    time = picosecondsToDiffTime $ fromIntegral timePicoseconds
-    in UTCTime day time
+systemToUTCTime (MkSystemTime seconds nanoseconds) =
+    let
+        days :: Int64
+        timeSeconds :: Int64
+        (days, timeSeconds) = seconds `divMod` 86400
+        day :: Day
+        day = addDays (fromIntegral days) systemEpochDay
+        timeNanoseconds :: Int64
+        timeNanoseconds = timeSeconds * 1000000000 + (fromIntegral nanoseconds)
+        timePicoseconds :: Int64
+        timePicoseconds = timeNanoseconds * 1000
+        time :: DiffTime
+        time = picosecondsToDiffTime $ fromIntegral timePicoseconds
+    in
+        UTCTime day time
 
 -- | Convert 'UTCTime' to 'SystemTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' UTC.
 utcToSystemTime :: UTCTime -> SystemTime
-utcToSystemTime (UTCTime day time) = let
-    days :: Int64
-    days = fromIntegral $ diffDays day systemEpochDay
-    timePicoseconds :: Int64
-    timePicoseconds = fromIntegral $ diffTimeToPicoseconds time
-    timeNanoseconds :: Int64
-    timeNanoseconds = timePicoseconds `div` 1000
-    timeSeconds :: Int64
-    nanoseconds :: Int64
-    (timeSeconds, nanoseconds) =
-        if timeNanoseconds >= 86400000000000
-            then (86399, timeNanoseconds - 86399000000000)
-            else timeNanoseconds `divMod` 1000000000
-    seconds :: Int64
-    seconds = days * 86400 + timeSeconds
-    in MkSystemTime seconds $ fromIntegral nanoseconds
+utcToSystemTime (UTCTime day time) =
+    let
+        days :: Int64
+        days = fromIntegral $ diffDays day systemEpochDay
+        timePicoseconds :: Int64
+        timePicoseconds = fromIntegral $ diffTimeToPicoseconds time
+        timeNanoseconds :: Int64
+        timeNanoseconds = timePicoseconds `div` 1000
+        timeSeconds :: Int64
+        nanoseconds :: Int64
+        (timeSeconds, nanoseconds) =
+            if timeNanoseconds >= 86400000000000
+                then (86399, timeNanoseconds - 86399000000000)
+                else timeNanoseconds `divMod` 1000000000
+        seconds :: Int64
+        seconds = days * 86400 + timeSeconds
+    in
+        MkSystemTime seconds $ fromIntegral nanoseconds
 
 systemEpochAbsolute :: AbsoluteTime
 systemEpochAbsolute = taiNominalDayStart systemEpochDay
 
 -- | Convert 'SystemTime' to 'AbsoluteTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' TAI.
 systemToTAITime :: SystemTime -> AbsoluteTime
-systemToTAITime (MkSystemTime s ns) = let
-    diff :: DiffTime
-    diff = (fromIntegral s) + (fromIntegral ns) * 1E-9
-    in addAbsoluteTime diff systemEpochAbsolute
+systemToTAITime (MkSystemTime s ns) =
+    let
+        diff :: DiffTime
+        diff = (fromIntegral s) + (fromIntegral ns) * 1E-9
+    in
+        addAbsoluteTime diff systemEpochAbsolute
 
 -- | The day of the epoch of 'SystemTime', 1970-01-01
 systemEpochDay :: Day
diff --git a/lib/Data/Time/Clock/TAI.hs b/lib/Data/Time/Clock/TAI.hs
--- a/lib/Data/Time/Clock/TAI.hs
+++ b/lib/Data/Time/Clock/TAI.hs
@@ -1,19 +1,25 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
 -- | TAI and leap-second maps for converting to UTC: most people won't need this module.
-module Data.Time.Clock.TAI
-    (
-    -- TAI arithmetic
-      module Data.Time.Clock.Internal.AbsoluteTime
-    -- leap-second map type
-    , LeapSecondMap
-    -- conversion between UTC and TAI with map
-    , utcDayLength
-    , utcToTAITime
-    , taiToUTCTime
-    , taiClock
-    ) where
+module Data.Time.Clock.TAI (
+    -- * Absolute Time
+    AbsoluteTime,
+    taiEpoch,
+    addAbsoluteTime,
+    diffAbsoluteTime,
+    taiNominalDayStart,
 
+    -- * Leap-Second Map
+    LeapSecondMap,
+    utcDayLength,
+    utcToTAITime,
+    taiToUTCTime,
+    taiClock,
+) where
+
 import Data.Fixed
 import Data.Maybe
 import Data.Time.Calendar.Days
@@ -22,6 +28,9 @@
 import Data.Time.Clock.Internal.SystemTime
 import Data.Time.Clock.System
 import Data.Time.LocalTime
+#ifdef __MHS__
+import Data.Tuple.Instances
+#endif
 
 instance Show AbsoluteTime where
     show t = show (utcToLocalTime utc (fromJust (taiToUTCTime (const (Just 0)) t))) ++ " TAI" -- ugly, but standard apparently
@@ -48,17 +57,19 @@
     return $ addAbsoluteTime dtime t
 
 taiToUTCTime :: LeapSecondMap -> AbsoluteTime -> Maybe UTCTime
-taiToUTCTime lsmap abstime = let
-    stable day = do
-        dayt <- dayStart lsmap day
-        len <- utcDayLength lsmap day
-        let
-            dtime = diffAbsoluteTime abstime dayt
-            day' = addDays (div' dtime len) day
-        if day == day'
-            then return (UTCTime day dtime)
-            else stable day'
-    in stable $ ModifiedJulianDay $ div' (diffAbsoluteTime abstime taiEpoch) 86400
+taiToUTCTime lsmap abstime =
+    let
+        stable day = do
+            dayt <- dayStart lsmap day
+            len <- utcDayLength lsmap day
+            let
+                dtime = diffAbsoluteTime abstime dayt
+                day' = addDays (div' dtime len) day
+            if day == day'
+                then return (UTCTime day dtime)
+                else stable day'
+    in
+        stable $ ModifiedJulianDay $ div' (diffAbsoluteTime abstime taiEpoch) 86400
 
 -- | TAI clock, if it exists. Note that it is unlikely to be set correctly, without due care and attention.
 taiClock :: Maybe (DiffTime, IO AbsoluteTime)
diff --git a/lib/Data/Time/Format.hs b/lib/Data/Time/Format.hs
--- a/lib/Data/Time/Format.hs
+++ b/lib/Data/Time/Format.hs
@@ -1,11 +1,28 @@
-module Data.Time.Format
-    (
+{-# LANGUAGE Safe #-}
+
+module Data.Time.Format (
     -- * UNIX-style formatting
-      FormatTime()
-    , formatTime
-    , module Data.Time.Format.Parse
-    ) where
+    FormatTime (),
+    formatTime,
 
+    -- * UNIX-style parsing
+    parseTimeM,
+    parseTimeMultipleM,
+    parseTimeOrError,
+    readSTime,
+    readPTime,
+    ParseTime (),
+
+    -- * Locale
+    TimeLocale (..),
+    defaultTimeLocale,
+    iso8601DateFormat,
+    rfc822DateFormat,
+) where
+
 import Data.Time.Format.Format.Class
 import Data.Time.Format.Format.Instances ()
+import Data.Time.Format.ISO8601 ()
+import Data.Time.Format.Locale
 import Data.Time.Format.Parse
+import Data.Time.Format.Parse.Class
diff --git a/lib/Data/Time/Format/Format/Class.hs b/lib/Data/Time/Format/Format/Class.hs
--- a/lib/Data/Time/Format/Format/Class.hs
+++ b/lib/Data/Time/Format/Format/Class.hs
@@ -1,22 +1,23 @@
-module Data.Time.Format.Format.Class
-    (
-        -- * Formatting
-      formatTime
-    , FormatNumericPadding
-    , FormatOptions(..)
-    , FormatTime(..)
-    , ShowPadded
-    , PadOption
-    , formatGeneral
-    , formatString
-    , formatNumber
-    , formatNumberStd
-    , showPaddedFixed
-    , showPaddedFixedFraction
-    , quotBy
-    , remBy
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Format.Format.Class (
+    -- * Formatting
+    formatTime,
+    FormatNumericPadding,
+    FormatOptions (..),
+    FormatTime (..),
+    ShowPadded,
+    PadOption,
+    formatGeneral,
+    formatString,
+    formatNumber,
+    formatNumberStd,
+    showPaddedFixed,
+    showPaddedFixedFraction,
+    quotBy,
+    remBy,
+) where
+
 import Data.Char
 import Data.Fixed
 import Data.Maybe
@@ -38,43 +39,40 @@
 
 -- the weird UNIX logic is here
 getPadOption :: Bool -> Bool -> Int -> Char -> Maybe FormatNumericPadding -> Maybe Int -> PadOption
-getPadOption trunc fdef idef cdef mnpad mi = let
-    c =
-        case mnpad of
+getPadOption trunc fdef idef cdef mnpad mi =
+    let
+        c = case mnpad of
             Just (Just c') -> c'
             Just Nothing -> ' '
             _ -> cdef
-    i =
-        case mi of
-            Just i' ->
-                case mnpad of
-                    Just Nothing -> i'
-                    _ ->
-                        if trunc
-                            then i'
-                            else max i' idef
+        i = case mi of
+            Just i' -> case mnpad of
+                Just Nothing -> i'
+                _ ->
+                    if trunc
+                        then i'
+                        else max i' idef
             Nothing -> idef
-    f =
-        case mi of
+        f = case mi of
             Just _ -> True
-            Nothing ->
-                case mnpad of
-                    Nothing -> fdef
-                    Just Nothing -> False
-                    Just (Just _) -> True
-    in if f
-           then Pad i c
-           else NoPad
+            Nothing -> case mnpad of
+                Nothing -> fdef
+                Just Nothing -> False
+                Just (Just _) -> True
+    in
+        if f
+            then Pad i c
+            else NoPad
 
 formatGeneral ::
-       Bool -> Bool -> Int -> Char -> (TimeLocale -> PadOption -> t -> String) -> (FormatOptions -> t -> String)
+    Bool -> Bool -> Int -> Char -> (TimeLocale -> PadOption -> t -> String) -> (FormatOptions -> t -> String)
 formatGeneral trunc fdef idef cdef ff fo =
     ff (foLocale fo) $ getPadOption trunc fdef idef cdef (foPadding fo) (foWidth fo)
 
 formatString :: (TimeLocale -> t -> String) -> (FormatOptions -> t -> String)
 formatString ff = formatGeneral False False 1 ' ' $ \locale pado -> showPadded pado . ff locale
 
-formatNumber :: (ShowPadded i) => Bool -> Int -> Char -> (t -> i) -> (FormatOptions -> t -> String)
+formatNumber :: ShowPadded i => Bool -> Int -> Char -> (t -> i) -> (FormatOptions -> t -> String)
 formatNumber fdef idef cdef ff = formatGeneral False fdef idef cdef $ \_ pado -> showPaddedNum pado . ff
 
 formatNumberStd :: Int -> (t -> Integer) -> (FormatOptions -> t -> String)
@@ -83,25 +81,29 @@
 showPaddedFixed :: HasResolution a => PadOption -> PadOption -> Fixed a -> String
 showPaddedFixed padn padf x
     | x < 0 = '-' : showPaddedFixed padn padf (negate x)
-showPaddedFixed padn padf x = let
-    ns = showPaddedNum padn $ (floor x :: Integer)
-    fs = showPaddedFixedFraction padf x
-    ds =
-        if null fs
-            then ""
-            else "."
-    in ns ++ ds ++ fs
+showPaddedFixed padn padf x =
+    let
+        ns = showPaddedNum padn $ (floor x :: Integer)
+        fs = showPaddedFixedFraction padf x
+        ds =
+            if null fs
+                then ""
+                else "."
+    in
+        ns ++ ds ++ fs
 
 showPaddedFixedFraction :: HasResolution a => PadOption -> Fixed a -> String
-showPaddedFixedFraction pado x = let
-    digits = dropWhile (== '.') $ dropWhile (/= '.') $ showFixed True x
-    n = length digits
-    in case pado of
-           NoPad -> digits
-           Pad i c ->
-               if i < n
-                   then take i digits
-                   else digits ++ replicate (i - n) c
+showPaddedFixedFraction pado x =
+    let
+        digits = dropWhile (== '.') $ dropWhile (/= '.') $ showFixed True x
+        n = length digits
+    in
+        case pado of
+            NoPad -> digits
+            Pad i c ->
+                if i < n
+                    then take i digits
+                    else digits ++ replicate (i - n) c
 
 -- | Substitute various time-related information for each %-code in the string, as per 'formatCharacter'.
 --
@@ -209,14 +211,13 @@
 --
 -- [@%A@] day of week, long form ('fst' from 'wDays' @locale@), @Sunday@ - @Saturday@
 --
--- === 'Day'
--- For 'Day' (and 'LocalTime' and 'ZonedTime' and 'UTCTime' and 'UniversalTime'):
---
--- [@%D@] same as @%m\/%d\/%y@
+-- === 'QuarterOfYear'
+-- For 'QuarterOfYear' (and 'Quarter' and 'Month' and 'Day' and 'LocalTime' and 'ZonedTime' and 'UTCTime' and 'UniversalTime'):
 --
--- [@%F@] same as @%Y-%m-%d@
+-- [@%v@] quarter number, @1@ - @4@
 --
--- [@%x@] as 'dateFmt' @locale@ (e.g. @%m\/%d\/%y@)
+-- === 'Quarter'
+-- For 'Quarter' (and 'Month' and 'Day' and 'LocalTime' and 'ZonedTime' and 'UTCTime' and 'UniversalTime'):
 --
 -- [@%Y@] year, no padding. Note @%0Y@ and @%_Y@ pad to four chars
 --
@@ -224,22 +225,41 @@
 --
 -- [@%C@] century, no padding. Note @%0C@ and @%_C@ pad to two chars
 --
+-- [@%v@] quarter number, @1@ - @4@
+--
+--
+-- === 'Month'
+-- For 'Month' (and 'Day' and 'LocalTime' and 'ZonedTime' and 'UTCTime' and 'UniversalTime'):
+--
 -- [@%B@] month name, long form ('fst' from 'months' @locale@), @January@ - @December@
 --
 -- [@%b@, @%h@] month name, short form ('snd' from 'months' @locale@), @Jan@ - @Dec@
 --
 -- [@%m@] month of year, 0-padded to two chars, @01@ - @12@
 --
+-- === 'Day'
+-- For 'Day' (and 'LocalTime' and 'ZonedTime' and 'UTCTime' and 'UniversalTime'):
+--
+-- [@%D@] same as @%m\/%d\/%y@
+--
+-- [@%F@] same as @%Y-%m-%d@
+--
+-- [@%x@] as 'dateFmt' @locale@ (e.g. @%m\/%d\/%y@)
+--
 -- [@%d@] day of month, 0-padded to two chars, @01@ - @31@
 --
 -- [@%e@] day of month, space-padded to two chars,  @ 1@ - @31@
 --
 -- [@%j@] day of year, 0-padded to three chars, @001@ - @366@
 --
--- [@%f@] century for Week Date format, no padding. Note @%0f@ and @%_f@ pad to two chars
+-- [@%G@] year for ISO 8601 Week Date format. Note @%0G@ and @%_G@ pad to four chars
 --
--- [@%V@] week of year for Week Date format, 0-padded to two chars, @01@ - @53@
+-- [@%g@] year of century for ISO 8601 Week Date format, 0-padded to two chars, @00@ - @99@
 --
+-- [@%f@] century for ISO 8601 Week Date format, no padding. Note @%0f@ and @%_f@ pad to two chars
+--
+-- [@%V@] week of year for ISO 8601 Week Date format, 0-padded to two chars, @01@ - @53@
+--
 -- [@%U@] week of year where weeks start on Sunday (as 'sundayStartWeek'), 0-padded to two chars, @00@ - @53@
 --
 -- [@%W@] week of year where weeks start on Monday (as 'mondayStartWeek'), 0-padded to two chars, @00@ - @53@
@@ -322,20 +342,20 @@
 -- For a whole number of seconds, @%ES@ omits the decimal point unless padding is specified.
 --
 -- [@%0ES@] seconds of minute as two digits, with decimal point and \<width\> (default 12) decimal places.
-formatTime :: (FormatTime t) => TimeLocale -> String -> t -> String
+formatTime :: FormatTime t => TimeLocale -> String -> t -> String
 formatTime _ [] _ = ""
-formatTime locale ('%':cs) t =
+formatTime locale ('%' : cs) t =
     case formatTime1 locale cs t of
         Just result -> result
         Nothing -> '%' : (formatTime locale cs t)
-formatTime locale (c:cs) t = c : (formatTime locale cs t)
+formatTime locale (c : cs) t = c : (formatTime locale cs t)
 
-formatTime1 :: (FormatTime t) => TimeLocale -> String -> t -> Maybe String
-formatTime1 locale ('_':cs) t = formatTime2 locale id (Just (Just ' ')) cs t
-formatTime1 locale ('-':cs) t = formatTime2 locale id (Just Nothing) cs t
-formatTime1 locale ('0':cs) t = formatTime2 locale id (Just (Just '0')) cs t
-formatTime1 locale ('^':cs) t = formatTime2 locale (fmap toUpper) Nothing cs t
-formatTime1 locale ('#':cs) t = formatTime2 locale (fmap toLower) Nothing cs t
+formatTime1 :: FormatTime t => TimeLocale -> String -> t -> Maybe String
+formatTime1 locale ('_' : cs) t = formatTime2 locale id (Just (Just ' ')) cs t
+formatTime1 locale ('-' : cs) t = formatTime2 locale id (Just Nothing) cs t
+formatTime1 locale ('0' : cs) t = formatTime2 locale id (Just (Just '0')) cs t
+formatTime1 locale ('^' : cs) t = formatTime2 locale (fmap toUpper) Nothing cs t
+formatTime1 locale ('#' : cs) t = formatTime2 locale (fmap toLower) Nothing cs t
 formatTime1 locale cs t = formatTime2 locale id Nothing cs t
 
 getDigit :: Char -> Maybe Int
@@ -347,34 +367,36 @@
 
 pullNumber :: Maybe Int -> String -> (Maybe Int, String)
 pullNumber mx [] = (mx, [])
-pullNumber mx s@(c:cs) =
+pullNumber mx s@(c : cs) =
     case getDigit c of
         Just i -> pullNumber (Just $ (fromMaybe 0 mx) * 10 + i) cs
         Nothing -> (mx, s)
 
 formatTime2 ::
-       (FormatTime t) => TimeLocale -> (String -> String) -> Maybe FormatNumericPadding -> String -> t -> Maybe String
-formatTime2 locale recase mpad cs t = let
-    (mwidth, rest) = pullNumber Nothing cs
-    in formatTime3 locale recase mpad mwidth rest t
+    FormatTime t => TimeLocale -> (String -> String) -> Maybe FormatNumericPadding -> String -> t -> Maybe String
+formatTime2 locale recase mpad cs t =
+    let
+        (mwidth, rest) = pullNumber Nothing cs
+    in
+        formatTime3 locale recase mpad mwidth rest t
 
 formatTime3 ::
-       (FormatTime t)
-    => TimeLocale
-    -> (String -> String)
-    -> Maybe FormatNumericPadding
-    -> Maybe Int
-    -> String
-    -> t
-    -> Maybe String
-formatTime3 locale recase mpad mwidth ('E':cs) = formatTime4 True recase (MkFormatOptions locale mpad mwidth) cs
+    FormatTime t =>
+    TimeLocale ->
+    (String -> String) ->
+    Maybe FormatNumericPadding ->
+    Maybe Int ->
+    String ->
+    t ->
+    Maybe String
+formatTime3 locale recase mpad mwidth ('E' : cs) = formatTime4 True recase (MkFormatOptions locale mpad mwidth) cs
 formatTime3 locale recase mpad mwidth cs = formatTime4 False recase (MkFormatOptions locale mpad mwidth) cs
 
-formatTime4 :: (FormatTime t) => Bool -> (String -> String) -> FormatOptions -> String -> t -> Maybe String
-formatTime4 alt recase fo (c:cs) t = Just $ (recase (formatChar alt c fo t)) ++ (formatTime (foLocale fo) cs t)
+formatTime4 :: FormatTime t => Bool -> (String -> String) -> FormatOptions -> String -> t -> Maybe String
+formatTime4 alt recase fo (c : cs) t = Just $ (recase (formatChar alt c fo t)) ++ (formatTime (foLocale fo) cs t)
 formatTime4 _alt _recase _fo [] _t = Nothing
 
-formatChar :: (FormatTime t) => Bool -> Char -> FormatOptions -> t -> String
+formatChar :: FormatTime t => Bool -> Char -> FormatOptions -> t -> String
 formatChar _ '%' = formatString $ \_ _ -> "%"
 formatChar _ 't' = formatString $ \_ _ -> "\t"
 formatChar _ 'n' = formatString $ \_ _ -> "\n"
diff --git a/lib/Data/Time/Format/Format/Instances.hs b/lib/Data/Time/Format/Format/Instances.hs
--- a/lib/Data/Time/Format/Format/Instances.hs
+++ b/lib/Data/Time/Format/Format/Instances.hs
@@ -1,16 +1,21 @@
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.Format.Format.Instances
-    (
-    ) where
+module Data.Time.Format.Format.Instances (
 
+) where
+
+import Control.Applicative ((<|>))
 import Data.Char
 import Data.Fixed
 import Data.Time.Calendar.CalendarDiffDays
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.Gregorian
+import Data.Time.Calendar.Month
 import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.Private
+import Data.Time.Calendar.Quarter
 import Data.Time.Calendar.Week
 import Data.Time.Calendar.WeekDate
 import Data.Time.Clock.Internal.DiffTime
@@ -26,22 +31,23 @@
 import Data.Time.LocalTime.Internal.TimeZone
 import Data.Time.LocalTime.Internal.ZonedTime
 
+mapFormatCharacter :: (b -> a) -> Maybe (FormatOptions -> a -> String) -> Maybe (FormatOptions -> b -> String)
+mapFormatCharacter ba = fmap $ fmap $ \as -> as . ba
+
 instance FormatTime LocalTime where
     formatCharacter _ 'c' = Just $ \fo -> formatTime (foLocale fo) $ dateTimeFmt $ foLocale fo
     formatCharacter alt c =
-        case formatCharacter alt c of
-            Just f -> Just $ \fo dt -> f fo (localDay dt)
-            Nothing ->
-                case formatCharacter alt c of
-                    Just f -> Just $ \fo dt -> f fo (localTimeOfDay dt)
-                    Nothing -> Nothing
+        mapFormatCharacter localDay (formatCharacter alt c)
+            <|> mapFormatCharacter localTimeOfDay (formatCharacter alt c)
 
 todAMPM :: TimeLocale -> TimeOfDay -> String
-todAMPM locale day = let
-    (am, pm) = amPm locale
-    in if (todHour day) < 12
-           then am
-           else pm
+todAMPM locale day =
+    let
+        (am, pm) = amPm locale
+    in
+        if (todHour day) < 12
+            then am
+            else pm
 
 tod12Hour :: TimeOfDay -> Int
 tod12Hour day = (mod (todHour day - 1) 12) + 1
@@ -78,26 +84,24 @@
     formatCharacter _ 's' =
         Just $ formatNumber True 1 '0' $ (floor . utcTimeToPOSIXSeconds . zonedTimeToUTC :: ZonedTime -> Integer)
     formatCharacter alt c =
-        case formatCharacter alt c of
-            Just f -> Just $ \fo dt -> f fo (zonedTimeToLocalTime dt)
-            Nothing ->
-                case formatCharacter alt c of
-                    Just f -> Just $ \fo dt -> f fo (zonedTimeZone dt)
-                    Nothing -> Nothing
+        mapFormatCharacter zonedTimeToLocalTime (formatCharacter alt c)
+            <|> mapFormatCharacter zonedTimeZone (formatCharacter alt c)
 
 instance FormatTime TimeZone where
     formatCharacter False 'z' = Just $ formatGeneral False True 4 '0' $ \_ -> timeZoneOffsetString'' False
     formatCharacter True 'z' = Just $ formatGeneral False True 5 '0' $ \_ -> timeZoneOffsetString'' True
     formatCharacter alt 'Z' =
-        Just $ \fo z -> let
-            n = timeZoneName z
-            idef =
-                if alt
-                    then 5
-                    else 4
-            in if null n
-                   then formatGeneral False True idef '0' (\_ -> timeZoneOffsetString'' alt) fo z
-                   else formatString (\_ -> timeZoneName) fo z
+        Just $ \fo z ->
+            let
+                n = timeZoneName z
+                idef =
+                    if alt
+                        then 5
+                        else 4
+            in
+                if null n
+                    then formatGeneral False True idef '0' (\_ -> timeZoneOffsetString'' alt) fo z
+                    else formatString (\_ -> timeZoneName) fo z
     formatCharacter _ _ = Nothing
 
 instance FormatTime DayOfWeek where
@@ -107,34 +111,47 @@
     formatCharacter _ 'A' = Just $ formatString $ \locale wd -> fst $ (wDays locale) !! (mod (fromEnum wd) 7)
     formatCharacter _ _ = Nothing
 
-instance FormatTime Day where
-    -- Aggregate
-    formatCharacter _ 'D' = Just $ formatString $ \locale -> formatTime locale "%m/%d/%y"
-    formatCharacter _ 'F' = Just $ formatString $ \locale -> formatTime locale "%Y-%m-%d"
-    formatCharacter _ 'x' = Just $ formatString $ \locale -> formatTime locale (dateFmt locale)
+instance FormatTime QuarterOfYear where
+    -- Quarter of Year
+    formatCharacter _ 'v' = Just $ formatNumber False 1 '0' fromEnum
+    formatCharacter _ _ = Nothing
+
+instance FormatTime Quarter where
     -- Year Count
-    formatCharacter _ 'Y' = Just $ formatNumber False 4 '0' $ fst . toOrdinalDate
-    formatCharacter _ 'y' = Just $ formatNumber True 2 '0' $ mod100 . fst . toOrdinalDate
-    formatCharacter _ 'C' = Just $ formatNumber False 2 '0' $ div100 . fst . toOrdinalDate
+    formatCharacter _ 'Y' = Just $ formatNumber False 4 '0' $ \(YearQuarter y _) -> y
+    formatCharacter _ 'y' = Just $ formatNumber True 2 '0' $ \(YearQuarter y _) -> mod100 y
+    formatCharacter _ 'C' = Just $ formatNumber False 2 '0' $ \(YearQuarter y _) -> div100 y
+    -- Default
+    formatCharacter alt c = mapFormatCharacter (\(YearQuarter _ q) -> q) $ formatCharacter alt c
+
+instance FormatTime Month where
     -- Month of Year
     formatCharacter _ 'B' =
-        Just $ formatString $ \locale -> fst . (\(_, m, _) -> (months locale) !! (m - 1)) . toGregorian
+        Just $ formatString $ \locale (YearMonth _ my) -> fst $ (months locale) !! (my - 1)
     formatCharacter _ 'b' =
-        Just $ formatString $ \locale -> snd . (\(_, m, _) -> (months locale) !! (m - 1)) . toGregorian
+        Just $ formatString $ \locale (YearMonth _ my) -> snd $ (months locale) !! (my - 1)
     formatCharacter _ 'h' =
-        Just $ formatString $ \locale -> snd . (\(_, m, _) -> (months locale) !! (m - 1)) . toGregorian
-    formatCharacter _ 'm' = Just $ formatNumber True 2 '0' $ (\(_, m, _) -> m) . toGregorian
+        Just $ formatString $ \locale (YearMonth _ my) -> snd $ (months locale) !! (my - 1)
+    formatCharacter _ 'm' = Just $ formatNumber True 2 '0' $ \(YearMonth _ m) -> m
+    -- Default
+    formatCharacter alt c = mapFormatCharacter monthQuarter $ formatCharacter alt c
+
+instance FormatTime Day where
+    -- Aggregate
+    formatCharacter _ 'D' = Just $ formatString $ \locale -> formatTime locale "%m/%d/%y"
+    formatCharacter _ 'F' = Just $ formatString $ \locale -> formatTime locale "%Y-%m-%d"
+    formatCharacter _ 'x' = Just $ formatString $ \locale -> formatTime locale (dateFmt locale)
     -- Day of Month
-    formatCharacter _ 'd' = Just $ formatNumber True 2 '0' $ (\(_, _, d) -> d) . toGregorian
-    formatCharacter _ 'e' = Just $ formatNumber True 2 ' ' $ (\(_, _, d) -> d) . toGregorian
+    formatCharacter _ 'd' = Just $ formatNumber True 2 '0' $ \(YearMonthDay _ _ dm) -> dm
+    formatCharacter _ 'e' = Just $ formatNumber True 2 ' ' $ \(YearMonthDay _ _ dm) -> dm
     -- Day of Year
-    formatCharacter _ 'j' = Just $ formatNumber True 3 '0' $ snd . toOrdinalDate
+    formatCharacter _ 'j' = Just $ formatNumber True 3 '0' $ \(YearDay _ dy) -> dy
     -- ISO 8601 Week Date
-    formatCharacter _ 'G' = Just $ formatNumber False 4 '0' $ (\(y, _, _) -> y) . toWeekDate
-    formatCharacter _ 'g' = Just $ formatNumber True 2 '0' $ mod100 . (\(y, _, _) -> y) . toWeekDate
-    formatCharacter _ 'f' = Just $ formatNumber False 2 '0' $ div100 . (\(y, _, _) -> y) . toWeekDate
-    formatCharacter _ 'V' = Just $ formatNumber True 2 '0' $ (\(_, w, _) -> w) . toWeekDate
-    formatCharacter _ 'u' = Just $ formatNumber True 1 '0' $ (\(_, _, d) -> d) . toWeekDate
+    formatCharacter _ 'G' = Just $ formatNumber False 4 '0' $ \(YearWeekDay y _ _) -> y
+    formatCharacter _ 'g' = Just $ formatNumber True 2 '0' $ \(YearWeekDay y _ _) -> mod100 y
+    formatCharacter _ 'f' = Just $ formatNumber False 2 '0' $ \(YearWeekDay y _ _) -> div100 y
+    formatCharacter _ 'V' = Just $ formatNumber True 2 '0' $ \(YearWeekDay _ wy _) -> wy
+    formatCharacter _ 'u' = Just $ formatNumber True 1 '0' $ \(YearWeekDay _ _ dw) -> fromEnum dw
     -- Day of week
     formatCharacter _ 'a' = Just $ formatString $ \locale -> snd . ((wDays locale) !!) . snd . sundayStartWeek
     formatCharacter _ 'A' = Just $ formatString $ \locale -> fst . ((wDays locale) !!) . snd . sundayStartWeek
@@ -142,13 +159,13 @@
     formatCharacter _ 'w' = Just $ formatNumber True 1 '0' $ snd . sundayStartWeek
     formatCharacter _ 'W' = Just $ formatNumber True 2 '0' $ fst . mondayStartWeek
     -- Default
-    formatCharacter _ _ = Nothing
+    formatCharacter alt c = mapFormatCharacter (\(MonthDay m _) -> m) $ formatCharacter alt c
 
 instance FormatTime UTCTime where
-    formatCharacter alt c = fmap (\f fo t -> f fo (utcToZonedTime utc t)) (formatCharacter alt c)
+    formatCharacter alt c = mapFormatCharacter (utcToZonedTime utc) $ formatCharacter alt c
 
 instance FormatTime UniversalTime where
-    formatCharacter alt c = fmap (\f fo t -> f fo (ut1ToLocalTime 0 t)) (formatCharacter alt c)
+    formatCharacter alt c = mapFormatCharacter (ut1ToLocalTime 0) $ formatCharacter alt c
 
 instance FormatTime NominalDiffTime where
     formatCharacter _ 'w' = Just $ formatNumberStd 1 $ quotBy $ 7 * 86400
@@ -164,12 +181,13 @@
     formatCharacter False 'S' = Just $ formatNumberStd 2 $ remBy 60 . quotBy 1
     formatCharacter True 'S' =
         Just $
-        formatGeneral True False 12 '0' $ \_ padf t -> let
-            padn =
-                case padf of
-                    NoPad -> NoPad
-                    Pad _ c -> Pad 2 c
-            in showPaddedFixed padn padf (realToFrac $ remBy 60 t :: Pico)
+            formatGeneral True False 12 '0' $ \_ padf t ->
+                let
+                    padn = case padf of
+                        NoPad -> NoPad
+                        Pad _ c -> Pad 2 c
+                in
+                    showPaddedFixed padn padf (realToFrac $ remBy 60 t :: Pico)
     formatCharacter _ _ = Nothing
 
 instance FormatTime DiffTime where
@@ -186,12 +204,13 @@
     formatCharacter False 'S' = Just $ formatNumberStd 2 $ remBy 60 . quotBy 1
     formatCharacter True 'S' =
         Just $
-        formatGeneral True False 12 '0' $ \_ padf t -> let
-            padn =
-                case padf of
-                    NoPad -> NoPad
-                    Pad _ c -> Pad 2 c
-            in showPaddedFixed padn padf (realToFrac $ remBy 60 t :: Pico)
+            formatGeneral True False 12 '0' $ \_ padf t ->
+                let
+                    padn = case padf of
+                        NoPad -> NoPad
+                        Pad _ c -> Pad 2 c
+                in
+                    showPaddedFixed padn padf (realToFrac $ remBy 60 t :: Pico)
     formatCharacter _ _ = Nothing
 
 instance FormatTime CalendarDiffDays where
@@ -207,4 +226,4 @@
     formatCharacter _ 'y' = Just $ formatNumberStd 1 $ quotBy 12 . ctMonths
     formatCharacter _ 'b' = Just $ formatNumberStd 1 $ ctMonths
     formatCharacter _ 'B' = Just $ formatNumberStd 2 $ remBy 12 . ctMonths
-    formatCharacter alt c = fmap (\f fo t -> f fo (ctTime t)) (formatCharacter alt c)
+    formatCharacter alt c = mapFormatCharacter ctTime $ formatCharacter alt c
diff --git a/lib/Data/Time/Format/ISO8601.hs b/lib/Data/Time/Format/ISO8601.hs
--- a/lib/Data/Time/Format/ISO8601.hs
+++ b/lib/Data/Time/Format/ISO8601.hs
@@ -1,77 +1,94 @@
-module Data.Time.Format.ISO8601
-    (
-        -- * Format
-      Format
-    , formatShowM
-    , formatShow
-    , formatReadP
-    , formatParseM
-        -- * Common formats
-    , ISO8601(..)
-    , iso8601Show
-    , iso8601ParseM
-        -- * All formats
-    , FormatExtension(..)
-    , formatReadPExtension
-    , parseFormatExtension
-    , calendarFormat
-    , yearMonthFormat
-    , yearFormat
-    , centuryFormat
-    , expandedCalendarFormat
-    , expandedYearMonthFormat
-    , expandedYearFormat
-    , expandedCenturyFormat
-    , ordinalDateFormat
-    , expandedOrdinalDateFormat
-    , weekDateFormat
-    , yearWeekFormat
-    , expandedWeekDateFormat
-    , expandedYearWeekFormat
-    , timeOfDayFormat
-    , hourMinuteFormat
-    , hourFormat
-    , withTimeDesignator
-    , withUTCDesignator
-    , timeOffsetFormat
-    , timeOfDayAndOffsetFormat
-    , localTimeFormat
-    , zonedTimeFormat
-    , utcTimeFormat
-    , dayAndTimeFormat
-    , timeAndOffsetFormat
-    , durationDaysFormat
-    , durationTimeFormat
-    , alternativeDurationDaysFormat
-    , alternativeDurationTimeFormat
-    , intervalFormat
-    , recurringIntervalFormat
-    ) where
+{-# LANGUAGE Safe #-}
 
+{-# OPTIONS -fno-warn-orphans #-}
+
+module Data.Time.Format.ISO8601 (
+    -- * Format
+    Format,
+    formatShowM,
+    formatShow,
+    formatReadP,
+    formatParseM,
+
+    -- * Common formats
+    ISO8601 (..),
+    iso8601Show,
+    iso8601ParseM,
+
+    -- * All formats
+    FormatExtension (..),
+    formatReadPExtension,
+    parseFormatExtension,
+    calendarFormat,
+    yearMonthFormat,
+    yearFormat,
+    centuryFormat,
+    expandedCalendarFormat,
+    expandedYearMonthFormat,
+    expandedYearFormat,
+    expandedCenturyFormat,
+    ordinalDateFormat,
+    expandedOrdinalDateFormat,
+    weekDateFormat,
+    yearWeekFormat,
+    expandedWeekDateFormat,
+    expandedYearWeekFormat,
+    timeOfDayFormat,
+    hourMinuteFormat,
+    hourFormat,
+    withTimeDesignator,
+    withUTCDesignator,
+    timeOffsetFormat,
+    timeOfDayAndOffsetFormat,
+    localTimeFormat,
+    zonedTimeFormat,
+    utcTimeFormat,
+    dayAndTimeFormat,
+    timeAndOffsetFormat,
+    durationDaysFormat,
+    durationTimeFormat,
+    alternativeDurationDaysFormat,
+    alternativeDurationTimeFormat,
+    intervalFormat,
+    recurringIntervalFormat,
+
+    -- * Other
+    isoMakeTimeOfDayValid,
+) where
+
 import Control.Monad.Fail
 import Data.Fixed
 import Data.Format
 import Data.Ratio
-import Data.Time
+import Data.Time.Calendar.CalendarDiffDays
+import Data.Time.Calendar.Days
+import Data.Time.Calendar.Gregorian
 import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.Private
 import Data.Time.Calendar.WeekDate
-import Prelude hiding (fail)
+import Data.Time.Clock.Internal.NominalDiffTime
+import Data.Time.Clock.Internal.UTCTime
+import Data.Time.LocalTime.Internal.CalendarDiffTime
+import Data.Time.LocalTime.Internal.LocalTime
+import Data.Time.LocalTime.Internal.TimeOfDay
+import Data.Time.LocalTime.Internal.TimeZone hiding (timeZoneOffsetString'')
+import Data.Time.LocalTime.Internal.ZonedTime
 import Text.ParserCombinators.ReadP
+import Text.Read (Read (..), lift)
+import Prelude hiding (fail)
 
 data FormatExtension
-    = 
-    -- | ISO 8601:2004(E) sec. 2.3.4. Use hyphens and colons.
+    = -- | Use hyphens and colons. [ISO 8601:2004(E) sec. 2.3.4]
       ExtendedFormat
-    -- | ISO 8601:2004(E) sec. 2.3.3. Omit hyphens and colons. "The basic format should be avoided in plain text."
-    | BasicFormat
+    | -- | Omit hyphens and colons. "The basic format should be avoided in plain text." [ISO 8601:2004(E) sec. 2.3.3]
+      BasicFormat
 
 -- | Read a value in either extended or basic format
 formatReadPExtension :: (FormatExtension -> Format t) -> ReadP t
 formatReadPExtension ff = formatReadP (ff ExtendedFormat) +++ formatReadP (ff BasicFormat)
 
 -- | Parse a value in either extended or basic format
-parseFormatExtension :: (MonadFail m) => (FormatExtension -> Format t) -> String -> m t
+parseFormatExtension :: MonadFail m => (FormatExtension -> Format t) -> String -> m t
 parseFormatExtension ff = parseReader $ formatReadPExtension ff
 
 sepFormat :: String -> Format a -> Format b -> Format (a, b)
@@ -148,68 +165,75 @@
 mapWeekDate =
     mapMFormat (\(y, (w, d)) -> fromWeekDateValid y w d) (\day -> (\(y, w, d) -> Just (y, (w, d))) $ toWeekDate day)
 
+-- | Like 'makeTimeOfDayValid', but accepts @24 0 0@ per ISO 8601:2004(E) sec. 4.2.3
+--
+-- @since 1.12
+isoMakeTimeOfDayValid :: Int -> Int -> Pico -> Maybe TimeOfDay
+isoMakeTimeOfDayValid 24 0 0 = return (TimeOfDay 24 0 0)
+isoMakeTimeOfDayValid h m s = makeTimeOfDayValid h m s
+
 mapTimeOfDay :: Format (Int, (Int, Pico)) -> Format TimeOfDay
-mapTimeOfDay = mapMFormat (\(h, (m, s)) -> makeTimeOfDayValid h m s) (\(TimeOfDay h m s) -> Just (h, (m, s)))
+mapTimeOfDay = mapMFormat (\(h, (m, s)) -> isoMakeTimeOfDayValid h m s) (\(TimeOfDay h m s) -> Just (h, (m, s)))
 
--- | ISO 8601:2004(E) sec. 4.1.2.2
+-- | @yyyy-mm-dd@ (extended), @yyyymmdd@ (basic) [ISO 8601:2004(E) sec. 4.1.2.2]
 calendarFormat :: FormatExtension -> Format Day
 calendarFormat fe = mapGregorian $ extDashFormat fe yearFormat $ extDashFormat fe monthFormat dayOfMonthFormat
 
--- | ISO 8601:2004(E) sec. 4.1.2.3(a)
+-- | @yyyy-mm@ [ISO 8601:2004(E) sec. 4.1.2.3(a)]
 yearMonthFormat :: Format (Integer, Int)
 yearMonthFormat = yearFormat <**> literalFormat "-" **> monthFormat
 
--- | ISO 8601:2004(E) sec. 4.1.2.3(b)
+-- | @yyyy@ [ISO 8601:2004(E) sec. 4.1.2.3(b)]
 yearFormat :: Format Integer
 yearFormat = yearFormat'
 
--- | ISO 8601:2004(E) sec. 4.1.2.3(c)
+-- | @yy@ [ISO 8601:2004(E) sec. 4.1.2.3(c)]
 centuryFormat :: Format Integer
 centuryFormat = integerFormat NegSign (Just 2)
 
--- | ISO 8601:2004(E) sec. 4.1.2.4(a)
+-- | @±__y__yyyy-mm-dd@ (extended), @±__y__yyyymmdd@ (basic) [ISO 8601:2004(E) sec. 4.1.2.4(a)]
 expandedCalendarFormat :: Int -> FormatExtension -> Format Day
 expandedCalendarFormat n fe =
     mapGregorian $ extDashFormat fe (expandedYearFormat n) $ extDashFormat fe monthFormat dayOfMonthFormat
 
--- | ISO 8601:2004(E) sec. 4.1.2.4(b)
+-- | @±__y__yyyy-mm@ [ISO 8601:2004(E) sec. 4.1.2.4(b)]
 expandedYearMonthFormat :: Int -> Format (Integer, Int)
 expandedYearMonthFormat n = dashFormat (expandedYearFormat n) monthFormat
 
--- | ISO 8601:2004(E) sec. 4.1.2.4(c)
+-- | @±__y__yyyy@ [ISO 8601:2004(E) sec. 4.1.2.4(c)]
 expandedYearFormat :: Int -> Format Integer
 expandedYearFormat = expandedYearFormat'
 
--- | ISO 8601:2004(E) sec. 4.1.2.4(d)
+-- | @±__y__yy@ [ISO 8601:2004(E) sec. 4.1.2.4(d)]
 expandedCenturyFormat :: Int -> Format Integer
 expandedCenturyFormat n = integerFormat PosNegSign (Just n)
 
--- | ISO 8601:2004(E) sec. 4.1.3.2
+-- | @yyyy-ddd@ (extended), @yyyyddd@ (basic) [ISO 8601:2004(E) sec. 4.1.3.2]
 ordinalDateFormat :: FormatExtension -> Format Day
 ordinalDateFormat fe = mapOrdinalDate $ extDashFormat fe yearFormat dayOfYearFormat
 
--- | ISO 8601:2004(E) sec. 4.1.3.3
+-- | @__y__yyyy-ddd@ (extended), @__y__yyyyddd@ (basic) [ISO 8601:2004(E) sec. 4.1.3.3]
 expandedOrdinalDateFormat :: Int -> FormatExtension -> Format Day
 expandedOrdinalDateFormat n fe = mapOrdinalDate $ extDashFormat fe (expandedYearFormat n) dayOfYearFormat
 
--- | ISO 8601:2004(E) sec. 4.1.4.2
+-- | @yyyy-Www-D@ (extended), @yyyyWwwd@ (basic) [ISO 8601:2004(E) sec. 4.1.4.2]
 weekDateFormat :: FormatExtension -> Format Day
 weekDateFormat fe = mapWeekDate $ extDashFormat fe yearFormat $ extDashFormat fe weekOfYearFormat dayOfWeekFormat
 
--- | ISO 8601:2004(E) sec. 4.1.4.3
+-- | @yyyy-Www@ (extended), @yyyyWww@ (basic) [ISO 8601:2004(E) sec. 4.1.4.3]
 yearWeekFormat :: FormatExtension -> Format (Integer, Int)
 yearWeekFormat fe = extDashFormat fe yearFormat weekOfYearFormat
 
--- | ISO 8601:2004(E) sec. 4.1.4.2
+-- | @±__y__yyyy-Www-d@ (extended), @±__y__yyyyWwwD@ (basic) [ISO 8601:2004(E) sec. 4.1.4.4]
 expandedWeekDateFormat :: Int -> FormatExtension -> Format Day
 expandedWeekDateFormat n fe =
     mapWeekDate $ extDashFormat fe (expandedYearFormat n) $ extDashFormat fe weekOfYearFormat dayOfWeekFormat
 
--- | ISO 8601:2004(E) sec. 4.1.4.3
+-- | @±__y__yyyy-Www@ (extended), @±__y__yyyyWww@ (basic) [ISO 8601:2004(E) sec. 4.1.4.4]
 expandedYearWeekFormat :: Int -> FormatExtension -> Format (Integer, Int)
 expandedYearWeekFormat n fe = extDashFormat fe (expandedYearFormat n) weekOfYearFormat
 
--- | ISO 8601:2004(E) sec. 4.2.2.2, 4.2.2.4(a)
+-- | @hh:mm:ss[.s__s__]@ (extended), @hhmmss[.s__s__]@ (basic) [ISO 8601:2004(E) sec. 4.2.2.2, 4.2.2.4(a)]
 timeOfDayFormat :: FormatExtension -> Format TimeOfDay
 timeOfDayFormat fe = mapTimeOfDay $ extColonFormat fe hourFormat' $ extColonFormat fe minuteFormat secondFormat
 
@@ -217,141 +241,172 @@
 fromRationalRound :: Rational -> NominalDiffTime
 fromRationalRound r = fromRational $ round (r * 1000000000000) % 1000000000000
 
--- | ISO 8601:2004(E) sec. 4.2.2.3(a), 4.2.2.4(b)
+-- | @hh:mm[.m__m__]@ (extended), @hhmm[.m__m__]@ (basic) [ISO 8601:2004(E) sec. 4.2.2.3(a), 4.2.2.4(b)]
 hourMinuteFormat :: FormatExtension -> Format TimeOfDay
-hourMinuteFormat fe = let
-    toTOD (h, m) =
-        case timeToDaysAndTimeOfDay $ fromRationalRound $ toRational $ (fromIntegral h) * 3600 + m * 60 of
-            (0, tod) -> Just tod
-            _ -> Nothing
-    fromTOD tod = let
-        mm = (realToFrac $ daysAndTimeOfDayToTime 0 tod) / 60
-        in Just $ quotRemBy 60 mm
-    in mapMFormat toTOD fromTOD $ extColonFormat fe hourFormat' $ minuteDecimalFormat
+hourMinuteFormat fe =
+    let
+        toTOD (h, m) =
+            case timeToDaysAndTimeOfDay $ fromRationalRound $ toRational $ (fromIntegral h) * 3600 + m * 60 of
+                (0, tod) -> Just tod
+                (1, TimeOfDay 0 0 0) -> Just $ TimeOfDay 24 0 0
+                _ -> Nothing
+        fromTOD tod =
+            let
+                mm = (realToFrac $ daysAndTimeOfDayToTime 0 tod) / 60
+            in
+                Just $ quotRemBy 60 mm
+    in
+        mapMFormat toTOD fromTOD $ extColonFormat fe hourFormat' $ minuteDecimalFormat
 
--- | ISO 8601:2004(E) sec. 4.2.2.3(b), 4.2.2.4(c)
+-- | @hh[.h__h__]@ [ISO 8601:2004(E) sec. 4.2.2.3(b), 4.2.2.4(c)]
 hourFormat :: Format TimeOfDay
-hourFormat = let
-    toTOD h =
-        case timeToDaysAndTimeOfDay $ fromRationalRound $ toRational $ h * 3600 of
+hourFormat =
+    let
+        toTOD h = case timeToDaysAndTimeOfDay $ fromRationalRound $ toRational $ h * 3600 of
             (0, tod) -> Just tod
+            (1, TimeOfDay 0 0 0) -> Just $ TimeOfDay 24 0 0
             _ -> Nothing
-    fromTOD tod = Just $ (realToFrac $ daysAndTimeOfDayToTime 0 tod) / 3600
-    in mapMFormat toTOD fromTOD $ hourDecimalFormat
+        fromTOD tod = Just $ (realToFrac $ daysAndTimeOfDayToTime 0 tod) / 3600
+    in
+        mapMFormat toTOD fromTOD $ hourDecimalFormat
 
--- | ISO 8601:2004(E) sec. 4.2.2.5
+-- | @Tx@ [ISO 8601:2004(E) sec. 4.2.2.5]
 withTimeDesignator :: Format t -> Format t
 withTimeDesignator f = literalFormat "T" **> f
 
--- | ISO 8601:2004(E) sec. 4.2.4
+-- | @xZ@ [ISO 8601:2004(E) sec. 4.2.4]
 withUTCDesignator :: Format t -> Format t
-withUTCDesignator f = f <** literalFormat "Z"
+withUTCDesignator f = f <** specialCaseReadFormat ((), "") (literalFormat "Z")
 
--- | ISO 8601:2004(E) sec. 4.2.5.1
+-- | @±hh:mm@ (extended), @±hhmm@ (basic) [ISO 8601:2004(E) sec. 4.2.5.1]
 timeOffsetFormat :: FormatExtension -> Format TimeZone
-timeOffsetFormat fe = let
-    toTimeZone (sign, (h, m)) = minutesToTimeZone $ sign * (h * 60 + m)
-    fromTimeZone tz = let
-        mm = timeZoneMinutes tz
-        hm = quotRem (abs mm) 60
-        in (signum mm, hm)
-    in isoMap toTimeZone fromTimeZone $
-       mandatorySignFormat <**> extColonFormat fe (integerFormat NoSign (Just 2)) (integerFormat NoSign (Just 2))
+timeOffsetFormat fe =
+    let
+        toTimeZone (sign, ehm) =
+            minutesToTimeZone $
+                sign * case ehm of
+                    Left h -> h * 60
+                    Right (h, m) -> h * 60 + m
+        fromTimeZone tz =
+            let
+                mm = timeZoneMinutes tz
+                (h, m) = quotRem (abs mm) 60
+            in
+                (signum mm, Right (h, m))
+        digits2 = integerFormat NoSign (Just 2)
+    in
+        specialCaseReadFormat (utc, "") $
+            specialCaseReadFormat (utc, "Z") $
+                isoMap toTimeZone fromTimeZone $
+                    mandatorySignFormat <**> (digits2 <++> extColonFormat fe digits2 digits2)
 
--- | ISO 8601:2004(E) sec. 4.2.5.2
+-- | @hh:mm:ss±hh:mm@ (extended), @hhmmss±hhmm@ (basic) [ISO 8601:2004(E) sec. 4.2.5.2]
 timeOfDayAndOffsetFormat :: FormatExtension -> Format (TimeOfDay, TimeZone)
 timeOfDayAndOffsetFormat fe = timeOfDayFormat fe <**> timeOffsetFormat fe
 
--- | ISO 8601:2004(E) sec. 4.3.2
+-- | @xTy@ [ISO 8601:2004(E) sec. 4.3.2]
 localTimeFormat :: Format Day -> Format TimeOfDay -> Format LocalTime
 localTimeFormat fday ftod =
-    isoMap (\(day, tod) -> LocalTime day tod) (\(LocalTime day tod) -> (day, tod)) $ fday <**> withTimeDesignator ftod
+    isoMap (\(day, tod) -> LocalTime day tod) (\(LocalTime day tod) -> (day, tod)) $ dayAndTimeFormat fday ftod
 
--- | ISO 8601:2004(E) sec. 4.3.2
+-- | @xTy±hh:mm@ (extended), @xTy±hhmm@ (basic) [ISO 8601:2004(E) sec. 4.3.2]
 zonedTimeFormat :: Format Day -> Format TimeOfDay -> FormatExtension -> Format ZonedTime
 zonedTimeFormat fday ftod fe =
     isoMap (\(lt, tz) -> ZonedTime lt tz) (\(ZonedTime lt tz) -> (lt, tz)) $
-    timeAndOffsetFormat (localTimeFormat fday ftod) fe
+        timeAndOffsetFormat (localTimeFormat fday ftod) fe
 
--- | ISO 8601:2004(E) sec. 4.3.2
+-- | @xTyZ@ [ISO 8601:2004(E) sec. 4.3.2]
 utcTimeFormat :: Format Day -> Format TimeOfDay -> Format UTCTime
 utcTimeFormat fday ftod =
     isoMap (localTimeToUTC utc) (utcToLocalTime utc) $ withUTCDesignator $ localTimeFormat fday ftod
 
--- | ISO 8601:2004(E) sec. 4.3.3
+-- | @xTy@ [ISO 8601:2004(E) sec. 4.3.3]
 dayAndTimeFormat :: Format Day -> Format time -> Format (Day, time)
-dayAndTimeFormat fday ft = fday <**> withTimeDesignator ft
+dayAndTimeFormat fday ftod = fday <**> withTimeDesignator ftod
 
--- | ISO 8601:2004(E) sec. 4.3.3
+-- | @x±hh:mm@ (extended), @x±hhmm@ (basic) [ISO 8601:2004(E) sec. 4.3.3]
 timeAndOffsetFormat :: Format t -> FormatExtension -> Format (t, TimeZone)
 timeAndOffsetFormat ft fe = ft <**> timeOffsetFormat fe
 
 intDesignator :: (Eq t, Show t, Read t, Num t) => Char -> Format t
-intDesignator c = optionalFormat 0 $ integerFormat NoSign Nothing <** literalFormat [c]
+intDesignator c = optionalFormat 0 $ integerFormat NegSign Nothing <** literalFormat [c]
 
 decDesignator :: (Eq t, Show t, Read t, Num t) => Char -> Format t
-decDesignator c = optionalFormat 0 $ decimalFormat NoSign Nothing <** literalFormat [c]
+decDesignator c = optionalFormat 0 $ decimalFormat NegSign Nothing <** literalFormat [c]
 
 daysDesigs :: Format CalendarDiffDays
-daysDesigs = let
-    toCD (y, (m, (w, d))) = CalendarDiffDays (y * 12 + m) (w * 7 + d)
-    fromCD (CalendarDiffDays mm d) = (quot mm 12, (rem mm 12, (0, d)))
-    in isoMap toCD fromCD $ intDesignator 'Y' <**> intDesignator 'M' <**> intDesignator 'W' <**> intDesignator 'D'
+daysDesigs =
+    let
+        toCD (y, (m, (w, d))) = CalendarDiffDays (y * 12 + m) (w * 7 + d)
+        fromCD (CalendarDiffDays mm d) = (quot mm 12, (rem mm 12, (0, d)))
+    in
+        isoMap toCD fromCD $ intDesignator 'Y' <**> intDesignator 'M' <**> intDesignator 'W' <**> intDesignator 'D'
 
--- | ISO 8601:2004(E) sec. 4.4.3.2
+-- | @PyyYmmMddD@ [ISO 8601:2004(E) sec. 4.4.3.2]
 durationDaysFormat :: Format CalendarDiffDays
 durationDaysFormat = (**>) (literalFormat "P") $ specialCaseShowFormat (mempty, "0D") $ daysDesigs
 
--- | ISO 8601:2004(E) sec. 4.4.3.2
+-- | @PyyYmmMddDThhHmmMss[.s__s__]S@ [ISO 8601:2004(E) sec. 4.4.3.2]
 durationTimeFormat :: Format CalendarDiffTime
-durationTimeFormat = let
-    toCT (cd, (h, (m, s))) =
-        mappend (calendarTimeDays cd) (calendarTimeTime $ daysAndTimeOfDayToTime 0 $ TimeOfDay h m s)
-    fromCT (CalendarDiffTime mm t) = let
-        (d, TimeOfDay h m s) = timeToDaysAndTimeOfDay t
-        in (CalendarDiffDays mm d, (h, (m, s)))
-    in (**>) (literalFormat "P") $
-       specialCaseShowFormat (mempty, "0D") $
-       isoMap toCT fromCT $
-       (<**>) daysDesigs $
-       optionalFormat (0, (0, 0)) $
-       literalFormat "T" **> intDesignator 'H' <**> intDesignator 'M' <**> decDesignator 'S'
+durationTimeFormat =
+    let
+        toCT (cd, (h, (m, s))) =
+            mappend (calendarTimeDays cd) (calendarTimeTime $ daysAndTimeOfDayToTime 0 $ TimeOfDay h m s)
+        fromCT (CalendarDiffTime mm t) =
+            let
+                (d, TimeOfDay h m s) = timeToDaysAndTimeOfDay t
+            in
+                (CalendarDiffDays mm d, (h, (m, s)))
+    in
+        (**>) (literalFormat "P") $
+            specialCaseShowFormat (mempty, "0D") $
+                isoMap toCT fromCT $
+                    (<**>) daysDesigs $
+                        optionalFormat (0, (0, 0)) $
+                            literalFormat "T" **> intDesignator 'H' <**> intDesignator 'M' <**> decDesignator 'S'
 
--- | ISO 8601:2004(E) sec. 4.4.3.3
+-- | @Pyyyy-mm-dd@ (extended), @Pyyyymmdd@ (basic) [ISO 8601:2004(E) sec. 4.4.3.3]
 alternativeDurationDaysFormat :: FormatExtension -> Format CalendarDiffDays
-alternativeDurationDaysFormat fe = let
-    toCD (y, (m, d)) = CalendarDiffDays (y * 12 + m) d
-    fromCD (CalendarDiffDays mm d) = (quot mm 12, (rem mm 12, d))
-    in isoMap toCD fromCD $
-       (**>) (literalFormat "P") $
-       extDashFormat fe (clipFormat (0, 9999) $ integerFormat NegSign $ Just 4) $
-       extDashFormat fe (clipFormat (0, 12) $ integerFormat NegSign $ Just 2) $
-       (clipFormat (0, 30) $ integerFormat NegSign $ Just 2)
+alternativeDurationDaysFormat fe =
+    let
+        toCD (y, (m, d)) = CalendarDiffDays (y * 12 + m) d
+        fromCD (CalendarDiffDays mm d) = (quot mm 12, (rem mm 12, d))
+    in
+        isoMap toCD fromCD $
+            (**>) (literalFormat "P") $
+                extDashFormat fe (clipFormat (0, 9999) $ integerFormat NegSign $ Just 4) $
+                    extDashFormat fe (clipFormat (0, 12) $ integerFormat NegSign $ Just 2) $
+                        (clipFormat (0, 30) $ integerFormat NegSign $ Just 2)
 
--- | ISO 8601:2004(E) sec. 4.4.3.3
+-- | @Pyyyy-mm-ddThh:mm:ss@ (extended), @PyyyymmddThhmmss@ (basic) [ISO 8601:2004(E) sec. 4.4.3.3]
 alternativeDurationTimeFormat :: FormatExtension -> Format CalendarDiffTime
-alternativeDurationTimeFormat fe = let
-    toCT (cd, (h, (m, s))) =
-        mappend (calendarTimeDays cd) (calendarTimeTime $ daysAndTimeOfDayToTime 0 $ TimeOfDay h m s)
-    fromCT (CalendarDiffTime mm t) = let
-        (d, TimeOfDay h m s) = timeToDaysAndTimeOfDay t
-        in (CalendarDiffDays mm d, (h, (m, s)))
-    in isoMap toCT fromCT $
-       (<**>) (alternativeDurationDaysFormat fe) $
-       withTimeDesignator $
-       extColonFormat fe (clipFormat (0, 24) $ integerFormat NegSign (Just 2)) $
-       extColonFormat fe (clipFormat (0, 60) $ integerFormat NegSign (Just 2)) $
-       (clipFormat (0, 60) $ decimalFormat NegSign (Just 2))
+alternativeDurationTimeFormat fe =
+    let
+        toCT (cd, (h, (m, s))) =
+            mappend (calendarTimeDays cd) (calendarTimeTime $ daysAndTimeOfDayToTime 0 $ TimeOfDay h m s)
+        fromCT (CalendarDiffTime mm t) =
+            let
+                (d, TimeOfDay h m s) = timeToDaysAndTimeOfDay t
+            in
+                (CalendarDiffDays mm d, (h, (m, s)))
+    in
+        isoMap toCT fromCT $
+            (<**>) (alternativeDurationDaysFormat fe) $
+                withTimeDesignator $
+                    extColonFormat fe (clipFormat (0, 24) $ integerFormat NegSign (Just 2)) $
+                        extColonFormat fe (clipFormat (0, 60) $ integerFormat NegSign (Just 2)) $
+                            (clipFormat (0, 60) $ decimalFormat NegSign (Just 2))
 
--- | ISO 8601:2004(E) sec. 4.4.4.1
+-- | @x\/y@ [ISO 8601:2004(E) sec. 4.4.4.1]
 intervalFormat :: Format a -> Format b -> Format (a, b)
 intervalFormat = sepFormat "/"
 
--- | ISO 8601:2004(E) sec. 4.5
+-- | @Rn\/x\/y@ [ISO 8601:2004(E) sec. 4.5]
 recurringIntervalFormat :: Format a -> Format b -> Format (Int, a, b)
 recurringIntervalFormat fa fb =
     isoMap (\(r, (a, b)) -> (r, a, b)) (\(r, a, b) -> (r, (a, b))) $
-    sepFormat "/" (literalFormat "R" **> integerFormat NoSign Nothing) $ intervalFormat fa fb
+        sepFormat "/" (literalFormat "R" **> integerFormat NoSign Nothing) $
+            intervalFormat fa fb
 
 class ISO8601 t where
     -- | The most commonly used ISO 8601 format for this type.
@@ -365,34 +420,50 @@
 iso8601ParseM :: (MonadFail m, ISO8601 t) => String -> m t
 iso8601ParseM = formatParseM iso8601Format
 
--- | @yyyy-mm-dd@ (ISO 8601:2004(E) sec. 4.1.2.2 extended format)
+-- | @yyyy-mm-dd@ [ISO 8601:2004(E) sec. 4.1.2.2 extended format]
 instance ISO8601 Day where
     iso8601Format = calendarFormat ExtendedFormat
 
--- | @hh:mm:ss[.sss]@ (ISO 8601:2004(E) sec. 4.2.2.2, 4.2.2.4(a) extended format)
+-- | @hh:mm:ss[.s__s__]@ [ISO 8601:2004(E) sec. 4.2.2.2, 4.2.2.4(a) extended format]
 instance ISO8601 TimeOfDay where
     iso8601Format = timeOfDayFormat ExtendedFormat
 
--- | @±hh:mm@ (ISO 8601:2004(E) sec. 4.2.5.1 extended format)
+-- | @±hh:mm@ [ISO 8601:2004(E) sec. 4.2.5.1 extended format]
 instance ISO8601 TimeZone where
     iso8601Format = timeOffsetFormat ExtendedFormat
 
--- | @yyyy-mm-ddThh:mm:ss[.sss]@ (ISO 8601:2004(E) sec. 4.3.2 extended format)
+-- | @yyyy-mm-ddThh:mm:ss[.s__s__]@ [ISO 8601:2004(E) sec. 4.3.2 extended format]
 instance ISO8601 LocalTime where
     iso8601Format = localTimeFormat iso8601Format iso8601Format
 
--- | @yyyy-mm-ddThh:mm:ss[.sss]±hh:mm@ (ISO 8601:2004(E) sec. 4.3.2 extended format)
+-- | @yyyy-mm-ddThh:mm:ss[.s__s__]±hh:mm@ [ISO 8601:2004(E) sec. 4.3.2 extended format]
 instance ISO8601 ZonedTime where
     iso8601Format = zonedTimeFormat iso8601Format iso8601Format ExtendedFormat
 
--- | @yyyy-mm-ddThh:mm:ss[.sss]Z@ (ISO 8601:2004(E) sec. 4.3.2 extended format)
+-- | @yyyy-mm-ddThh:mm:ss[.s__s__]Z@ [ISO 8601:2004(E) sec. 4.3.2 extended format]
 instance ISO8601 UTCTime where
     iso8601Format = utcTimeFormat iso8601Format iso8601Format
 
--- | @PyYmMdD@ (ISO 8601:2004(E) sec. 4.4.3.2)
+-- | @PyYmMdD@ [ISO 8601:2004(E) sec. 4.4.3.2]
 instance ISO8601 CalendarDiffDays where
     iso8601Format = durationDaysFormat
 
--- | @PyYmMdDThHmMs[.sss]S@ (ISO 8601:2004(E) sec. 4.4.3.2)
+-- | @PyYmMdDThHmMs[.s__s__]S@ [ISO 8601:2004(E) sec. 4.4.3.2]
 instance ISO8601 CalendarDiffTime where
     iso8601Format = durationTimeFormat
+
+-- orphan instance
+instance Read CalendarDiffDays where
+    readPrec = lift $ formatReadP iso8601Format
+
+-- orphan instance
+instance Show CalendarDiffDays where
+    show = formatShow iso8601Format
+
+-- orphan instance
+instance Read CalendarDiffTime where
+    readPrec = lift $ formatReadP iso8601Format
+
+-- orphan instance
+instance Show CalendarDiffTime where
+    show = formatShow iso8601Format
diff --git a/lib/Data/Time/Format/Internal.hs b/lib/Data/Time/Format/Internal.hs
--- a/lib/Data/Time/Format/Internal.hs
+++ b/lib/Data/Time/Format/Internal.hs
@@ -1,11 +1,15 @@
-{-|
-The contents of this module is liable to change, or disappear entirely.
-Please <https://github.com/haskell/time/issues/new let me know> if you depend on anything here.
--}
-module Data.Time.Format.Internal
-    ( FormatTime(..)
-    , ParseTime(..)
-    ) where
+{-# LANGUAGE Safe #-}
 
+-- |
+-- The contents of this module is liable to change, or disappear entirely.
+-- Please <https://github.com/haskell/time/issues/new let me know> if you depend on anything here.
+module Data.Time.Format.Internal (
+    -- * ISO8601 formatting
+    Format (..),
+    module Data.Time.Format.Format.Class,
+    module Data.Time.Format.Parse.Class,
+) where
+
+import Data.Format
 import Data.Time.Format.Format.Class
 import Data.Time.Format.Parse.Class
diff --git a/lib/Data/Time/Format/Locale.hs b/lib/Data/Time/Format/Locale.hs
--- a/lib/Data/Time/Format/Locale.hs
+++ b/lib/Data/Time/Format/Locale.hs
@@ -1,25 +1,23 @@
+{-# LANGUAGE Safe #-}
+
 -- Note: this file derives from old-locale:System.Locale.hs, which is copyright (c) The University of Glasgow 2001
-module Data.Time.Format.Locale
-    ( TimeLocale(..)
-    , defaultTimeLocale
-    , iso8601DateFormat
-    , rfc822DateFormat
-    ) where
+module Data.Time.Format.Locale where
 
 import Data.Time.LocalTime.Internal.TimeZone
 
 data TimeLocale = TimeLocale
-    { wDays :: [(String, String)]
-        -- ^ full and abbreviated week days, starting with Sunday
-    , months :: [(String, String)]
-        -- ^ full and abbreviated months
-    , amPm :: (String, String)
-        -- ^ AM\/PM symbols
-    , dateTimeFmt, dateFmt, timeFmt, time12Fmt :: String
-        -- ^ formatting strings
-    , knownTimeZones :: [TimeZone]
-        -- ^ time zones known by name
-    } deriving (Eq, Ord, Show)
+    { -- | full and abbreviated week days, starting with Sunday
+      wDays :: [(String, String)]
+    , -- | full and abbreviated months
+      months :: [(String, String)]
+    , -- | AM\/PM symbols
+      amPm :: (String, String)
+    , -- | formatting strings
+      dateTimeFmt, dateFmt, timeFmt, time12Fmt :: String
+    , -- | time zones known by name
+      knownTimeZones :: [TimeZone]
+    }
+    deriving (Eq, Ord, Show)
 
 -- | Locale representing American usage.
 --
@@ -30,50 +28,48 @@
 defaultTimeLocale =
     TimeLocale
         { wDays =
-              [ ("Sunday", "Sun")
-              , ("Monday", "Mon")
-              , ("Tuesday", "Tue")
-              , ("Wednesday", "Wed")
-              , ("Thursday", "Thu")
-              , ("Friday", "Fri")
-              , ("Saturday", "Sat")
-              ]
+            [ ("Sunday", "Sun")
+            , ("Monday", "Mon")
+            , ("Tuesday", "Tue")
+            , ("Wednesday", "Wed")
+            , ("Thursday", "Thu")
+            , ("Friday", "Fri")
+            , ("Saturday", "Sat")
+            ]
         , months =
-              [ ("January", "Jan")
-              , ("February", "Feb")
-              , ("March", "Mar")
-              , ("April", "Apr")
-              , ("May", "May")
-              , ("June", "Jun")
-              , ("July", "Jul")
-              , ("August", "Aug")
-              , ("September", "Sep")
-              , ("October", "Oct")
-              , ("November", "Nov")
-              , ("December", "Dec")
-              ]
+            [ ("January", "Jan")
+            , ("February", "Feb")
+            , ("March", "Mar")
+            , ("April", "Apr")
+            , ("May", "May")
+            , ("June", "Jun")
+            , ("July", "Jul")
+            , ("August", "Aug")
+            , ("September", "Sep")
+            , ("October", "Oct")
+            , ("November", "Nov")
+            , ("December", "Dec")
+            ]
         , amPm = ("AM", "PM")
         , dateTimeFmt = "%a %b %e %H:%M:%S %Z %Y"
         , dateFmt = "%m/%d/%y"
         , timeFmt = "%H:%M:%S"
         , time12Fmt = "%I:%M:%S %p"
         , knownTimeZones =
-              [ TimeZone 0 False "UT"
-              , TimeZone 0 False "GMT"
-              , TimeZone (-5 * 60) False "EST"
-              , TimeZone (-4 * 60) True "EDT"
-              , TimeZone (-6 * 60) False "CST"
-              , TimeZone (-5 * 60) True "CDT"
-              , TimeZone (-7 * 60) False "MST"
-              , TimeZone (-6 * 60) True "MDT"
-              , TimeZone (-8 * 60) False "PST"
-              , TimeZone (-7 * 60) True "PDT"
-              ]
+            [ TimeZone 0 False "UT"
+            , TimeZone 0 False "GMT"
+            , TimeZone (-5 * 60) False "EST"
+            , TimeZone (-4 * 60) True "EDT"
+            , TimeZone (-6 * 60) False "CST"
+            , TimeZone (-5 * 60) True "CDT"
+            , TimeZone (-7 * 60) False "MST"
+            , TimeZone (-6 * 60) True "MDT"
+            , TimeZone (-8 * 60) False "PST"
+            , TimeZone (-7 * 60) True "PDT"
+            ]
         }
 
-{-# DEPRECATED
-iso8601DateFormat "use \"Data.Time.Format.ISO8601\" functions instead"
- #-}
+{-# DEPRECATED iso8601DateFormat "use \"Data.Time.Format.ISO8601\" functions instead" #-}
 
 {- | Construct format string according to <http://en.wikipedia.org/wiki/ISO_8601 ISO-8601>.
 
@@ -86,10 +82,10 @@
 -}
 iso8601DateFormat :: Maybe String -> String
 iso8601DateFormat mTimeFmt =
-    "%Y-%m-%d" ++
-    case mTimeFmt of
-        Nothing -> ""
-        Just fmt -> 'T' : fmt
+    "%Y-%m-%d"
+        ++ case mTimeFmt of
+            Nothing -> ""
+            Just fmt -> 'T' : fmt
 
 -- | Format string according to <http://tools.ietf.org/html/rfc822#section-5 RFC822>.
 rfc822DateFormat :: String
diff --git a/lib/Data/Time/Format/Parse.hs b/lib/Data/Time/Format/Parse.hs
--- a/lib/Data/Time/Format/Parse.hs
+++ b/lib/Data/Time/Format/Parse.hs
@@ -1,16 +1,8 @@
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.Format.Parse
-    (
-    -- * UNIX-style parsing
-      parseTimeM
-    , parseTimeOrError
-    , readSTime
-    , readPTime
-    , ParseTime()
-    -- * Locale
-    , module Data.Time.Format.Locale
-    ) where
+module Data.Time.Format.Parse where
 
 import Control.Monad.Fail
 import Data.Char
@@ -25,10 +17,12 @@
 import Data.Time.LocalTime.Internal.TimeOfDay
 import Data.Time.LocalTime.Internal.TimeZone
 import Data.Time.LocalTime.Internal.ZonedTime
-import Prelude hiding (fail)
+import Data.Traversable
 import Text.ParserCombinators.ReadP hiding (char, string)
+import Prelude hiding (fail)
 
 -- | Parses a time value given a format string.
+-- Missing information will be derived from 1970-01-01 00:00 UTC (which was a Thursday).
 -- Supports the same %-codes as 'formatTime', including @%-@, @%_@ and @%0@ modifiers, however padding widths are not supported.
 -- Case is not significant in the input string.
 -- Some variations in the input are accepted:
@@ -51,81 +45,162 @@
 --
 -- > Prelude Data.Time> parseTimeM True defaultTimeLocale "%Y-%-m-%-d" "2010-3-04" :: Maybe Day
 -- > Just 2010-03-04
---
 parseTimeM ::
-       (MonadFail m, ParseTime t)
-    => Bool -- ^ Accept leading and trailing whitespace?
-    -> TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string.
-    -> String -- ^ Input string.
-    -> m t -- ^ Return the time value, or fail if the input could
-                        -- not be parsed using the given format.
-parseTimeM acceptWS l fmt s =
-    case parseTimeList acceptWS l fmt s of
-        [t] -> return t
-        [] -> fail $ "parseTimeM: no parse of " ++ show s
-        _ -> fail $ "parseTimeM: multiple parses of " ++ show s
+    (MonadFail m, ParseTime t) =>
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string.
+    String ->
+    -- | Input string.
+    String ->
+    -- | Return the time value, or fail if the input could not be parsed using the given format.
+    m t
+parseTimeM acceptWS l fmt s = parseTimeMultipleM acceptWS l [(fmt, s)]
 
+-- | Parses a time value given a list of pairs of format and input.
+-- Resulting value is constructed from all provided specifiers.
+parseTimeMultipleM' ::
+    (MonadFail m, ParseTime t) =>
+    Proxy t ->
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Pairs of (format string, input string).
+    [(String, String)] ->
+    -- | Return the time value, or fail if the input could not be parsed using the given format.
+    m t
+parseTimeMultipleM' pt acceptWS l fmts = do
+    specss <- for fmts $ \(fmt, s) -> parseTimeSpecifiersM pt acceptWS l fmt s
+    case buildTime l $ mconcat specss of
+        Just t -> return t
+        Nothing -> fail "parseTimeM: cannot construct"
+
+-- | Parses a time value given a list of pairs of format and input.
+-- Resulting value is constructed from all provided specifiers.
+parseTimeMultipleM ::
+    (MonadFail m, ParseTime t) =>
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Pairs of (format string, input string).
+    [(String, String)] ->
+    -- | Return the time value, or fail if the input could not be parsed using the given format.
+    m t
+parseTimeMultipleM = parseTimeMultipleM' Proxy
+
 -- | Parse a time value given a format string. Fails if the input could
 -- not be parsed using the given format. See 'parseTimeM' for details.
 parseTimeOrError ::
-       ParseTime t
-    => Bool -- ^ Accept leading and trailing whitespace?
-    -> TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string.
-    -> String -- ^ Input string.
-    -> t -- ^ The time value.
+    ParseTime t =>
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string.
+    String ->
+    -- | Input string.
+    String ->
+    -- | The time value.
+    t
 parseTimeOrError acceptWS l fmt s =
-    case parseTimeList acceptWS l fmt s of
+    case parseTimeM acceptWS l fmt s of
         [t] -> t
         [] -> error $ "parseTimeOrError: no parse of " ++ show s
         _ -> error $ "parseTimeOrError: multiple parses of " ++ show s
 
-parseTimeList ::
-       ParseTime t
-    => Bool -- ^ Accept leading and trailing whitespace?
-    -> TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string
-    -> String -- ^ Input string.
-    -> [t]
-parseTimeList False l fmt s = [t | (t, "") <- readSTime False l fmt s]
-parseTimeList True l fmt s = [t | (t, r) <- readSTime True l fmt s, all isSpace r]
+parseTimeSpecifiersM ::
+    (MonadFail m, ParseTime t) =>
+    Proxy t ->
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    -- | Input string.
+    String ->
+    m [(Char, String)]
+parseTimeSpecifiersM pt acceptWS l fmt s =
+    case parseTimeSpecifiers pt acceptWS l fmt s of
+        [t] -> return t
+        [] -> fail $ "parseTimeM: no parse of " ++ show s
+        _ -> fail $ "parseTimeM: multiple parses of " ++ show s
 
+parseTimeSpecifiers ::
+    ParseTime t =>
+    Proxy t ->
+    -- | Accept leading and trailing whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    -- | Input string.
+    String ->
+    [[(Char, String)]]
+parseTimeSpecifiers pt False l fmt s = [t | (t, "") <- readP_to_S (readPSpecifiers pt False l fmt) s]
+parseTimeSpecifiers pt True l fmt s = [t | (t, r) <- readP_to_S (readPSpecifiers pt True l fmt) s, all isSpace r]
+
 -- | Parse a time value given a format string.  See 'parseTimeM' for details.
 readSTime ::
-       ParseTime t
-    => Bool -- ^ Accept leading whitespace?
-    -> TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string
-    -> ReadS t
-readSTime acceptWS l f = readP_to_S (readPTime acceptWS l f)
+    ParseTime t =>
+    -- | Accept leading whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    ReadS t
+readSTime acceptWS l f = readP_to_S $ readPTime acceptWS l f
 
--- | Parse a time value given a format string.  See 'parseTimeM' for details.
-readPTime ::
-       ParseTime t
-    => Bool -- ^ Accept leading whitespace?
-    -> TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string
-    -> ReadP t
-readPTime False l f = readPOnlyTime l f
-readPTime True l f = (skipSpaces >> readPOnlyTime l f) <++ readPOnlyTime l f
+readPSpecifiers ::
+    ParseTime t =>
+    Proxy t ->
+    -- | Accept leading whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    ReadP [(Char, String)]
+readPSpecifiers pt False l f = parseSpecifiers pt l f
+readPSpecifiers pt True l f = (skipSpaces >> parseSpecifiers pt l f) <++ parseSpecifiers pt l f
 
-readPOnlyTime' :: ParseTime t => Proxy t -> TimeLocale -> String -> ReadP t
-readPOnlyTime' pt l f = do
-    pairs <- parseSpecifiers pt l f
+-- | Parse a time value given a format string.  See 'parseTimeM' for details.
+readPTime' ::
+    ParseTime t =>
+    Proxy t ->
+    -- | Accept leading whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    ReadP t
+readPTime' pt ws l f = do
+    pairs <- readPSpecifiers pt ws l f
     case buildTime l pairs of
         Just t -> return t
         Nothing -> pfail
 
--- | Parse a time value given a format string (without allowing leading whitespace).  See 'parseTimeM' for details.
-readPOnlyTime ::
-       ParseTime t
-    => TimeLocale -- ^ Time locale.
-    -> String -- ^ Format string
-    -> ReadP t
-readPOnlyTime = readPOnlyTime' Proxy
+-- | Parse a time value given a format string.  See 'parseTimeM' for details.
+readPTime ::
+    ParseTime t =>
+    -- | Accept leading whitespace?
+    Bool ->
+    -- | Time locale.
+    TimeLocale ->
+    -- | Format string
+    String ->
+    ReadP t
+readPTime = readPTime' Proxy
 
 -- * Read instances for time package types
+
 instance Read Day where
     readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%Y-%m-%d"
 
@@ -137,18 +212,27 @@
 
 -- | This only works for @±HHMM@ format,
 -- single-letter military time-zones,
--- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\".
+-- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\",
+-- per RFC 822 section 5.
 instance Read TimeZone where
     readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%Z"
 
 -- | This only works for a 'zonedTimeZone' in @±HHMM@ format,
 -- single-letter military time-zones,
--- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\".
+-- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\",
+-- per RFC 822 section 5.
 instance Read ZonedTime where
     readsPrec n = readParen False $ \s -> [(ZonedTime t z, r2) | (t, r1) <- readsPrec n s, (z, r2) <- readsPrec n r1]
 
+(<||) :: [a] -> [a] -> [a]
+[] <|| b = b
+a <|| _ = a
+
 instance Read UTCTime where
-    readsPrec n s = [(zonedTimeToUTC t, r) | (t, r) <- readsPrec n s]
+    readsPrec n s = do
+        (lt, s') <- readsPrec n s
+        (tz, s'') <- readsPrec n s' <|| pure (utc, s')
+        return (localTimeToUTC tz lt, s'')
 
 instance Read UniversalTime where
     readsPrec n s = [(localTimeToUT1 0 t, r) | (t, r) <- readsPrec n s]
diff --git a/lib/Data/Time/Format/Parse/Class.hs b/lib/Data/Time/Format/Parse/Class.hs
--- a/lib/Data/Time/Format/Parse/Class.hs
+++ b/lib/Data/Time/Format/Parse/Class.hs
@@ -1,15 +1,17 @@
-module Data.Time.Format.Parse.Class
-    (
-        -- * Parsing
-      ParseNumericPadding(..)
-    , ParseTime(..)
-    , parseSpecifiers
-    , timeSubstituteTimeSpecifier
-    , timeParseTimeSpecifier
-    , durationParseTimeSpecifier
-    ) where
+{-# LANGUAGE Safe #-}
 
+module Data.Time.Format.Parse.Class (
+    ParseNumericPadding (..),
+    ParseTime (..),
+    parseSpecifiers,
+    timeSubstituteTimeSpecifier,
+    timeParseTimeSpecifier,
+    durationParseTimeSpecifier,
+) where
+
+import Control.Monad
 import Data.Char
+import Data.Foldable
 import Data.Maybe
 import Data.Proxy
 import Data.Time.Format.Locale
@@ -26,10 +28,12 @@
     -- | @since 1.9.1
     substituteTimeSpecifier :: Proxy t -> TimeLocale -> Char -> Maybe String
     substituteTimeSpecifier _ _ _ = Nothing
+
     -- | Get the string corresponding to the given format specifier.
     --
     -- @since 1.9.1
     parseTimeSpecifier :: Proxy t -> TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
+
     -- | Builds a time value from a parsed input string.
     -- If the input does not include all the information needed to
     -- construct a complete value, any missing parts should be taken
@@ -38,10 +42,12 @@
     --
     -- @since 1.9.1
     buildTime ::
-           TimeLocale -- ^ The time locale.
-        -> [(Char, String)] -- ^ Pairs of format characters and the
-                                 -- corresponding part of the input.
-        -> Maybe t
+        -- | The time locale.
+        TimeLocale ->
+        -- | Pairs of format characters and the
+        -- corresponding part of the input.
+        [(Char, String)] ->
+        Maybe t
 
 -- | Case-insensitive version of 'Text.ParserCombinators.ReadP.char'.
 charCI :: Char -> ReadP Char
@@ -52,7 +58,7 @@
 stringCI this = do
     let
         scan [] _ = return this
-        scan (x:xs) (y:ys)
+        scan (x : xs) (y : ys)
             | toUpper x == toUpper y = do
                 _ <- get
                 scan xs ys
@@ -61,147 +67,186 @@
     scan this s
 
 parseSpecifiers :: ParseTime t => Proxy t -> TimeLocale -> String -> ReadP [(Char, String)]
-parseSpecifiers pt locale = let
-    parse :: String -> ReadP [(Char, String)]
-    parse [] = return []
-    parse ('%':cs) = parse1 cs
-    parse (c:cs)
-        | isSpace c = do
+parseSpecifiers pt locale =
+    let
+        parse :: String -> ReadP [(Char, String)]
+        parse [] = return []
+        parse ('%' : cs) = parse1 cs
+        parse (c : cs) | isSpace c = do
             _ <- satisfy isSpace
             case cs of
-                (c':_)
-                    | isSpace c' -> return ()
+                (c' : _) | isSpace c' -> return ()
                 _ -> skipSpaces
             parse cs
-    parse (c:cs) = do
-        _ <- charCI c
-        parse cs
-    parse1 :: String -> ReadP [(Char, String)]
-    parse1 ('-':cs) = parse2 (Just NoPadding) cs
-    parse1 ('_':cs) = parse2 (Just SpacePadding) cs
-    parse1 ('0':cs) = parse2 (Just ZeroPadding) cs
-    parse1 cs = parse2 Nothing cs
-    parse2 :: Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
-    parse2 mpad ('E':cs) = parse3 mpad True cs
-    parse2 mpad cs = parse3 mpad False cs
-    parse3 :: Maybe ParseNumericPadding -> Bool -> String -> ReadP [(Char, String)]
-    parse3 _ _ ('%':cs) = do
-        _ <- char '%'
-        parse cs
-    parse3 _ _ (c:cs)
-        | Just s <- substituteTimeSpecifier pt locale c = parse $ s ++ cs
-    parse3 mpad _alt (c:cs) = do
-        str <- parseTimeSpecifier pt locale mpad c
-        specs <- parse cs
-        return $ (c, str) : specs
-    parse3 _ _ [] = return []
-    in parse
+        parse (c : cs) = do
+            _ <- charCI c
+            parse cs
+        parse1 :: String -> ReadP [(Char, String)]
+        parse1 ('-' : cs) = parse2 (Just NoPadding) cs
+        parse1 ('_' : cs) = parse2 (Just SpacePadding) cs
+        parse1 ('0' : cs) = parse2 (Just ZeroPadding) cs
+        parse1 cs = parse2 Nothing cs
+        parse2 :: Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
+        parse2 mpad ('E' : cs) = parse3 mpad True cs
+        parse2 mpad cs = parse3 mpad False cs
+        parse3 :: Maybe ParseNumericPadding -> Bool -> String -> ReadP [(Char, String)]
+        parse3 _ _ ('%' : cs) = do
+            _ <- char '%'
+            parse cs
+        parse3 _ _ (c : cs) | Just s <- substituteTimeSpecifier pt locale c = parse $ s ++ cs
+        parse3 mpad _alt (c : cs) = do
+            str <- parseTimeSpecifier pt locale mpad c
+            specs <- parse cs
+            return $ (c, str) : specs
+        parse3 _ _ [] = return []
+    in
+        parse
 
 data PaddingSide
     = PrePadding
     | PostPadding
 
-allowEmptyParser :: Bool -> ReadP String
-allowEmptyParser False = many1 (satisfy isDigit)
-allowEmptyParser True = many (satisfy isDigit)
+data EmptyOption = AllowEmptyOption | ForbidEmptyOption
 
-parsePaddedDigits :: PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
-parsePaddedDigits _ ZeroPadding _ n = count n (satisfy isDigit)
-parsePaddedDigits PrePadding SpacePadding allowEmpty _n = skipSpaces >> allowEmptyParser allowEmpty
-parsePaddedDigits PostPadding SpacePadding allowEmpty _n = do
-    r <- allowEmptyParser allowEmpty
+checkEmptyOption :: EmptyOption -> String -> ReadP ()
+checkEmptyOption ForbidEmptyOption "" = mzero
+checkEmptyOption _ _ = return ()
+
+data MunchType = AmbiguousMunchType | MaximalMunchType
+
+data Munch = InexactMunch MunchType | ExactMunch Int
+
+munchDigits :: MunchType -> ReadP String
+munchDigits AmbiguousMunchType = many $ satisfy isDigit
+munchDigits MaximalMunchType = munch isDigit
+
+checkAll :: (a -> Bool) -> [a] -> ReadP ()
+checkAll f l = for_ l $ \c -> if f c then return () else mzero
+
+parseAnyPaddedDigits :: Maybe PaddingSide -> Munch -> ReadP String
+parseAnyPaddedDigits mpad (ExactMunch n) = do
+    chars <- count n get
+    case mpad of
+        Nothing -> do
+            checkAll isDigit chars
+            return chars
+        Just PrePadding -> do
+            let
+                digits = dropWhile isSpace chars
+            checkAll isDigit digits
+            return digits
+        Just PostPadding -> do
+            let
+                (digits, spaces) = span isDigit chars
+            checkAll isSpace spaces
+            return digits
+parseAnyPaddedDigits Nothing (InexactMunch munchtype) = munchDigits munchtype
+parseAnyPaddedDigits (Just PrePadding) (InexactMunch munchtype) = do
     skipSpaces
+    munchDigits munchtype
+parseAnyPaddedDigits (Just PostPadding) (InexactMunch munchtype) = do
+    r <- munchDigits munchtype
+    skipSpaces
     return r
-parsePaddedDigits _ NoPadding False _n = many1 (satisfy isDigit)
-parsePaddedDigits _ NoPadding True _n = many (satisfy isDigit)
 
-parsePaddedSignedDigits :: ParseNumericPadding -> Int -> ReadP String
-parsePaddedSignedDigits pad n = do
-    sign <- option "" $ char '-' >> return "-"
-    digits <- parsePaddedDigits PrePadding pad False n
-    return $ sign ++ digits
+parsePaddedDigits :: Maybe PaddingSide -> Munch -> EmptyOption -> ReadP String
+parsePaddedDigits mps mn eo = do
+    digits <- parseAnyPaddedDigits mps mn
+    checkEmptyOption eo digits
+    return digits
 
-parseSignedDecimal :: ReadP String
-parseSignedDecimal = do
-    sign <- option "" $ char '-' >> return "-"
-    skipSpaces
-    digits <- many1 $ satisfy isDigit
-    decimaldigits <-
-        option "" $ do
-            _ <- char '.'
-            dd <- many $ satisfy isDigit
-            return $ '.' : dd
-    return $ sign ++ digits ++ decimaldigits
+parsePaddingDigits :: PaddingSide -> ParseNumericPadding -> EmptyOption -> MunchType -> Int -> ReadP String
+parsePaddingDigits _ps NoPadding eo mt _n = parsePaddedDigits Nothing (InexactMunch mt) eo
+parsePaddingDigits _ps ZeroPadding eo _mt n = parsePaddedDigits Nothing (ExactMunch n) eo
+parsePaddingDigits ps SpacePadding eo mt _n = parsePaddedDigits (Just ps) (InexactMunch mt) eo
 
+allowNegative :: ReadP String -> ReadP String
+allowNegative p = do
+    sign <- option "" $ fmap pure $ char '-'
+    val <- p
+    return $ sign ++ val
+
 timeParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
-timeParseTimeSpecifier l mpad c = let
-    digits' ps pad = parsePaddedDigits ps (fromMaybe pad mpad)
-    digits pad = digits' PrePadding pad False
-    oneOf = choice . map stringCI
-    numericTZ = do
-        s <- choice [char '+', char '-']
-        h <- parsePaddedDigits PrePadding ZeroPadding False 2
-        optional (char ':')
-        m <- parsePaddedDigits PrePadding ZeroPadding False 2
-        return (s : h ++ m)
-    in case c of
-        -- century
-           'C' -> (char '-' >> fmap ('-' :) (digits SpacePadding 2)) <++ digits SpacePadding 2
-           'f' -> digits SpacePadding 2
-        -- year
-           'Y' -> (char '-' >> fmap ('-' :) (digits SpacePadding 4)) <++ digits SpacePadding 4
-           'G' -> digits SpacePadding 4
-        -- year of century
-           'y' -> digits ZeroPadding 2
-           'g' -> digits ZeroPadding 2
-        -- month of year
-           'B' -> oneOf (map fst (months l))
-           'b' -> oneOf (map snd (months l))
-           'm' -> digits ZeroPadding 2
-        -- day of month
-           'd' -> digits ZeroPadding 2
-           'e' -> digits SpacePadding 2
-        -- week of year
-           'V' -> digits ZeroPadding 2
-           'U' -> digits ZeroPadding 2
-           'W' -> digits ZeroPadding 2
-        -- day of week
-           'u' -> oneOf $ map (: []) ['1' .. '7']
-           'a' -> oneOf (map snd (wDays l))
-           'A' -> oneOf (map fst (wDays l))
-           'w' -> oneOf $ map (: []) ['0' .. '6']
-        -- day of year
-           'j' -> digits ZeroPadding 3
-        -- dayhalf of day (i.e. AM or PM)
-           'P' ->
-               oneOf
-                   (let
+timeParseTimeSpecifier l mpad c =
+    let
+        parseDigits :: PaddingSide -> ParseNumericPadding -> EmptyOption -> MunchType -> Int -> ReadP String
+        parseDigits ps pad = parsePaddingDigits ps $ fromMaybe pad mpad
+
+        parseDigitsUsual :: ParseNumericPadding -> Int -> ReadP String
+        parseDigitsUsual pad = parseDigits PrePadding pad ForbidEmptyOption AmbiguousMunchType
+
+        oneOf = choice . map stringCI
+        numericTZ = do
+            s <- choice [char '+', char '-']
+            h <- parseDigitsUsual ZeroPadding 2
+            optional (char ':')
+            m <- parseDigitsUsual ZeroPadding 2
+            return (s : h ++ m)
+    in
+        case c of
+            -- century
+            'C' -> allowNegative $ parseDigitsUsual SpacePadding 2
+            'f' -> allowNegative $ parseDigitsUsual SpacePadding 2
+            -- year
+            'Y' -> allowNegative $ parseDigitsUsual SpacePadding 4
+            'G' -> allowNegative $ parseDigitsUsual SpacePadding 4
+            -- year of century
+            'y' -> parseDigitsUsual ZeroPadding 2
+            'g' -> parseDigitsUsual ZeroPadding 2
+            -- quarter of year
+            'v' -> parseDigitsUsual ZeroPadding 1
+            -- month of year
+            'B' -> oneOf (map fst (months l))
+            'b' -> oneOf (map snd (months l))
+            'm' -> parseDigitsUsual ZeroPadding 2
+            -- day of month
+            'd' -> parseDigitsUsual ZeroPadding 2
+            'e' -> parseDigitsUsual SpacePadding 2
+            -- week of year
+            'V' -> parseDigitsUsual ZeroPadding 2
+            'U' -> parseDigitsUsual ZeroPadding 2
+            'W' -> parseDigitsUsual ZeroPadding 2
+            -- day of week
+            'u' -> oneOf $ map (: []) ['1' .. '7']
+            'a' -> oneOf (map snd (wDays l))
+            'A' -> oneOf (map fst (wDays l))
+            'w' -> oneOf $ map (: []) ['0' .. '6']
+            -- day of year
+            'j' -> parseDigitsUsual ZeroPadding 3
+            -- dayhalf of day (i.e. AM or PM)
+            'P' ->
+                oneOf
+                    ( let
                         (am, pm) = amPm l
-                        in [am, pm])
-           'p' ->
-               oneOf
-                   (let
+                      in
+                        [am, pm]
+                    )
+            'p' ->
+                oneOf
+                    ( let
                         (am, pm) = amPm l
-                        in [am, pm])
-        -- hour of day (i.e. 24h)
-           'H' -> digits ZeroPadding 2
-           'k' -> digits SpacePadding 2
-        -- hour of dayhalf (i.e. 12h)
-           'I' -> digits ZeroPadding 2
-           'l' -> digits SpacePadding 2
-        -- minute of hour
-           'M' -> digits ZeroPadding 2
-        -- second of minute
-           'S' -> digits ZeroPadding 2
-        -- picosecond of second
-           'q' -> digits' PostPadding ZeroPadding True 12
-           'Q' -> (char '.' >> digits' PostPadding NoPadding True 12) <++ return ""
-        -- time zone
-           'z' -> numericTZ
-           'Z' -> munch1 isAlpha <++ numericTZ
-        -- seconds since epoch
-           's' -> (char '-' >> fmap ('-' :) (munch1 isDigit)) <++ munch1 isDigit
-           _ -> fail $ "Unknown format character: " ++ show c
+                      in
+                        [am, pm]
+                    )
+            -- hour of day (i.e. 24h)
+            'H' -> parseDigitsUsual ZeroPadding 2
+            'k' -> parseDigitsUsual SpacePadding 2
+            -- hour of dayhalf (i.e. 12h)
+            'I' -> parseDigitsUsual ZeroPadding 2
+            'l' -> parseDigitsUsual SpacePadding 2
+            -- minute of hour
+            'M' -> parseDigitsUsual ZeroPadding 2
+            -- second of minute
+            'S' -> parseDigitsUsual ZeroPadding 2
+            -- picosecond of second
+            'q' -> parseDigits PostPadding NoPadding AllowEmptyOption MaximalMunchType 12
+            'Q' -> (char '.' >> parseDigits PostPadding NoPadding AllowEmptyOption MaximalMunchType 12) <++ return ""
+            -- time zone
+            'z' -> numericTZ
+            'Z' -> munch1 isAlpha <++ numericTZ
+            -- seconds since epoch
+            's' -> (char '-' >> fmap ('-' :) (munch1 isDigit)) <++ munch1 isDigit
+            _ -> fail $ "Unknown format character: " ++ show c
 
 timeSubstituteTimeSpecifier :: TimeLocale -> Char -> Maybe String
 timeSubstituteTimeSpecifier l 'c' = Just $ dateTimeFmt l
@@ -216,19 +261,33 @@
 timeSubstituteTimeSpecifier _ _ = Nothing
 
 durationParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
-durationParseTimeSpecifier _ mpad c = let
-    padopt = parsePaddedSignedDigits $ fromMaybe NoPadding mpad
-    in case c of
-           'y' -> padopt 1
-           'b' -> padopt 1
-           'B' -> padopt 2
-           'w' -> padopt 1
-           'd' -> padopt 1
-           'D' -> padopt 1
-           'h' -> padopt 1
-           'H' -> padopt 2
-           'm' -> padopt 1
-           'M' -> padopt 2
-           's' -> parseSignedDecimal
-           'S' -> parseSignedDecimal
-           _ -> fail $ "Unknown format character: " ++ show c
+durationParseTimeSpecifier _ mpad c =
+    let
+        parsePaddedSignedDigits :: Int -> ReadP String
+        parsePaddedSignedDigits n = allowNegative $ do
+            parsePaddingDigits PrePadding (fromMaybe NoPadding mpad) ForbidEmptyOption MaximalMunchType n
+
+        parseSignedDecimal :: ReadP String
+        parseSignedDecimal = allowNegative $ do
+            digits <- munch1 isDigit
+            decimaldigits <-
+                option "" $ do
+                    _ <- char '.'
+                    dd <- munch isDigit
+                    return $ '.' : dd
+            return $ digits ++ decimaldigits
+    in
+        case c of
+            'y' -> parsePaddedSignedDigits 1
+            'b' -> parsePaddedSignedDigits 1
+            'B' -> parsePaddedSignedDigits 2
+            'w' -> parsePaddedSignedDigits 1
+            'd' -> parsePaddedSignedDigits 1
+            'D' -> parsePaddedSignedDigits 1
+            'h' -> parsePaddedSignedDigits 1
+            'H' -> parsePaddedSignedDigits 2
+            'm' -> parsePaddedSignedDigits 1
+            'M' -> parsePaddedSignedDigits 2
+            's' -> parseSignedDecimal
+            'S' -> parseSignedDecimal
+            _ -> fail $ "Unknown format character: " ++ show c
diff --git a/lib/Data/Time/Format/Parse/Instances.hs b/lib/Data/Time/Format/Parse/Instances.hs
--- a/lib/Data/Time/Format/Parse/Instances.hs
+++ b/lib/Data/Time/Format/Parse/Instances.hs
@@ -1,23 +1,25 @@
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.Format.Parse.Instances
-    (
-    ) where
+module Data.Time.Format.Parse.Instances (
 
-#if MIN_VERSION_base(4,13,0)
+) where
+
 import Control.Applicative ((<|>))
-#else
-import Control.Applicative ((<$>), (<*>), (<|>))
-#endif
 import Data.Char
 import Data.Fixed
-import Data.List
+import Data.List (elemIndex, find)
+import Data.Maybe
 import Data.Ratio
 import Data.Time.Calendar.CalendarDiffDays
 import Data.Time.Calendar.Days
 import Data.Time.Calendar.Gregorian
+import Data.Time.Calendar.Month
 import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.Private (clipValid)
+import Data.Time.Calendar.Quarter
+import Data.Time.Calendar.Types
 import Data.Time.Calendar.WeekDate
 import Data.Time.Clock.Internal.DiffTime
 import Data.Time.Clock.Internal.NominalDiffTime
@@ -34,236 +36,474 @@
 import Data.Traversable
 import Text.Read (readMaybe)
 
-data DayComponent
-    = Century Integer -- century of all years
-    | CenturyYear Integer -- 0-99, last two digits of both real years and week years
-    | YearMonth Int -- 1-12
-    | MonthDay Int -- 1-31
-    | YearDay Int -- 1-366
-    | WeekDay Int -- 1-7 (mon-sun)
-    | YearWeek WeekType
-               Int -- 1-53 or 0-53
-
 data WeekType
     = ISOWeek
     | SundayWeek
     | MondayWeek
+    deriving Eq
 
-instance ParseTime Day where
-    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
-    parseTimeSpecifier _ = timeParseTimeSpecifier
-    buildTime l = let
-        -- 'Nothing' indicates a parse failure,
-        -- while 'Just []' means no information
-        f :: Char -> String -> Maybe [DayComponent]
-        f c x = let
-            ra :: (Read a) => Maybe a
-            ra = readMaybe x
-            zeroBasedListIndex :: [String] -> Maybe Int
-            zeroBasedListIndex ss = elemIndex (map toUpper x) $ fmap (map toUpper) ss
-            oneBasedListIndex :: [String] -> Maybe Int
-            oneBasedListIndex ss = do
-                index <- zeroBasedListIndex ss
-                return $ 1 + index
-            in case c of
+mkDayFromWeekType :: WeekType -> Year -> WeekOfYear -> DayOfWeek -> Maybe Day
+mkDayFromWeekType wt y woy dow =
+    case wt of
+        ISOWeek -> fromWeekDateValid y woy $ fromEnum dow
+        SundayWeek -> fromSundayStartWeekValid y woy $ mod (fromEnum dow) 7
+        MondayWeek -> fromMondayStartWeekValid y woy $ fromEnum dow
+
+data DayFact
+    = CenturyDayFact Integer -- century of all years
+    | YearOfCenturyDayFact Integer -- 0-99, last two digits of both real years and week years
+    | QuarterOfYearDayFact QuarterOfYear
+    | MonthOfYearDayFact MonthOfYear -- 1-12
+    | DayOfMonthDayFact DayOfMonth -- 1-31
+    | DayOfYearDayFact DayOfYear -- 1-366
+    | DayOfWeekDayFact DayOfWeek
+    | WeekOfYearDayFact
+        WeekType
+        WeekOfYear -- 1-53 or 0-53
+    | UTCTimeDayFact UTCTime
+    | TimeZoneDayFact TimeZone
+
+lastMatch :: (a -> Maybe b) -> [a] -> Maybe b
+lastMatch f aa = listToMaybe $ reverse $ catMaybes $ fmap f aa
+
+dayFactGetCentury :: [DayFact] -> Maybe Integer
+dayFactGetCentury = lastMatch $ \case
+    CenturyDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetYearOfCentury :: [DayFact] -> Maybe Integer
+dayFactGetYearOfCentury = lastMatch $ \case
+    YearOfCenturyDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetQuarterOfYear :: [DayFact] -> Maybe QuarterOfYear
+dayFactGetQuarterOfYear = lastMatch $ \case
+    QuarterOfYearDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetMonthOfYear :: [DayFact] -> Maybe MonthOfYear
+dayFactGetMonthOfYear = lastMatch $ \case
+    MonthOfYearDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetDayOfMonth :: [DayFact] -> Maybe DayOfMonth
+dayFactGetDayOfMonth = lastMatch $ \case
+    DayOfMonthDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetDayOfYear :: [DayFact] -> Maybe DayOfYear
+dayFactGetDayOfYear = lastMatch $ \case
+    DayOfYearDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetDayOfWeek :: [DayFact] -> Maybe DayOfWeek
+dayFactGetDayOfWeek = lastMatch $ \case
+    DayOfWeekDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetWeekOfYear :: [DayFact] -> Maybe (WeekType, WeekOfYear)
+dayFactGetWeekOfYear = lastMatch $ \case
+    WeekOfYearDayFact wt x -> Just (wt, x)
+    _ -> Nothing
+
+dayFactGetUTCTime :: [DayFact] -> Maybe UTCTime
+dayFactGetUTCTime = lastMatch $ \case
+    UTCTimeDayFact x -> Just x
+    _ -> Nothing
+
+dayFactGetTimeZone :: [DayFact] -> Maybe TimeZone
+dayFactGetTimeZone = lastMatch $ \case
+    TimeZoneDayFact x -> Just x
+    _ -> Nothing
+
+readSpec_z :: String -> Maybe Int
+readSpec_z = readTzOffset
+
+readSpec_Z :: TimeLocale -> String -> Maybe TimeZone
+readSpec_Z _ str | Just offset <- readTzOffset str = Just $ TimeZone offset False ""
+readSpec_Z l str | Just zone <- getKnownTimeZone l str = Just zone
+readSpec_Z _ "UTC" = Just utc
+readSpec_Z _ [c] | Just zone <- getMilZone c = Just zone
+readSpec_Z _ _ = Nothing
+
+makeDayFact :: TimeLocale -> Char -> String -> Maybe [DayFact]
+makeDayFact l c x =
+    let
+        ra :: Read a => Maybe a
+        ra = readMaybe x
+        zeroBasedListIndex :: [String] -> Maybe Int
+        zeroBasedListIndex ss = elemIndex (map toUpper x) $ fmap (map toUpper) ss
+        oneBasedListIndex :: [String] -> Maybe Int
+        oneBasedListIndex ss = do
+            index <- zeroBasedListIndex ss
+            return $ 1 + index
+    in
+        case c of
             -- %C: century (all but the last two digits of the year), 00 - 99
-                   'C' -> do
-                       a <- ra
-                       return [Century a]
+            'C' -> do
+                a <- ra
+                return [CenturyDayFact a]
             -- %f century (all but the last two digits of the year), 00 - 99
-                   'f' -> do
-                       a <- ra
-                       return [Century a]
+            'f' -> do
+                a <- ra
+                return [CenturyDayFact a]
             -- %Y: year
-                   'Y' -> do
-                       a <- ra
-                       return [Century (a `div` 100), CenturyYear (a `mod` 100)]
+            'Y' -> do
+                a <- ra
+                return [CenturyDayFact (a `div` 100), YearOfCenturyDayFact (a `mod` 100)]
             -- %G: year for Week Date format
-                   'G' -> do
-                       a <- ra
-                       return [Century (a `div` 100), CenturyYear (a `mod` 100)]
+            'G' -> do
+                a <- ra
+                return [CenturyDayFact (a `div` 100), YearOfCenturyDayFact (a `mod` 100)]
             -- %y: last two digits of year, 00 - 99
-                   'y' -> do
-                       a <- ra
-                       return [CenturyYear a]
+            'y' -> do
+                a <- ra
+                return [YearOfCenturyDayFact a]
             -- %g: last two digits of year for Week Date format, 00 - 99
-                   'g' -> do
-                       a <- ra
-                       return [CenturyYear a]
+            'g' -> do
+                a <- ra
+                return [YearOfCenturyDayFact a]
+            -- %v: quarter of year, 1 - 4
+            'v' -> do
+                raw <- ra
+                a <- clipValid 1 4 raw
+                return [QuarterOfYearDayFact $ toEnum a]
             -- %B: month name, long form (fst from months locale), January - December
-                   'B' -> do
-                       a <- oneBasedListIndex $ fmap fst $ months l
-                       return [YearMonth a]
+            'B' -> do
+                a <- oneBasedListIndex $ fmap fst $ months l
+                return [MonthOfYearDayFact a]
             -- %b: month name, short form (snd from months locale), Jan - Dec
-                   'b' -> do
-                       a <- oneBasedListIndex $ fmap snd $ months l
-                       return [YearMonth a]
+            'b' -> do
+                a <- oneBasedListIndex $ fmap snd $ months l
+                return [MonthOfYearDayFact a]
             -- %m: month of year, leading 0 as needed, 01 - 12
-                   'm' -> do
-                       raw <- ra
-                       a <- clipValid 1 12 raw
-                       return [YearMonth a]
+            'm' -> do
+                raw <- ra
+                a <- clipValid 1 12 raw
+                return [MonthOfYearDayFact a]
             -- %d: day of month, leading 0 as needed, 01 - 31
-                   'd' -> do
-                       raw <- ra
-                       a <- clipValid 1 31 raw
-                       return [MonthDay a]
+            'd' -> do
+                raw <- ra
+                a <- clipValid 1 31 raw
+                return [DayOfMonthDayFact a]
             -- %e: day of month, leading space as needed, 1 - 31
-                   'e' -> do
-                       raw <- ra
-                       a <- clipValid 1 31 raw
-                       return [MonthDay a]
+            'e' -> do
+                raw <- ra
+                a <- clipValid 1 31 raw
+                return [DayOfMonthDayFact a]
             -- %V: week for Week Date format, 01 - 53
-                   'V' -> do
-                       raw <- ra
-                       a <- clipValid 1 53 raw
-                       return [YearWeek ISOWeek a]
+            'V' -> do
+                raw <- ra
+                a <- clipValid 1 53 raw
+                return [WeekOfYearDayFact ISOWeek a]
             -- %U: week number of year, where weeks start on Sunday (as sundayStartWeek), 00 - 53
-                   'U' -> do
-                       raw <- ra
-                       a <- clipValid 0 53 raw
-                       return [YearWeek SundayWeek a]
+            'U' -> do
+                raw <- ra
+                a <- clipValid 0 53 raw
+                return [WeekOfYearDayFact SundayWeek a]
             -- %W: week number of year, where weeks start on Monday (as mondayStartWeek), 00 - 53
-                   'W' -> do
-                       raw <- ra
-                       a <- clipValid 0 53 raw
-                       return [YearWeek MondayWeek a]
+            'W' -> do
+                raw <- ra
+                a <- clipValid 0 53 raw
+                return [WeekOfYearDayFact MondayWeek a]
             -- %u: day for Week Date format, 1 - 7
-                   'u' -> do
-                       raw <- ra
-                       a <- clipValid 1 7 raw
-                       return [WeekDay a]
+            'u' -> do
+                raw <- ra
+                a <- clipValid 1 7 raw
+                return [DayOfWeekDayFact $ toEnum a]
             -- %a: day of week, short form (snd from wDays locale), Sun - Sat
-                   'a' -> do
-                       a' <- zeroBasedListIndex $ fmap snd $ wDays l
-                       let
-                           a =
-                               if a' == 0
-                                   then 7
-                                   else a'
-                       return [WeekDay a]
+            'a' -> do
+                a <- zeroBasedListIndex $ fmap snd $ wDays l
+                return [DayOfWeekDayFact $ toEnum a]
             -- %A: day of week, long form (fst from wDays locale), Sunday - Saturday
-                   'A' -> do
-                       a' <- zeroBasedListIndex $ fmap fst $ wDays l
-                       let
-                           a =
-                               if a' == 0
-                                   then 7
-                                   else a'
-                       return [WeekDay a]
+            'A' -> do
+                a <- zeroBasedListIndex $ fmap fst $ wDays l
+                return [DayOfWeekDayFact $ toEnum a]
             -- %w: day of week number, 0 (= Sunday) - 6 (= Saturday)
-                   'w' -> do
-                       raw <- ra
-                       a' <- clipValid 0 6 raw
-                       let
-                           a =
-                               if a' == 0
-                                   then 7
-                                   else a'
-                       return [WeekDay a]
+            'w' -> do
+                raw <- ra
+                a <- clipValid 0 6 raw
+                return [DayOfWeekDayFact $ toEnum a]
             -- %j: day of year for Ordinal Date format, 001 - 366
-                   'j' -> do
-                       raw <- ra
-                       a <- clipValid 1 366 raw
-                       return [YearDay a]
+            'j' -> do
+                raw <- ra
+                a <- clipValid 1 366 raw
+                return [DayOfYearDayFact a]
+            -- %s: number of whole seconds since the Unix epoch.
+            's' -> do
+                raw <- ra
+                return [UTCTimeDayFact $ posixSecondsToUTCTime $ fromInteger raw]
+            'z' -> do
+                a <- readSpec_z x
+                return [TimeZoneDayFact $ TimeZone a False ""]
+            'Z' -> do
+                a <- readSpec_Z l x
+                return [TimeZoneDayFact a]
             -- unrecognised, pass on to other parsers
-                   _ -> return []
-        buildDay :: [DayComponent] -> Maybe Day
-        buildDay cs = let
-            safeLast x xs = last (x : xs)
-            y = let
-                d = safeLast 70 [x | CenturyYear x <- cs]
-                c =
-                    safeLast
-                        (if d >= 69
-                             then 19
-                             else 20)
-                        [x | Century x <- cs]
-                in 100 * c + d
-            rest (YearMonth m:_) = let
-                d = safeLast 1 [x | MonthDay x <- cs]
-                in fromGregorianValid y m d
-            rest (YearDay d:_) = fromOrdinalDateValid y d
-            rest (YearWeek wt w:_) = let
-                d = safeLast 4 [x | WeekDay x <- cs]
-                in case wt of
-                       ISOWeek -> fromWeekDateValid y w d
-                       SundayWeek -> fromSundayStartWeekValid y w (d `mod` 7)
-                       MondayWeek -> fromMondayStartWeekValid y w d
-            rest (_:xs) = rest xs
-            rest [] = rest [YearMonth 1]
-            in rest cs
-        in \pairs -> do
-               components <- for pairs $ \(c, x) -> f c x
-               buildDay $ concat components
+            _ -> return []
 
-mfoldl :: (Monad m) => (a -> b -> m a) -> m a -> [b] -> m a
-mfoldl f = let
-    mf ma b = do
-        a <- ma
-        f a b
-    in foldl mf
+makeDayFacts :: TimeLocale -> [(Char, String)] -> Maybe [DayFact]
+makeDayFacts l pairs = do
+    factss <- for pairs $ \(c, x) -> makeDayFact l c x
+    return $ mconcat factss
 
-instance ParseTime TimeOfDay where
+dayFactYear :: [DayFact] -> Integer
+dayFactYear facts =
+    let
+        d = fromMaybe 70 $ dayFactGetYearOfCentury facts
+        c =
+            fromMaybe
+                ( if d >= 69
+                    then 19
+                    else 20
+                )
+                $ dayFactGetCentury facts
+    in
+        100 * c + d
+
+dayFactDay :: [DayFact] -> Maybe Day
+dayFactDay facts =
+    case dayFactYear facts of
+        y | Just doy <- dayFactGetDayOfYear facts -> fromOrdinalDateValid y doy
+        y
+            | Just moy <- dayFactGetMonthOfYear facts ->
+                let
+                    dom = fromMaybe 1 $ dayFactGetDayOfMonth facts
+                in
+                    fromGregorianValid y moy dom
+        y
+            | Just (wt, woy) <- dayFactGetWeekOfYear facts ->
+                let
+                    dow = fromMaybe Thursday $ dayFactGetDayOfWeek facts
+                in
+                    mkDayFromWeekType wt y woy dow
+        y
+            | Just qoy <- dayFactGetQuarterOfYear facts ->
+                let
+                    moy = case qoy of
+                        Q1 -> 1
+                        Q2 -> 4
+                        Q3 -> 7
+                        Q4 -> 10
+                    dom = fromMaybe 1 $ dayFactGetDayOfMonth facts
+                in
+                    fromGregorianValid y moy dom
+        _
+            | Just ut <- dayFactGetUTCTime facts ->
+                let
+                    tz = fromMaybe utc $ dayFactGetTimeZone facts
+                in
+                    Just $ localDay $ utcToLocalTime tz ut
+        y | Just dom <- dayFactGetDayOfMonth facts -> fromGregorianValid y 1 dom
+        y | Just dow <- dayFactGetDayOfWeek facts -> fromWeekDateValid y 1 $ fromEnum dow
+        y -> fromOrdinalDateValid y 1
+
+instance ParseTime Day where
     substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
     parseTimeSpecifier _ = timeParseTimeSpecifier
-    buildTime l = let
-        f t@(TimeOfDay h m s) (c, x) = let
-            ra :: (Read a) => Maybe a
-            ra = readMaybe x
-            getAmPm = let
+    buildTime l pairs = do
+        facts <- makeDayFacts l pairs
+        dayFactDay facts
+
+instance ParseTime DayOfWeek where
+    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
+    parseTimeSpecifier _ = timeParseTimeSpecifier
+    buildTime l pairs = do
+        facts <- makeDayFacts l pairs
+        dayFactGetDayOfWeek facts
+            <|> (fmap dayOfWeek $ dayFactDay facts)
+
+instance ParseTime Month where
+    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
+    parseTimeSpecifier _ = timeParseTimeSpecifier
+    buildTime l pairs = do
+        facts <- makeDayFacts l pairs
+        case dayFactGetMonthOfYear facts of
+            Just moy ->
+                let
+                    y = dayFactYear facts
+                in
+                    Just $ YearMonth y moy
+            Nothing -> fmap dayPeriod $ dayFactDay facts
+
+instance ParseTime QuarterOfYear where
+    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
+    parseTimeSpecifier _ = timeParseTimeSpecifier
+    buildTime l pairs = do
+        facts <- makeDayFacts l pairs
+        case dayFactGetQuarterOfYear facts of
+            Just qoy -> Just qoy
+            Nothing -> do
+                QuarterDay (YearQuarter _ qoy) _ <- dayFactDay facts
+                return qoy
+
+instance ParseTime Quarter where
+    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
+    parseTimeSpecifier _ = timeParseTimeSpecifier
+    buildTime l pairs = do
+        facts <- makeDayFacts l pairs
+        case dayFactGetQuarterOfYear facts of
+            Just qoy ->
+                let
+                    y = dayFactYear facts
+                in
+                    Just $ YearQuarter y qoy
+            Nothing -> fmap dayPeriod $ dayFactDay facts
+
+mfoldl :: Monad m => (a -> b -> m a) -> m a -> [b] -> m a
+mfoldl f =
+    let
+        mf ma b = do
+            a <- ma
+            f a b
+    in
+        foldl mf
+
+data AMPM = AM | PM
+
+data TimeFact
+    = AMAPMTimeFact AMPM
+    | HourTimeFact Int
+    | MinuteTimeFact Int
+    | WholeSecondTimeFact Int
+    | FractSecondTimeFact Pico
+    | UTCTimeFact UTCTime
+    | ZoneTimeFact TimeZone
+
+timeFactGetAMPM :: [TimeFact] -> Maybe AMPM
+timeFactGetAMPM = lastMatch $ \case
+    AMAPMTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetHour :: [TimeFact] -> Maybe Int
+timeFactGetHour = lastMatch $ \case
+    HourTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetMinute :: [TimeFact] -> Maybe Int
+timeFactGetMinute = lastMatch $ \case
+    MinuteTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetWholeSecond :: [TimeFact] -> Maybe Int
+timeFactGetWholeSecond = lastMatch $ \case
+    WholeSecondTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetFractSecond :: [TimeFact] -> Maybe Pico
+timeFactGetFractSecond = lastMatch $ \case
+    FractSecondTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetUTC :: [TimeFact] -> Maybe UTCTime
+timeFactGetUTC = lastMatch $ \case
+    UTCTimeFact x -> Just x
+    _ -> Nothing
+
+timeFactGetZone :: [TimeFact] -> Maybe TimeZone
+timeFactGetZone = lastMatch $ \case
+    ZoneTimeFact x -> Just x
+    _ -> Nothing
+
+makeTimeFact :: TimeLocale -> Char -> String -> Maybe [TimeFact]
+makeTimeFact l c x =
+    let
+        ra :: Read a => Maybe a
+        ra = readMaybe x
+        getAmPm =
+            let
                 upx = map toUpper x
                 (amStr, pmStr) = amPm l
-                in if upx == amStr
-                       then Just $ TimeOfDay (h `mod` 12) m s
-                       else if upx == pmStr
-                                then Just $
-                                     TimeOfDay
-                                         (if h < 12
-                                              then h + 12
-                                              else h)
-                                         m
-                                         s
-                                else Nothing
-            in case c of
-                   'P' -> getAmPm
-                   'p' -> getAmPm
-                   'H' -> do
-                       raw <- ra
-                       a <- clipValid 0 23 raw
-                       return $ TimeOfDay a m s
-                   'I' -> do
-                       raw <- ra
-                       a <- clipValid 1 12 raw
-                       return $ TimeOfDay a m s
-                   'k' -> do
-                       raw <- ra
-                       a <- clipValid 0 23 raw
-                       return $ TimeOfDay a m s
-                   'l' -> do
-                       raw <- ra
-                       a <- clipValid 1 12 raw
-                       return $ TimeOfDay a m s
-                   'M' -> do
-                       raw <- ra
-                       a <- clipValid 0 59 raw
-                       return $ TimeOfDay h a s
-                   'S' -> do
-                       raw <- ra
-                       a <- clipValid 0 60 raw
-                       return $ TimeOfDay h m (fromInteger a)
-                   'q' -> do
-                       ps <- (readMaybe $ take 12 $ rpad 12 '0' x) <|> return 0
-                       return $ TimeOfDay h m (mkPico (floor s) ps)
-                   'Q' ->
-                       if null x
-                           then Just t
-                           else do
-                               ps <- (readMaybe $ take 12 $ rpad 12 '0' x) <|> return 0
-                               return $ TimeOfDay h m (mkPico (floor s) ps)
-                   _ -> Just t
-        in mfoldl f (Just midnight)
+            in
+                if upx == amStr
+                    then Just [AMAPMTimeFact AM]
+                    else
+                        if upx == pmStr
+                            then Just [AMAPMTimeFact PM]
+                            else Nothing
+    in
+        case c of
+            'P' -> getAmPm
+            'p' -> getAmPm
+            'H' -> do
+                raw <- ra
+                a <- clipValid 0 23 raw
+                return [HourTimeFact a]
+            'I' -> do
+                raw <- ra
+                a <- clipValid 1 12 raw
+                return [HourTimeFact a]
+            'k' -> do
+                raw <- ra
+                a <- clipValid 0 23 raw
+                return [HourTimeFact a]
+            'l' -> do
+                raw <- ra
+                a <- clipValid 1 12 raw
+                return [HourTimeFact a]
+            'M' -> do
+                raw <- ra
+                a <- clipValid 0 59 raw
+                return [MinuteTimeFact a]
+            'S' -> do
+                raw <- ra
+                a <- clipValid 0 60 raw
+                return [WholeSecondTimeFact $ fromInteger a]
+            'q' -> do
+                ps <- (readMaybe $ take 12 $ rpad 12 '0' x) <|> return 0
+                return [FractSecondTimeFact $ mkPico 0 ps]
+            'Q' ->
+                if null x
+                    then return []
+                    else do
+                        ps <- (readMaybe $ take 12 $ rpad 12 '0' x) <|> return 0
+                        return [FractSecondTimeFact $ mkPico 0 ps]
+            's' -> do
+                raw <- ra
+                return [UTCTimeFact $ posixSecondsToUTCTime $ fromInteger raw]
+            'z' -> do
+                a <- readSpec_z x
+                return [ZoneTimeFact $ TimeZone a False ""]
+            'Z' -> do
+                a <- readSpec_Z l x
+                return [ZoneTimeFact a]
+            _ -> return []
 
+makeTimeFacts :: TimeLocale -> [(Char, String)] -> Maybe [TimeFact]
+makeTimeFacts l pairs = do
+    factss <- for pairs $ \(c, x) -> makeTimeFact l c x
+    return $ mconcat factss
+
+instance ParseTime TimeOfDay where
+    substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
+    parseTimeSpecifier _ = timeParseTimeSpecifier
+    buildTime l pairs = do
+        facts <- makeTimeFacts l pairs
+        -- 'Nothing' indicates a parse failure,
+        -- while 'Just []' means no information
+        case timeFactGetUTC facts of
+            Just t ->
+                let
+                    zone = fromMaybe utc $ timeFactGetZone facts
+                    sf = fromMaybe 0 $ timeFactGetFractSecond facts
+                    TimeOfDay h m s = localTimeOfDay $ utcToLocalTime zone t
+                in
+                    return $ TimeOfDay h m $ s + sf
+            Nothing ->
+                let
+                    h = fromMaybe 0 $ timeFactGetHour facts
+                    m = fromMaybe 0 $ timeFactGetMinute facts
+                    si = fromMaybe 0 $ timeFactGetWholeSecond facts
+                    sf = fromMaybe 0 $ timeFactGetFractSecond facts
+                    s :: Pico
+                    s = fromIntegral si + sf
+                    h' = case timeFactGetAMPM facts of
+                        Nothing -> h
+                        Just AM -> mod h 12
+                        Just PM -> if h < 12 then h + 12 else h
+                in
+                    return $ TimeOfDay h' m s
+
 rpad :: Int -> a -> [a] -> [a]
 rpad n c xs = xs ++ replicate (n - length xs) c
 
@@ -275,7 +515,7 @@
     parseTimeSpecifier _ = timeParseTimeSpecifier
     buildTime l xs = LocalTime <$> (buildTime l xs) <*> (buildTime l xs)
 
-enumDiff :: (Enum a) => a -> a -> Int
+enumDiff :: Enum a => a -> a -> Int
 enumDiff a b = (fromEnum a) - (fromEnum b)
 
 getMilZoneHours :: Char -> Maybe Int
@@ -292,11 +532,13 @@
 getMilZoneHours _ = Nothing
 
 getMilZone :: Char -> Maybe TimeZone
-getMilZone c = let
-    yc = toUpper c
-    in do
-           hours <- getMilZoneHours yc
-           return $ TimeZone (hours * 60) False [yc]
+getMilZone c =
+    let
+        yc = toUpper c
+    in
+        do
+            hours <- getMilZoneHours yc
+            return $ TimeZone (hours * 60) False [yc]
 
 getKnownTimeZone :: TimeLocale -> String -> Maybe TimeZone
 getKnownTimeZone locale x = find (\tz -> map toUpper x == timeZoneName tz) (knownTimeZones locale)
@@ -304,50 +546,49 @@
 instance ParseTime TimeZone where
     substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
     parseTimeSpecifier _ = timeParseTimeSpecifier
-    buildTime l = let
-        f :: Char -> String -> TimeZone -> Maybe TimeZone
-        f 'z' str (TimeZone _ dst name)
-            | Just offset <- readTzOffset str = Just $ TimeZone offset dst name
-        f 'z' _ _ = Nothing
-        f 'Z' str _
-            | Just offset <- readTzOffset str = Just $ TimeZone offset False ""
-        f 'Z' str _
-            | Just zone <- getKnownTimeZone l str = Just zone
-        f 'Z' "UTC" _ = Just utc
-        f 'Z' [c] _
-            | Just zone <- getMilZone c = Just zone
-        f 'Z' _ _ = Nothing
-        f _ _ tz = Just tz
-        in foldl (\mt (c, s) -> mt >>= f c s) (Just $ minutesToTimeZone 0)
+    buildTime l =
+        let
+            f :: Char -> String -> TimeZone -> Maybe TimeZone
+            f 'z' str (TimeZone _ dst name) = do
+                offset <- readSpec_z str
+                return $ TimeZone offset dst name
+            f 'Z' str _ = readSpec_Z l str
+            f _ _ tz = Just tz
+        in
+            foldl (\mt (c, s) -> mt >>= f c s) (Just $ minutesToTimeZone 0)
 
 readTzOffset :: String -> Maybe Int
-readTzOffset str = let
-    getSign '+' = Just 1
-    getSign '-' = Just (-1)
-    getSign _ = Nothing
-    calc s h1 h2 m1 m2 = do
-        sign <- getSign s
-        h <- readMaybe [h1, h2]
-        m <- readMaybe [m1, m2]
-        return $ sign * (60 * h + m)
-    in case str of
-           (s:h1:h2:':':m1:m2:[]) -> calc s h1 h2 m1 m2
-           (s:h1:h2:m1:m2:[]) -> calc s h1 h2 m1 m2
-           _ -> Nothing
+readTzOffset str =
+    let
+        getSign '+' = Just 1
+        getSign '-' = Just (-1)
+        getSign _ = Nothing
+        calc s h1 h2 m1 m2 = do
+            sign <- getSign s
+            h <- readMaybe [h1, h2]
+            m <- readMaybe [m1, m2]
+            return $ sign * (60 * h + m)
+    in
+        case str of
+            (s : h1 : h2 : ':' : m1 : m2 : []) -> calc s h1 h2 m1 m2
+            (s : h1 : h2 : m1 : m2 : []) -> calc s h1 h2 m1 m2
+            _ -> Nothing
 
 instance ParseTime ZonedTime where
     substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
     parseTimeSpecifier _ = timeParseTimeSpecifier
-    buildTime l xs = let
-        f (ZonedTime (LocalTime _ tod) z) ('s', x) = do
-            a <- readMaybe x
-            let
-                s = fromInteger a
-                (_, ps) = properFraction (todSec tod) :: (Integer, Pico)
-                s' = s + fromRational (toRational ps)
-            return $ utcToZonedTime z (posixSecondsToUTCTime s')
-        f t _ = Just t
-        in mfoldl f (ZonedTime <$> (buildTime l xs) <*> (buildTime l xs)) xs
+    buildTime l xs =
+        let
+            f (ZonedTime (LocalTime _ tod) z) ('s', x) = do
+                a <- readMaybe x
+                let
+                    s = fromInteger a
+                    (_, ps) = properFraction (todSec tod) :: (Integer, Pico)
+                    s' = s + fromRational (toRational ps)
+                return $ utcToZonedTime z (posixSecondsToUTCTime s')
+            f t _ = Just t
+        in
+            mfoldl f (ZonedTime <$> (buildTime l xs) <*> (buildTime l xs)) xs
 
 instance ParseTime UTCTime where
     substituteTimeSpecifier _ = timeSubstituteTimeSpecifier
@@ -359,6 +600,8 @@
     parseTimeSpecifier _ = timeParseTimeSpecifier
     buildTime l xs = localTimeToUT1 0 <$> buildTime l xs
 
+--- Duration
+
 buildTimeMonths :: [(Char, String)] -> Maybe Integer
 buildTimeMonths xs = do
     tt <-
@@ -383,20 +626,21 @@
 
 buildTimeSeconds :: [(Char, String)] -> Maybe Pico
 buildTimeSeconds xs = do
-    tt <-
-        for xs $ \(c, s) -> let
+    tt <- for xs $ \(c, s) ->
+        let
             readInt :: Integer -> Maybe Pico
             readInt t = do
                 i <- readMaybe s
                 return $ fromInteger $ i * t
-            in case c of
-                   'h' -> readInt 3600
-                   'H' -> readInt 3600
-                   'm' -> readInt 60
-                   'M' -> readInt 60
-                   's' -> readMaybe s
-                   'S' -> readMaybe s
-                   _ -> return 0
+        in
+            case c of
+                'h' -> readInt 3600
+                'H' -> readInt 3600
+                'm' -> readInt 60
+                'M' -> readInt 60
+                's' -> readMaybe s
+                'S' -> readMaybe s
+                _ -> return 0
     return $ sum tt
 
 instance ParseTime NominalDiffTime where
diff --git a/lib/Data/Time/LocalTime.hs b/lib/Data/Time/LocalTime.hs
--- a/lib/Data/Time/LocalTime.hs
+++ b/lib/Data/Time/LocalTime.hs
@@ -1,23 +1,63 @@
-module Data.Time.LocalTime
-    (
+{-# LANGUAGE Safe #-}
+
+module Data.Time.LocalTime (
     -- * Time zones
-      TimeZone(..)
-    , timeZoneOffsetString
-    , timeZoneOffsetString'
-    , minutesToTimeZone
-    , hoursToTimeZone
-    , utc
+    TimeZone (..),
+    timeZoneOffsetString,
+    timeZoneOffsetString',
+    minutesToTimeZone,
+    hoursToTimeZone,
+    utc,
     -- getting the locale time zone
-    , getTimeZone
-    , getCurrentTimeZone
-    , module Data.Time.LocalTime.Internal.TimeOfDay
-    , module Data.Time.LocalTime.Internal.CalendarDiffTime
-    , module Data.Time.LocalTime.Internal.LocalTime
-    , module Data.Time.LocalTime.Internal.ZonedTime
-    ) where
+    getTimeZone,
+    getCurrentTimeZone,
 
+    -- * Time of day
+    TimeOfDay (..),
+    midnight,
+    midday,
+    makeTimeOfDayValid,
+    timeToDaysAndTimeOfDay,
+    daysAndTimeOfDayToTime,
+    utcToLocalTimeOfDay,
+    localToUTCTimeOfDay,
+    timeToTimeOfDay,
+    pastMidnight,
+    timeOfDayToTime,
+    sinceMidnight,
+    diffTimeOfDay,
+    dayFractionToTimeOfDay,
+    timeOfDayToDayFraction,
+
+    -- * Calendar Duration
+    module Data.Time.LocalTime.Internal.CalendarDiffTime,
+
+    -- * Local Time
+    LocalTime (..),
+    addLocalTime,
+    diffLocalTime,
+    -- converting UTC and UT1 times to LocalTime
+    utcToLocalTime,
+    localTimeToUTC,
+    ut1ToLocalTime,
+    localTimeToUT1,
+    -- using CalendarDiffTime
+    addLocalDurationClip,
+    addLocalDurationRollOver,
+    diffLocalDurationClip,
+    diffLocalDurationRollOver,
+
+    -- * Zoned Time
+    ZonedTime (..),
+    utcToZonedTime,
+    zonedTimeToUTC,
+    getZonedTime,
+    utcToLocalZonedTime,
+) where
+
 import Data.Time.Format ()
 import Data.Time.LocalTime.Internal.CalendarDiffTime
+import Data.Time.LocalTime.Internal.Foreign
 import Data.Time.LocalTime.Internal.LocalTime
 import Data.Time.LocalTime.Internal.TimeOfDay
 import Data.Time.LocalTime.Internal.TimeZone hiding (timeZoneOffsetString'')
diff --git a/lib/Data/Time/LocalTime/Internal/CalendarDiffTime.hs b/lib/Data/Time/LocalTime/Internal/CalendarDiffTime.hs
--- a/lib/Data/Time/LocalTime/Internal/CalendarDiffTime.hs
+++ b/lib/Data/Time/LocalTime/Internal/CalendarDiffTime.hs
@@ -1,31 +1,31 @@
-module Data.Time.LocalTime.Internal.CalendarDiffTime
-    (
-        -- * Calendar Duration
-        module Data.Time.LocalTime.Internal.CalendarDiffTime
-    ) where
-#if !MIN_VERSION_base(4,11,0)
-import Data.Semigroup hiding (option)
-#endif
-import Data.Fixed
-import Data.Typeable
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
+module Data.Time.LocalTime.Internal.CalendarDiffTime where
+
+import Control.DeepSeq
 import Data.Data
 import Data.Time.Calendar.CalendarDiffDays
+import Data.Time.Calendar.Gregorian
 import Data.Time.Clock.Internal.NominalDiffTime
+import Data.Time.Clock.Internal.UTCDiff
+import Data.Time.Clock.Internal.UTCTime
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 data CalendarDiffTime = CalendarDiffTime
     { ctMonths :: Integer
     , ctTime :: NominalDiffTime
-    } deriving (Eq,
-    Data
-#if __GLASGOW_HASKELL__ >= 802
-    -- ^ @since 1.9.2
-#endif
-    ,Typeable
-#if __GLASGOW_HASKELL__ >= 802
-    -- ^ @since 1.9.2
-#endif
-    )
+    }
+    deriving (Eq, Typeable, Data, Generic, TH.Lift)
 
+instance NFData CalendarDiffTime where
+    rnf (CalendarDiffTime m t) = rnf m `seq` rnf t `seq` ()
+
 -- | Additive
 instance Semigroup CalendarDiffTime where
     CalendarDiffTime m1 d1 <> CalendarDiffTime m2 d2 = CalendarDiffTime (m1 + m2) (d1 + d2)
@@ -35,9 +35,6 @@
     mempty = CalendarDiffTime 0 0
     mappend = (<>)
 
-instance Show CalendarDiffTime where
-    show (CalendarDiffTime m t) = "P" ++ show m ++ "MT" ++ showFixed True (realToFrac t :: Pico) ++ "S"
-
 calendarTimeDays :: CalendarDiffDays -> CalendarDiffTime
 calendarTimeDays (CalendarDiffDays m d) = CalendarDiffTime m $ fromInteger d * nominalDay
 
@@ -47,3 +44,25 @@
 -- | Scale by a factor. Note that @scaleCalendarDiffTime (-1)@ will not perfectly invert a duration, due to variable month lengths.
 scaleCalendarDiffTime :: Integer -> CalendarDiffTime -> CalendarDiffTime
 scaleCalendarDiffTime k (CalendarDiffTime m d) = CalendarDiffTime (k * m) (fromInteger k * d)
+
+addUTCDurationClip :: CalendarDiffTime -> UTCTime -> UTCTime
+addUTCDurationClip (CalendarDiffTime m d) (UTCTime day t) =
+    addUTCTime d $ UTCTime (addGregorianMonthsClip m day) t
+
+addUTCDurationRollOver :: CalendarDiffTime -> UTCTime -> UTCTime
+addUTCDurationRollOver (CalendarDiffTime m d) (UTCTime day t) =
+    addUTCTime d $ UTCTime (addGregorianMonthsRollOver m day) t
+
+diffUTCDurationClip :: UTCTime -> UTCTime -> CalendarDiffTime
+diffUTCDurationClip (UTCTime day1 t1) (UTCTime day2 t2) =
+    let
+        CalendarDiffTime m t = calendarTimeDays $ diffGregorianDurationClip day1 day2
+    in
+        CalendarDiffTime m $ t + realToFrac (t1 - t2)
+
+diffUTCDurationRollOver :: UTCTime -> UTCTime -> CalendarDiffTime
+diffUTCDurationRollOver (UTCTime day1 t1) (UTCTime day2 t2) =
+    let
+        CalendarDiffTime m t = calendarTimeDays $ diffGregorianDurationRollOver day1 day2
+    in
+        CalendarDiffTime m $ t + realToFrac (t1 - t2)
diff --git a/lib/Data/Time/LocalTime/Internal/Foreign.hs b/lib/Data/Time/LocalTime/Internal/Foreign.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Time/LocalTime/Internal/Foreign.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE Safe #-}
+
+module Data.Time.LocalTime.Internal.Foreign (
+    getTimeZone,
+    getCurrentTimeZone,
+) where
+
+import Data.Time.Clock.Internal.UTCTime
+import Data.Time.Clock.POSIX
+import Data.Time.Clock.System
+import Data.Time.LocalTime.Internal.TimeZone
+import Foreign
+import Foreign.C
+#if defined(javascript_HOST_ARCH)
+import Data.Time.Calendar.Gregorian
+import Data.Time.Clock.Internal.NominalDiffTime
+import Data.Time.LocalTime.Internal.LocalTime
+import Data.Time.LocalTime.Internal.TimeOfDay
+#endif
+
+#if defined(javascript_HOST_ARCH)
+
+foreign import javascript "((dy,dm,dd,th,tm,ts) => { return new Date(dy,dm,dd,th,tm,ts).getTimezoneOffset(); })"
+  js_get_timezone_minutes :: Int -> Int -> Int -> Int -> Int -> Int -> IO Int
+
+get_timezone_minutes :: UTCTime -> IO Int
+get_timezone_minutes ut = let
+    lt :: LocalTime
+    lt = utcToLocalTime utc ut
+    in case lt of
+        LocalTime (YearMonthDay dy dm dd) (TimeOfDay th tm ts) ->
+            js_get_timezone_minutes (fromInteger dy) (pred dm) dd th tm (floor ts)
+
+getTimeZoneCTime :: CTime -> IO TimeZone
+getTimeZoneCTime ct = do
+    let
+        ut :: UTCTime
+        ut = posixSecondsToUTCTime $ secondsToNominalDiffTime $ fromIntegral $ fromCTime ct
+    mins <- get_timezone_minutes ut
+    return $ TimeZone mins False ""
+
+fromCTime :: CTime -> Int64
+fromCTime (CTime tt) = fromIntegral tt
+
+#else
+{-# CFILES cbits/HsTime.c #-}
+foreign import ccall unsafe "HsTime.h get_current_timezone_seconds"
+    get_current_timezone_seconds ::
+        CTime -> Ptr CInt -> Ptr CString -> IO CLong
+
+getTimeZoneCTime :: CTime -> IO TimeZone
+getTimeZoneCTime ctime =
+    with 0 $ \pdst ->
+        with nullPtr $ \pcname -> do
+            secs <- get_current_timezone_seconds ctime pdst pcname
+            case secs of
+                0x80000000 -> fail "localtime_r failed"
+                _ -> do
+                    dst <- peek pdst
+                    cname <- peek pcname
+                    name <- peekCString cname
+                    return (TimeZone (div (fromIntegral secs) 60) (dst == 1) name)
+#endif
+
+-- there's no instance Bounded CTime, so this is the easiest way to check for overflow
+toCTime :: Int64 -> IO CTime
+toCTime t =
+    let
+        tt = fromIntegral t
+        t' = fromIntegral tt
+    in
+        if t' == t
+            then return $ CTime tt
+            else fail "Data.Time.LocalTime.Internal.TimeZone.toCTime: Overflow"
+
+-- | Get the configured time-zone for a given time (varying as per summertime adjustments).
+getTimeZoneSystem :: SystemTime -> IO TimeZone
+getTimeZoneSystem t = do
+    ctime <- toCTime $ systemSeconds t
+    getTimeZoneCTime ctime
+
+-- | Get the configured time-zone for a given time (varying as per summertime adjustments).
+--
+-- On Unix systems the output of this function depends on:
+--
+-- 1. The value of @TZ@ environment variable (if set)
+--
+-- 2. The system time zone (usually configured by @\/etc\/localtime@ symlink)
+--
+-- For details see tzset(3) and localtime(3).
+--
+-- Example:
+--
+-- @
+-- > let t = `UTCTime` (`Data.Time.Calendar.fromGregorian` 2021 7 1) 0
+-- > `getTimeZone` t
+-- CEST
+-- > `System.Environment.setEnv` \"TZ\" \"America/New_York\" >> `getTimeZone` t
+-- EDT
+-- > `System.Environment.setEnv` \"TZ\" \"Europe/Berlin\" >> `getTimeZone` t
+-- CEST
+-- @
+--
+-- On Windows systems the output of this function depends on:
+--
+-- 1. The value of @TZ@ environment variable (if set).
+-- See [here](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/tzset) for how Windows interprets this variable.
+--
+-- 2. The system time zone, configured in Settings
+getTimeZone :: UTCTime -> IO TimeZone
+getTimeZone t = do
+    ctime <- toCTime $ floor $ utcTimeToPOSIXSeconds t
+    getTimeZoneCTime ctime
+
+-- | Get the configured time-zone for the current time.
+getCurrentTimeZone :: IO TimeZone
+getCurrentTimeZone = getSystemTime >>= getTimeZoneSystem
diff --git a/lib/Data/Time/LocalTime/Internal/LocalTime.hs b/lib/Data/Time/LocalTime/Internal/LocalTime.hs
--- a/lib/Data/Time/LocalTime/Internal/LocalTime.hs
+++ b/lib/Data/Time/LocalTime/Internal/LocalTime.hs
@@ -1,17 +1,9 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.LocalTime.Internal.LocalTime
-    (
-    -- * Local Time
-      LocalTime(..)
-    , addLocalTime
-    , diffLocalTime
-    -- converting UTC and UT1 times to LocalTime
-    , utcToLocalTime
-    , localTimeToUTC
-    , ut1ToLocalTime
-    , localTimeToUT1
-    ) where
+module Data.Time.LocalTime.Internal.LocalTime where
 
 import Control.DeepSeq
 import Data.Data
@@ -21,8 +13,15 @@
 import Data.Time.Clock.Internal.UTCDiff
 import Data.Time.Clock.Internal.UTCTime
 import Data.Time.Clock.Internal.UniversalTime
+import Data.Time.LocalTime.Internal.CalendarDiffTime
 import Data.Time.LocalTime.Internal.TimeOfDay
 import Data.Time.LocalTime.Internal.TimeZone
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | A simple day and time aggregate, where the day is of the specified parameter,
 -- and the time is a TimeOfDay.
@@ -31,7 +30,8 @@
 data LocalTime = LocalTime
     { localDay :: Day
     , localTimeOfDay :: TimeOfDay
-    } deriving (Eq, Ord, Data, Typeable)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
 instance NFData LocalTime where
     rnf (LocalTime d t) = rnf d `seq` rnf t `seq` ()
@@ -76,3 +76,25 @@
 -- orphan instance
 instance Show UniversalTime where
     show t = show (ut1ToLocalTime 0 t)
+
+addLocalDurationClip :: CalendarDiffTime -> LocalTime -> LocalTime
+addLocalDurationClip (CalendarDiffTime m d) (LocalTime day t) =
+    addLocalTime d $ LocalTime (addGregorianMonthsClip m day) t
+
+addLocalDurationRollOver :: CalendarDiffTime -> LocalTime -> LocalTime
+addLocalDurationRollOver (CalendarDiffTime m d) (LocalTime day t) =
+    addLocalTime d $ LocalTime (addGregorianMonthsRollOver m day) t
+
+diffLocalDurationClip :: LocalTime -> LocalTime -> CalendarDiffTime
+diffLocalDurationClip (LocalTime day1 t1) (LocalTime day2 t2) =
+    let
+        CalendarDiffTime m t = calendarTimeDays $ diffGregorianDurationClip day1 day2
+    in
+        CalendarDiffTime m $ t + diffTimeOfDay t1 t2
+
+diffLocalDurationRollOver :: LocalTime -> LocalTime -> CalendarDiffTime
+diffLocalDurationRollOver (LocalTime day1 t1) (LocalTime day2 t2) =
+    let
+        CalendarDiffTime m t = calendarTimeDays $ diffGregorianDurationRollOver day1 day2
+    in
+        CalendarDiffTime m $ t + diffTimeOfDay t1 t2
diff --git a/lib/Data/Time/LocalTime/Internal/TimeOfDay.hs b/lib/Data/Time/LocalTime/Internal/TimeOfDay.hs
--- a/lib/Data/Time/LocalTime/Internal/TimeOfDay.hs
+++ b/lib/Data/Time/LocalTime/Internal/TimeOfDay.hs
@@ -1,23 +1,7 @@
-{-# OPTIONS -fno-warn-unused-imports #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
-module Data.Time.LocalTime.Internal.TimeOfDay
-    (
-    -- * Time of day
-      TimeOfDay(..)
-    , midnight
-    , midday
-    , makeTimeOfDayValid
-    , timeToDaysAndTimeOfDay
-    , daysAndTimeOfDayToTime
-    , utcToLocalTimeOfDay
-    , localToUTCTimeOfDay
-    , timeToTimeOfDay
-    , pastMidnight
-    , timeOfDayToTime
-    , sinceMidnight
-    , dayFractionToTimeOfDay
-    , timeOfDayToDayFraction
-    ) where
+module Data.Time.LocalTime.Internal.TimeOfDay where
 
 import Control.DeepSeq
 import Data.Data
@@ -26,21 +10,30 @@
 import Data.Time.Clock.Internal.DiffTime
 import Data.Time.Clock.Internal.NominalDiffTime
 import Data.Time.LocalTime.Internal.TimeZone
-import Data.Typeable
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | Time of day as represented in hour, minute and second (with picoseconds), typically used to express local time of day.
+--
+-- @TimeOfDay 24 0 0@ is considered invalid for the purposes of 'makeTimeOfDayValid', as well as reading and parsing,
+-- but valid for ISO 8601 parsing in "Data.Time.Format.ISO8601".
 data TimeOfDay = TimeOfDay
     { todHour :: Int
     -- ^ range 0 - 23
     , todMin :: Int
     -- ^ range 0 - 59
     , todSec :: Pico
-    -- ^ Note that 0 <= 'todSec' < 61, accomodating leap seconds.
+    -- ^ Note that 0 <= 'todSec' < 61, accommodating leap seconds.
     -- Any local minute may have a leap second, since leap seconds happen in all zones simultaneously
-    } deriving (Eq, Ord, Data, Typeable)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
 instance NFData TimeOfDay where
-    rnf (TimeOfDay h m s) = rnf h `seq` rnf m `seq` s `seq` () -- FIXME: Data.Fixed had no NFData instances yet at time of writing
+    rnf (TimeOfDay h m s) = rnf h `seq` rnf m `seq` rnf s `seq` ()
 
 -- | Hour zero
 midnight :: TimeOfDay
@@ -63,12 +56,14 @@
 -- | Convert a period of time into a count of days and a time of day since midnight.
 -- The time of day will never have a leap second.
 timeToDaysAndTimeOfDay :: NominalDiffTime -> (Integer, TimeOfDay)
-timeToDaysAndTimeOfDay dt = let
-    s = realToFrac dt
-    (m, ms) = divMod' s 60
-    (h, hm) = divMod' m 60
-    (d, dh) = divMod' h 24
-    in (d, TimeOfDay dh hm ms)
+timeToDaysAndTimeOfDay dt =
+    let
+        s = realToFrac dt
+        (m, ms) = divMod' s 60
+        (h, hm) = divMod' m 60
+        (d, dh) = divMod' h 24
+    in
+        (d, TimeOfDay dh hm ms)
 
 -- | Convert a count of days and a time of day since midnight into a period of time.
 daysAndTimeOfDayToTime :: Integer -> TimeOfDay -> NominalDiffTime
@@ -121,3 +116,6 @@
 -- | Get the fraction of a day since midnight given a time of day.
 timeOfDayToDayFraction :: TimeOfDay -> Rational
 timeOfDayToDayFraction tod = realToFrac (timeOfDayToTime tod) / realToFrac posixDayLength
+
+diffTimeOfDay :: TimeOfDay -> TimeOfDay -> NominalDiffTime
+diffTimeOfDay t1 t2 = realToFrac $ daysAndTimeOfDayToTime 0 t1 - daysAndTimeOfDayToTime 0 t2
diff --git a/lib/Data/Time/LocalTime/Internal/TimeZone.hs b/lib/Data/Time/LocalTime/Internal/TimeZone.hs
--- a/lib/Data/Time/LocalTime/Internal/TimeZone.hs
+++ b/lib/Data/Time/LocalTime/Internal/TimeZone.hs
@@ -1,30 +1,26 @@
-{-# OPTIONS -fno-warn-unused-imports #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 
-module Data.Time.LocalTime.Internal.TimeZone
-    (
+module Data.Time.LocalTime.Internal.TimeZone (
     -- * Time zones
-      TimeZone(..)
-    , timeZoneOffsetString
-    , timeZoneOffsetString'
-    , timeZoneOffsetString''
-    , minutesToTimeZone
-    , hoursToTimeZone
-    , utc
-    -- getting the locale time zone
-    , getTimeZone
-    , getCurrentTimeZone
-    ) where
+    TimeZone (..),
+    timeZoneOffsetString,
+    timeZoneOffsetString',
+    timeZoneOffsetString'',
+    minutesToTimeZone,
+    hoursToTimeZone,
+    utc,
+) where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Time.Calendar.Private
-import Data.Time.Clock.Internal.UTCTime
-import Data.Time.Clock.POSIX
-import Data.Time.Clock.System
-import Data.Typeable
-import Foreign
-import Foreign.C
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | A TimeZone is a whole number of minutes offset from UTC, together with a name and a \"just for summer\" flag.
 data TimeZone = TimeZone
@@ -34,7 +30,8 @@
     -- ^ Is this time zone just persisting for the summer?
     , timeZoneName :: String
     -- ^ The name of the zone, typically a three- or four-letter acronym.
-    } deriving (Eq, Ord, Data, Typeable)
+    }
+    deriving (Eq, Ord, Typeable, Data, Generic, TH.Lift)
 
 instance NFData TimeZone where
     rnf (TimeZone m so n) = rnf m `seq` rnf so `seq` rnf n `seq` ()
@@ -49,12 +46,13 @@
 
 showT :: Bool -> PadOption -> Int -> String
 showT False opt t = showPaddedNum opt ((div t 60) * 100 + (mod t 60))
-showT True opt t = let
-    opt' =
-        case opt of
+showT True opt t =
+    let
+        opt' = case opt of
             NoPad -> NoPad
             Pad i c -> Pad (max 0 $ i - 3) c
-    in showPaddedNum opt' (div t 60) ++ ":" ++ show2 (mod t 60)
+    in
+        showPaddedNum opt' (div t 60) ++ ":" ++ show2 (mod t 60)
 
 timeZoneOffsetString'' :: Bool -> PadOption -> TimeZone -> String
 timeZoneOffsetString'' colon opt (TimeZone t _ _)
@@ -78,49 +76,3 @@
 -- | The UTC time zone.
 utc :: TimeZone
 utc = TimeZone 0 False "UTC"
-
-{-# CFILES cbits/HsTime.c #-}
-foreign import ccall unsafe "HsTime.h get_current_timezone_seconds" get_current_timezone_seconds
-    :: CTime -> Ptr CInt -> Ptr CString -> IO CLong
-
-getTimeZoneCTime :: CTime -> IO TimeZone
-getTimeZoneCTime ctime =
-    with
-        0
-        (\pdst ->
-             with
-                 nullPtr
-                 (\pcname -> do
-                      secs <- get_current_timezone_seconds ctime pdst pcname
-                      case secs of
-                          0x80000000 -> fail "localtime_r failed"
-                          _ -> do
-                              dst <- peek pdst
-                              cname <- peek pcname
-                              name <- peekCString cname
-                              return (TimeZone (div (fromIntegral secs) 60) (dst == 1) name)))
-
-toCTime :: Int64 -> IO CTime
-toCTime t = let
-    tt = fromIntegral t
-    t' = fromIntegral tt
-    -- there's no instance Bounded CTime, so this is the easiest way to check for overflow
-    in if t' == t
-           then return $ CTime tt
-           else fail "Data.Time.LocalTime.Internal.TimeZone.toCTime: Overflow"
-
--- | Get the local time-zone for a given time (varying as per summertime adjustments).
-getTimeZoneSystem :: SystemTime -> IO TimeZone
-getTimeZoneSystem t = do
-    ctime <- toCTime $ systemSeconds t
-    getTimeZoneCTime ctime
-
--- | Get the local time-zone for a given time (varying as per summertime adjustments).
-getTimeZone :: UTCTime -> IO TimeZone
-getTimeZone t = do
-    ctime <- toCTime $ floor $ utcTimeToPOSIXSeconds t
-    getTimeZoneCTime ctime
-
--- | Get the current time-zone.
-getCurrentTimeZone :: IO TimeZone
-getCurrentTimeZone = getSystemTime >>= getTimeZoneSystem
diff --git a/lib/Data/Time/LocalTime/Internal/ZonedTime.hs b/lib/Data/Time/LocalTime/Internal/ZonedTime.hs
--- a/lib/Data/Time/LocalTime/Internal/ZonedTime.hs
+++ b/lib/Data/Time/LocalTime/Internal/ZonedTime.hs
@@ -1,19 +1,23 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
+
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Data.Time.LocalTime.Internal.ZonedTime
-    ( ZonedTime(..)
-    , utcToZonedTime
-    , zonedTimeToUTC
-    , getZonedTime
-    , utcToLocalZonedTime
-    ) where
+module Data.Time.LocalTime.Internal.ZonedTime where
 
 import Control.DeepSeq
 import Data.Data
 import Data.Time.Clock.Internal.UTCTime
 import Data.Time.Clock.POSIX
+import Data.Time.LocalTime.Internal.Foreign
 import Data.Time.LocalTime.Internal.LocalTime
 import Data.Time.LocalTime.Internal.TimeZone
+import GHC.Generics
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
 
 -- | A local time together with a time zone.
 --
@@ -23,7 +27,8 @@
 data ZonedTime = ZonedTime
     { zonedTimeToLocalTime :: LocalTime
     , zonedTimeZone :: TimeZone
-    } deriving (Data, Typeable)
+    }
+    deriving (Typeable, Data, Generic, TH.Lift)
 
 instance NFData ZonedTime where
     rnf (ZonedTime lt z) = rnf lt `seq` rnf z `seq` ()
@@ -34,6 +39,7 @@
 zonedTimeToUTC :: ZonedTime -> UTCTime
 zonedTimeToUTC (ZonedTime t zone) = localTimeToUTC zone t
 
+-- | For the time zone, this only shows the name, or offset if the name is empty.
 instance Show ZonedTime where
     show (ZonedTime t zone) = show t ++ " " ++ show zone
 
@@ -47,7 +53,6 @@
     zone <- getTimeZone t
     return (utcToZonedTime zone t)
 
--- |
 utcToLocalZonedTime :: UTCTime -> IO ZonedTime
 utcToLocalZonedTime t = do
     zone <- getTimeZone t
diff --git a/lib/cbits/HsTime.c b/lib/cbits/HsTime.c
--- a/lib/cbits/HsTime.c
+++ b/lib/cbits/HsTime.c
@@ -5,12 +5,12 @@
 {
 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
     // When compiling with MinGW (which does not provide a full POSIX
-    // layer as opposed to CygWin) it's better to use the CRT's
+    // layer as opposed to Cygwin) it's better to use the CRT's
     // underscore-prefixed `_tzset()` variant to avoid linker issues
     // as Microsoft considers the POSIX named `tzset()` function
     // deprecated (see http://msdn.microsoft.com/en-us/library/ms235384.aspx)
     _tzset();
-#else
+#elif defined(HAVE_TZSET)
     tzset();
 #endif
 
@@ -35,7 +35,7 @@
         *pname = dst ? _tzname[1] : _tzname[0];
         return - (dst ? _timezone - 3600 : _timezone);
 #else
-# if HAVE_TZNAME
+# if HAVE_TZNAME || defined(__MHS__)
         *pname = *tzname;
 # else
 #  error "Don't know how to get timezone name on your OS"
diff --git a/lib/include/HsTime.h b/lib/include/HsTime.h
--- a/lib/include/HsTime.h
+++ b/lib/include/HsTime.h
@@ -1,7 +1,7 @@
 #ifndef __HSTIME_H__
 #define __HSTIME_H__
 
-#if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32) || defined(__MHS__)
 #define HAVE_TIME_H 1
 #else
 
@@ -17,6 +17,8 @@
 #if HAVE_TIME_H
 #include <time.h>
 #endif
+
+#define HS_CLOCK_REALTIME (uintptr_t)(CLOCK_REALTIME)
 
 long int get_current_timezone_seconds (time_t,int* pdst,char const* * pname);
 
diff --git a/lib/include/HsTimeConfig.h b/lib/include/HsTimeConfig.h
deleted file mode 100644
--- a/lib/include/HsTimeConfig.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* lib/include/HsTimeConfig.h.  Generated from HsTimeConfig.h.in by configure.  */
-/* lib/include/HsTimeConfig.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#define HAVE_CLOCK_GETTIME 1
-
-/* Define to 1 if you have the declaration of `altzone', and to 0 if you
-   don't. */
-#define HAVE_DECL_ALTZONE 0
-
-/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
-   */
-/* #undef HAVE_DECL_TZNAME */
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if `tm_zone' is a member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_ZONE 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
-   `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#define HAVE_TM_ZONE 1
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
-   `tzname'. */
-/* #undef HAVE_TZNAME */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "ashley@semantic.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "Haskell time package"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "Haskell time package 1.10"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "time"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.10"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
diff --git a/lib/include/HsTimeConfig.h.in b/lib/include/HsTimeConfig.h.in
--- a/lib/include/HsTimeConfig.h.in
+++ b/lib/include/HsTimeConfig.h.in
@@ -20,12 +20,15 @@
 /* Define to 1 if you have the `localtime_r' function. */
 #undef HAVE_LOCALTIME_R
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+/* Define to 1 if you have the <minix/config.h> header file. */
+#undef HAVE_MINIX_CONFIG_H
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -58,9 +61,15 @@
    `tzname'. */
 #undef HAVE_TZNAME
 
+/* Define to 1 if you have the `tzset' function. */
+#undef HAVE_TZSET
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
@@ -79,12 +88,11 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
@@ -92,30 +100,86 @@
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
 #endif
+/* Enable general extensions on macOS.  */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE
 # undef _GNU_SOURCE
 #endif
-/* Enable threading extensions on Solaris.  */
+/* Enable X/Open compliant socket functions that do not require linking
+   with -lxnet on HP-UX 11.11.  */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Identify the host operating system as Minix.
+   This macro does not affect the system headers' behavior.
+   A future release of Autoconf may stop defining this macro.  */
+#ifndef _MINIX
+# undef _MINIX
+#endif
+/* Enable general extensions on NetBSD.
+   Enable NetBSD compatibility extensions on Minix.  */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+   Oddly enough, this does nothing on OpenBSD.  */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_SOURCE
+# undef _POSIX_SOURCE
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_1_SOURCE
+# undef _POSIX_1_SOURCE
+#endif
+/* Enable POSIX-compatible threading on Solaris.  */
 #ifndef _POSIX_PTHREAD_SEMANTICS
 # undef _POSIX_PTHREAD_SEMANTICS
 #endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009.  */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
 /* Enable extensions on HP NonStop.  */
 #ifndef _TANDEM_SOURCE
 # undef _TANDEM_SOURCE
 #endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
+/* Enable X/Open extensions.  Define to 500 only if necessary
+   to make mbstate_t available.  */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
 #endif
 
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
diff --git a/test/ForeignCalls.hs b/test/ForeignCalls.hs
new file mode 100644
--- /dev/null
+++ b/test/ForeignCalls.hs
@@ -0,0 +1,50 @@
+module Main (main) where
+
+import Control.Exception
+import Control.Monad
+import Data.Foldable
+import Data.Monoid
+import Data.Time
+import Data.Time.Clock.POSIX
+import Data.Time.Clock.System
+import Data.Time.Clock.TAI
+import Data.Traversable
+import System.Exit
+import System.IO
+
+data Test = MkTest String (IO ())
+
+tests :: [Test]
+tests =
+    [ MkTest "getCurrentTime" $ void $ getCurrentTime
+    , MkTest "getZonedTime" $ void $ getZonedTime
+    , MkTest "getCurrentTimeZone" $ void $ getCurrentTimeZone
+    , MkTest "getTimeZone" $ void $ getCurrentTime >>= getTimeZone
+    , MkTest "getPOSIXTime" $ void $ getPOSIXTime
+    , MkTest "getSystemTime" $ void $ getSystemTime
+    , MkTest "getTime_resolution" $ void $ evaluate getTime_resolution
+    , MkTest "taiClock time" $ for_ taiClock $ \(_, getTime) -> void $ getTime
+    , MkTest "taiClock resolution" $ for_ taiClock $ \(res, _) -> void $ evaluate res
+    ]
+
+runTest :: Test -> IO Bool
+runTest (MkTest name action) = do
+    hPutStr stderr $ name <> ": "
+    result <- try action
+    case result of
+        Left err -> do
+            hPutStrLn stderr $ "FAILED: " <> show (err :: SomeException)
+            return False
+        Right () -> do
+            hPutStrLn stderr "PASSED"
+            return True
+
+main :: IO ()
+main = do
+    results <- for tests $ \test -> do
+        passed <- runTest test
+        return (Sum $ if passed then 1 else 0 :: Int, Sum 1)
+    let
+        (Sum i, Sum n) = mconcat results
+    hPutStrLn stderr $ show i <> " out of " <> show n <> " tests passed"
+    exitWith $ if i == n then ExitSuccess else ExitFailure 1
diff --git a/test/ShowDefaultTZAbbreviations.hs b/test/ShowDefaultTZAbbreviations.hs
--- a/test/ShowDefaultTZAbbreviations.hs
+++ b/test/ShowDefaultTZAbbreviations.hs
@@ -4,10 +4,11 @@
 
 showTZ :: TimeZone -> String
 showTZ tz =
-    (formatTime defaultTimeLocale "%Z %z" tz) ++
-    (if timeZoneSummerOnly tz
-         then " DST"
-         else "")
+    (formatTime defaultTimeLocale "%Z %z" tz)
+        ++ ( if timeZoneSummerOnly tz
+                then " DST"
+                else ""
+           )
 
 main :: IO ()
 main = mapM_ (\tz -> putStrLn (showTZ tz)) (knownTimeZones defaultTimeLocale)
diff --git a/test/ShowTime.hs b/test/ShowTime.hs
new file mode 100644
--- /dev/null
+++ b/test/ShowTime.hs
@@ -0,0 +1,8 @@
+module Main (main) where
+
+import Data.Time
+
+main :: IO ()
+main = do
+    now <- getZonedTime
+    putStrLn $ show now
diff --git a/test/main/Main.hs b/test/main/Main.hs
--- a/test/main/Main.hs
+++ b/test/main/Main.hs
@@ -1,17 +1,21 @@
 module Main where
 
-import Test.Types()
 import Test.Calendar.AddDays
+import Test.Calendar.CalendarProps
 import Test.Calendar.Calendars
 import Test.Calendar.ClipDates
 import Test.Calendar.ConvertBack
+import Test.Calendar.DayPeriod
 import Test.Calendar.Duration
 import Test.Calendar.Easter
 import Test.Calendar.LongWeekYears
 import Test.Calendar.MonthDay
+import Test.Calendar.MonthOfYear
 import Test.Calendar.Valid
 import Test.Calendar.Week
+import Test.Calendar.Year
 import Test.Clock.Conversion
+import Test.Clock.Pattern
 import Test.Clock.Resolution
 import Test.Clock.TAI
 import Test.Format.Compile ()
@@ -22,25 +26,30 @@
 import Test.LocalTime.Time
 import Test.LocalTime.TimeOfDay
 import Test.Tasty
+import Test.Types ()
 
 tests :: TestTree
 tests =
     testGroup
         "Time"
         [ testGroup
-              "Calendar"
-              [ addDaysTest
-              , testCalendars
-              , clipDates
-              , convertBack
-              , longWeekYears
-              , testMonthDay
-              , testEaster
-              , testValid
-              , testWeek
-              , testDuration
-              ]
-        , testGroup "Clock" [testClockConversion, testResolutions, testTAI]
+            "Calendar"
+            [ addDaysTest
+            , testCalendarProps
+            , testCalendars
+            , clipDates
+            , convertBack
+            , longWeekYears
+            , testDayPeriod
+            , testMonthDay
+            , testMonthOfYear
+            , testEaster
+            , testValid
+            , testWeek
+            , testYear
+            , testDuration
+            ]
+        , testGroup "Clock" [testClockPatterns, testClockConversion, testResolutions, testTAI]
         , testGroup "Format" [testFormat, testParseTime, testISO8601]
         , testGroup "LocalTime" [testTime, testTimeOfDay, testCalendarDiffTime]
         ]
diff --git a/test/main/Test/AddDiff.hs b/test/main/Test/AddDiff.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/AddDiff.hs
@@ -0,0 +1,20 @@
+module Test.AddDiff (
+    AddDiff (..),
+    testAddDiff,
+) where
+
+import Test.Arbitrary
+import Test.Tasty
+import Test.Tasty.QuickCheck hiding (reason)
+
+data AddDiff duration time = MkAddDiff
+    { adName :: String
+    , adAdd :: duration -> time -> time
+    , adDifference :: time -> time -> duration
+    }
+
+testAddDiff :: (Arbitrary (NoLeapSeconds time), Eq time, Show time) => AddDiff duration time -> TestTree
+testAddDiff MkAddDiff{..} =
+    testProperty adName $
+        \(MkNoLeapSeconds time1) (MkNoLeapSeconds time2) ->
+            adAdd (adDifference time2 time1) time1 == time2
diff --git a/test/main/Test/Arbitrary.hs b/test/main/Test/Arbitrary.hs
--- a/test/main/Test/Arbitrary.hs
+++ b/test/main/Test/Arbitrary.hs
@@ -1,43 +1,114 @@
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Test.Arbitrary where
+module Test.Arbitrary (
+    supportedDayRange,
+    NoLeapSeconds (..),
+) where
 
 import Control.Monad
 import Data.Fixed
 import Data.Ratio
 import Data.Time
+import Data.Time.Calendar.Month
+import Data.Time.Calendar.Quarter
+import Data.Time.Calendar.WeekDate
 import Data.Time.Clock.POSIX
+import System.Random
 import Test.Tasty.QuickCheck hiding (reason)
 
 instance Arbitrary DayOfWeek where
     arbitrary = fmap toEnum $ choose (1, 7)
 
-instance Arbitrary Day where
-    arbitrary = liftM ModifiedJulianDay $ choose (-313698, 2973483) -- 1000-01-1 to 9999-12-31
-    shrink day = let
-        (y, m, d) = toGregorian day
-        dayShrink =
-            if d > 1
-                then [fromGregorian y m (d - 1)]
-                else []
-        monthShrink =
-            if m > 1
-                then [fromGregorian y (m - 1) d]
-                else []
+instance Arbitrary FirstWeekType where
+    arbitrary = do
+        b <- arbitrary
+        return $ if b then FirstWholeWeek else FirstMostWeek
+
+deriving instance Show FirstWeekType
+
+deriving instance Random Month
+
+supportedMonthRange :: (Month, Month)
+supportedMonthRange = (YearMonth (-9899) 1, YearMonth 9999 12)
+
+shrinkYear :: Integer -> [Integer]
+shrinkYear y =
+    let
         yearShrink =
             if y > 2000
-                then [fromGregorian (y - 1) m d]
-                else if y < 2000
-                         then [fromGregorian (y + 1) m d]
-                         else []
-        in dayShrink ++ monthShrink ++ yearShrink
+                then [pred y]
+                else
+                    if y < 2000
+                        then [succ y]
+                        else []
+        year10Shrink =
+            if y > 2010
+                then fmap (\i -> y - i) [1 .. 10]
+                else
+                    if y < 1990
+                        then fmap (\i -> y + i) [1 .. 10]
+                        else []
+        year100Shrink =
+            if y > 2100
+                then [y - 100]
+                else
+                    if y < 1900
+                        then [y + 100]
+                        else []
+    in
+        year100Shrink <> year10Shrink <> yearShrink
 
+instance Arbitrary Month where
+    arbitrary = choose supportedMonthRange
+
+instance Arbitrary Quarter where
+    arbitrary = fmap monthQuarter arbitrary
+    shrink (YearQuarter y qoy) =
+        fmap (\y' -> YearQuarter y' qoy) (shrinkYear y)
+            <> fmap (YearQuarter y) (shrink qoy)
+
+instance Arbitrary QuarterOfYear where
+    arbitrary = liftM toEnum $ choose (1, 4)
+    shrink Q1 = []
+    shrink _ = [Q1]
+
+deriving instance Random Day
+
+supportedDayRange :: (Day, Day)
+supportedDayRange = (fromGregorian (-9899) 1 1, fromGregorian 9999 12 31)
+
+instance Arbitrary Day where
+    arbitrary = choose supportedDayRange
+    shrink day =
+        let
+            (y, m, d) = toGregorian day
+            dayShrink =
+                if d > 1
+                    then [fromGregorian y m (d - 1)]
+                    else []
+            monthShrink =
+                if m > 1
+                    then [fromGregorian y (m - 1) d]
+                    else []
+        in
+            dayShrink <> monthShrink <> fmap (\y' -> fromGregorian y' m d) (shrinkYear y)
+
 instance CoArbitrary Day where
     coarbitrary (ModifiedJulianDay d) = coarbitrary d
 
 instance Arbitrary CalendarDiffDays where
     arbitrary = liftM2 CalendarDiffDays arbitrary arbitrary
 
+newtype NoLeapSeconds a = MkNoLeapSeconds {unNoLeapSeconds :: a}
+    deriving newtype (Eq, Ord, Show)
+
+arbitraryNoLeapSeconds :: Arbitrary (NoLeapSeconds a) => Gen a
+arbitraryNoLeapSeconds = fmap unNoLeapSeconds arbitrary
+
+instance {-# OVERLAPPABLE #-} Arbitrary t => Arbitrary (NoLeapSeconds t) where
+    arbitrary = fmap MkNoLeapSeconds arbitrary
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
+
 instance Arbitrary DiffTime where
     arbitrary = oneof [intSecs, fracSecs] -- up to 1 leap second
       where
@@ -51,6 +122,17 @@
 instance CoArbitrary DiffTime where
     coarbitrary t = coarbitrary (fromEnum t)
 
+instance Arbitrary (NoLeapSeconds DiffTime) where
+    arbitrary = fmap MkNoLeapSeconds $ oneof [intSecs, fracSecs] -- no leap second
+      where
+        intSecs = liftM secondsToDiffTime' $ choose (0, 86399)
+        fracSecs = liftM picosecondsToDiffTime' $ choose (0, 86399 * 10 ^ (12 :: Int))
+        secondsToDiffTime' :: Integer -> DiffTime
+        secondsToDiffTime' = fromInteger
+        picosecondsToDiffTime' :: Integer -> DiffTime
+        picosecondsToDiffTime' x = fromRational (x % 10 ^ (12 :: Int))
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
+
 instance Arbitrary NominalDiffTime where
     arbitrary = oneof [intSecs, fracSecs]
       where
@@ -71,29 +153,37 @@
 
 reduceDigits :: Int -> Pico -> Maybe Pico
 reduceDigits (-1) _ = Nothing
-reduceDigits n x = let
-    d :: Pico
-    d = 10 ^^ (negate n)
-    r = mod' x d
-    in case r of
-           0 -> reduceDigits (n - 1) x
-           _ -> Just $ x - r
+reduceDigits n x =
+    let
+        d :: Pico
+        d = 10 ^^ (negate n)
+        r = mod' x d
+    in
+        case r of
+            0 -> reduceDigits (n - 1) x
+            _ -> Just $ x - r
 
 instance Arbitrary TimeOfDay where
     arbitrary = liftM timeToTimeOfDay arbitrary
-    shrink (TimeOfDay h m s) = let
-        shrinkInt 0 = []
-        shrinkInt 1 = [0]
-        shrinkInt _ = [0, 1]
-        shrinkPico 0 = []
-        shrinkPico 1 = [0]
-        shrinkPico p =
-            case reduceDigits 12 p of
+    shrink (TimeOfDay h m s) =
+        let
+            shrinkInt 0 = []
+            shrinkInt 1 = [0]
+            shrinkInt _ = [0, 1]
+            shrinkPico 0 = []
+            shrinkPico 1 = [0]
+            shrinkPico p = case reduceDigits 12 p of
                 Just p' -> [0, 1, p']
                 Nothing -> [0, 1]
-        in [TimeOfDay h' m s | h' <- shrinkInt h] ++
-           [TimeOfDay h m' s | m' <- shrinkInt m] ++ [TimeOfDay h m s' | s' <- shrinkPico s]
+        in
+            [TimeOfDay h' m s | h' <- shrinkInt h]
+                ++ [TimeOfDay h m' s | m' <- shrinkInt m]
+                ++ [TimeOfDay h m s' | s' <- shrinkPico s]
 
+instance Arbitrary (NoLeapSeconds TimeOfDay) where
+    arbitrary = fmap (MkNoLeapSeconds . timeToTimeOfDay) arbitraryNoLeapSeconds
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
+
 instance CoArbitrary TimeOfDay where
     coarbitrary t = coarbitrary (timeOfDayToTime t)
 
@@ -104,6 +194,10 @@
 instance CoArbitrary LocalTime where
     coarbitrary t = coarbitrary (floor (utcTimeToPOSIXSeconds (localTimeToUTC utc t)) :: Integer)
 
+instance Arbitrary (NoLeapSeconds LocalTime) where
+    arbitrary = fmap MkNoLeapSeconds $ liftM2 LocalTime arbitraryNoLeapSeconds arbitraryNoLeapSeconds
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
+
 instance Arbitrary TimeZone where
     arbitrary = liftM minutesToTimeZone $ choose (-720, 720)
     shrink (TimeZone 0 _ _) = []
@@ -119,12 +213,20 @@
 instance CoArbitrary ZonedTime where
     coarbitrary t = coarbitrary (floor (utcTimeToPOSIXSeconds (zonedTimeToUTC t)) :: Integer)
 
+instance Arbitrary (NoLeapSeconds ZonedTime) where
+    arbitrary = fmap MkNoLeapSeconds $ liftM2 ZonedTime arbitraryNoLeapSeconds arbitraryNoLeapSeconds
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
+
 instance Arbitrary UTCTime where
     arbitrary = liftM2 UTCTime arbitrary arbitrary
     shrink t = fmap (localTimeToUTC utc) $ shrink $ utcToLocalTime utc t
 
 instance CoArbitrary UTCTime where
     coarbitrary t = coarbitrary (floor (utcTimeToPOSIXSeconds t) :: Integer)
+
+instance Arbitrary (NoLeapSeconds UTCTime) where
+    arbitrary = fmap MkNoLeapSeconds $ liftM2 UTCTime arbitraryNoLeapSeconds arbitraryNoLeapSeconds
+    shrink (MkNoLeapSeconds t) = fmap MkNoLeapSeconds $ shrink t
 
 instance Arbitrary UniversalTime where
     arbitrary = liftM (\n -> ModJulianDate $ n % k) $ choose (-313698 * k, 2973483 * k) -- 1000-01-1 to 9999-12-31
diff --git a/test/main/Test/Calendar/AddDays.hs b/test/main/Test/Calendar/AddDays.hs
--- a/test/main/Test/Calendar/AddDays.hs
+++ b/test/main/Test/Calendar/AddDays.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.AddDays
-    ( addDaysTest
-    ) where
+module Test.Calendar.AddDays (
+    addDaysTest,
+) where
 
 import Data.Time.Calendar
 import Test.Calendar.AddDaysRef
@@ -36,8 +36,14 @@
     increment <- increments
     day <- days
     return
-        ((showGregorian day) ++
-         " + " ++ (show increment) ++ " * " ++ aname ++ " = " ++ showGregorian (adder increment day))
+        ( (showGregorian day)
+            ++ " + "
+            ++ (show increment)
+            ++ " * "
+            ++ aname
+            ++ " = "
+            ++ showGregorian (adder increment day)
+        )
 
 addDaysTest :: TestTree
 addDaysTest = testCase "addDays" $ assertEqual "" addDaysRef $ unlines resultDays
diff --git a/test/main/Test/Calendar/CalendarProps.hs b/test/main/Test/Calendar/CalendarProps.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/Calendar/CalendarProps.hs
@@ -0,0 +1,24 @@
+module Test.Calendar.CalendarProps (
+    testCalendarProps,
+) where
+
+import Data.Time.Calendar.Month
+import Data.Time.Calendar.Quarter
+import Test.Arbitrary ()
+import Test.Tasty
+import Test.TestUtil
+
+testYearMonth :: TestTree
+testYearMonth = nameTest "YearMonth" $ \m -> case m of
+    YearMonth y my -> m == YearMonth y my
+
+testMonthDay :: TestTree
+testMonthDay = nameTest "MonthDay" $ \d -> case d of
+    MonthDay m dm -> d == MonthDay m dm
+
+testYearQuarter :: TestTree
+testYearQuarter = nameTest "YearQuarter" $ \q -> case q of
+    YearQuarter y qy -> q == YearQuarter y qy
+
+testCalendarProps :: TestTree
+testCalendarProps = nameTest "calendar-props" [testYearMonth, testMonthDay, testYearQuarter]
diff --git a/test/main/Test/Calendar/Calendars.hs b/test/main/Test/Calendar/Calendars.hs
--- a/test/main/Test/Calendar/Calendars.hs
+++ b/test/main/Test/Calendar/Calendars.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.Calendars
-    ( testCalendars
-    ) where
+module Test.Calendar.Calendars (
+    testCalendars,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.Julian
diff --git a/test/main/Test/Calendar/ClipDates.hs b/test/main/Test/Calendar/ClipDates.hs
--- a/test/main/Test/Calendar/ClipDates.hs
+++ b/test/main/Test/Calendar/ClipDates.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.ClipDates
-    ( clipDates
-    ) where
+module Test.Calendar.ClipDates (
+    clipDates,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.OrdinalDate
@@ -20,24 +20,28 @@
 
 --
 tupleUp2 :: [a] -> [b] -> [(a, b)]
-tupleUp2 l1 l2 = concatMap (\e -> map (e, ) l2) l1
+tupleUp2 l1 l2 = concatMap (\e -> map (e,) l2) l1
 
 tupleUp3 :: [a] -> [b] -> [c] -> [(a, b, c)]
-tupleUp3 l1 l2 l3 = let
-    ts = tupleUp2 l2 l3
-    in concatMap (\e -> map (\(f, g) -> (e, f, g)) ts) l1
+tupleUp3 l1 l2 l3 =
+    let
+        ts = tupleUp2 l2 l3
+    in
+        concatMap (\e -> map (\(f, g) -> (e, f, g)) ts) l1
 
+testPairs :: String -> [String] -> [String] -> TestTree
+testPairs name expected found = testGroup name $ fmap (\(e, f) -> testCase e $ assertEqual "" e f) $ zip expected found
+
 --
 clipDates :: TestTree
 clipDates =
-    testCase "clipDates" $ let
-        yad = unlines $ map yearAndDay $ tupleUp2 [1968, 1969, 1971] [-4, 0, 1, 200, 364, 365, 366, 367, 700]
-        greg =
-            unlines $
+    testGroup
+        "clipDates"
+        [ testPairs "YearAndDay" clipDatesYearAndDayRef $ map yearAndDay $ tupleUp2 [1968, 1969, 1971] [-4, 0, 1, 200, 364, 365, 366, 367, 700]
+        , testPairs "Gregorian" clipDatesGregorianDayRef $
             map gregorian $
-            tupleUp3 [1968, 1969, 1971] [-20, -1, 0, 1, 2, 12, 13, 17] [-7, -1, 0, 1, 2, 27, 28, 29, 30, 31, 32, 40]
-        iso =
-            unlines $
+                tupleUp3 [1968, 1969, 1971] [-20, -1, 0, 1, 2, 12, 13, 17] [-7, -1, 0, 1, 2, 27, 28, 29, 30, 31, 32, 40]
+        , testPairs "ISOWeekDay" clipDatesISOWeekDayRef $
             map iSOWeekDay $
-            tupleUp3 [1968, 1969, 2004] [-20, -1, 0, 1, 20, 51, 52, 53, 54] [-2, -1, 0, 1, 4, 6, 7, 8, 9]
-        in assertEqual "" clipDatesRef $ concat ["YearAndDay\n", yad, "Gregorian\n", greg, "ISOWeekDay\n", iso]
+                tupleUp3 [1968, 1969, 2004] [-20, -1, 0, 1, 20, 51, 52, 53, 54] [-2, -1, 0, 1, 4, 6, 7, 8, 9]
+        ]
diff --git a/test/main/Test/Calendar/ClipDatesRef.hs b/test/main/Test/Calendar/ClipDatesRef.hs
--- a/test/main/Test/Calendar/ClipDatesRef.hs
+++ b/test/main/Test/Calendar/ClipDatesRef.hs
@@ -1,567 +1,571 @@
 module Test.Calendar.ClipDatesRef where
 
-clipDatesRef :: String
-clipDatesRef =
-    unlines
-        [ "YearAndDay"
-        , "1968--4 = 1968-001"
-        , "1968-0 = 1968-001"
-        , "1968-1 = 1968-001"
-        , "1968-200 = 1968-200"
-        , "1968-364 = 1968-364"
-        , "1968-365 = 1968-365"
-        , "1968-366 = 1968-366"
-        , "1968-367 = 1968-366"
-        , "1968-700 = 1968-366"
-        , "1969--4 = 1969-001"
-        , "1969-0 = 1969-001"
-        , "1969-1 = 1969-001"
-        , "1969-200 = 1969-200"
-        , "1969-364 = 1969-364"
-        , "1969-365 = 1969-365"
-        , "1969-366 = 1969-365"
-        , "1969-367 = 1969-365"
-        , "1969-700 = 1969-365"
-        , "1971--4 = 1971-001"
-        , "1971-0 = 1971-001"
-        , "1971-1 = 1971-001"
-        , "1971-200 = 1971-200"
-        , "1971-364 = 1971-364"
-        , "1971-365 = 1971-365"
-        , "1971-366 = 1971-365"
-        , "1971-367 = 1971-365"
-        , "1971-700 = 1971-365"
-        , "Gregorian"
-        , "1968--20--7 = 1968-01-01"
-        , "1968--20--1 = 1968-01-01"
-        , "1968--20-0 = 1968-01-01"
-        , "1968--20-1 = 1968-01-01"
-        , "1968--20-2 = 1968-01-02"
-        , "1968--20-27 = 1968-01-27"
-        , "1968--20-28 = 1968-01-28"
-        , "1968--20-29 = 1968-01-29"
-        , "1968--20-30 = 1968-01-30"
-        , "1968--20-31 = 1968-01-31"
-        , "1968--20-32 = 1968-01-31"
-        , "1968--20-40 = 1968-01-31"
-        , "1968--1--7 = 1968-01-01"
-        , "1968--1--1 = 1968-01-01"
-        , "1968--1-0 = 1968-01-01"
-        , "1968--1-1 = 1968-01-01"
-        , "1968--1-2 = 1968-01-02"
-        , "1968--1-27 = 1968-01-27"
-        , "1968--1-28 = 1968-01-28"
-        , "1968--1-29 = 1968-01-29"
-        , "1968--1-30 = 1968-01-30"
-        , "1968--1-31 = 1968-01-31"
-        , "1968--1-32 = 1968-01-31"
-        , "1968--1-40 = 1968-01-31"
-        , "1968-0--7 = 1968-01-01"
-        , "1968-0--1 = 1968-01-01"
-        , "1968-0-0 = 1968-01-01"
-        , "1968-0-1 = 1968-01-01"
-        , "1968-0-2 = 1968-01-02"
-        , "1968-0-27 = 1968-01-27"
-        , "1968-0-28 = 1968-01-28"
-        , "1968-0-29 = 1968-01-29"
-        , "1968-0-30 = 1968-01-30"
-        , "1968-0-31 = 1968-01-31"
-        , "1968-0-32 = 1968-01-31"
-        , "1968-0-40 = 1968-01-31"
-        , "1968-1--7 = 1968-01-01"
-        , "1968-1--1 = 1968-01-01"
-        , "1968-1-0 = 1968-01-01"
-        , "1968-1-1 = 1968-01-01"
-        , "1968-1-2 = 1968-01-02"
-        , "1968-1-27 = 1968-01-27"
-        , "1968-1-28 = 1968-01-28"
-        , "1968-1-29 = 1968-01-29"
-        , "1968-1-30 = 1968-01-30"
-        , "1968-1-31 = 1968-01-31"
-        , "1968-1-32 = 1968-01-31"
-        , "1968-1-40 = 1968-01-31"
-        , "1968-2--7 = 1968-02-01"
-        , "1968-2--1 = 1968-02-01"
-        , "1968-2-0 = 1968-02-01"
-        , "1968-2-1 = 1968-02-01"
-        , "1968-2-2 = 1968-02-02"
-        , "1968-2-27 = 1968-02-27"
-        , "1968-2-28 = 1968-02-28"
-        , "1968-2-29 = 1968-02-29"
-        , "1968-2-30 = 1968-02-29"
-        , "1968-2-31 = 1968-02-29"
-        , "1968-2-32 = 1968-02-29"
-        , "1968-2-40 = 1968-02-29"
-        , "1968-12--7 = 1968-12-01"
-        , "1968-12--1 = 1968-12-01"
-        , "1968-12-0 = 1968-12-01"
-        , "1968-12-1 = 1968-12-01"
-        , "1968-12-2 = 1968-12-02"
-        , "1968-12-27 = 1968-12-27"
-        , "1968-12-28 = 1968-12-28"
-        , "1968-12-29 = 1968-12-29"
-        , "1968-12-30 = 1968-12-30"
-        , "1968-12-31 = 1968-12-31"
-        , "1968-12-32 = 1968-12-31"
-        , "1968-12-40 = 1968-12-31"
-        , "1968-13--7 = 1968-12-01"
-        , "1968-13--1 = 1968-12-01"
-        , "1968-13-0 = 1968-12-01"
-        , "1968-13-1 = 1968-12-01"
-        , "1968-13-2 = 1968-12-02"
-        , "1968-13-27 = 1968-12-27"
-        , "1968-13-28 = 1968-12-28"
-        , "1968-13-29 = 1968-12-29"
-        , "1968-13-30 = 1968-12-30"
-        , "1968-13-31 = 1968-12-31"
-        , "1968-13-32 = 1968-12-31"
-        , "1968-13-40 = 1968-12-31"
-        , "1968-17--7 = 1968-12-01"
-        , "1968-17--1 = 1968-12-01"
-        , "1968-17-0 = 1968-12-01"
-        , "1968-17-1 = 1968-12-01"
-        , "1968-17-2 = 1968-12-02"
-        , "1968-17-27 = 1968-12-27"
-        , "1968-17-28 = 1968-12-28"
-        , "1968-17-29 = 1968-12-29"
-        , "1968-17-30 = 1968-12-30"
-        , "1968-17-31 = 1968-12-31"
-        , "1968-17-32 = 1968-12-31"
-        , "1968-17-40 = 1968-12-31"
-        , "1969--20--7 = 1969-01-01"
-        , "1969--20--1 = 1969-01-01"
-        , "1969--20-0 = 1969-01-01"
-        , "1969--20-1 = 1969-01-01"
-        , "1969--20-2 = 1969-01-02"
-        , "1969--20-27 = 1969-01-27"
-        , "1969--20-28 = 1969-01-28"
-        , "1969--20-29 = 1969-01-29"
-        , "1969--20-30 = 1969-01-30"
-        , "1969--20-31 = 1969-01-31"
-        , "1969--20-32 = 1969-01-31"
-        , "1969--20-40 = 1969-01-31"
-        , "1969--1--7 = 1969-01-01"
-        , "1969--1--1 = 1969-01-01"
-        , "1969--1-0 = 1969-01-01"
-        , "1969--1-1 = 1969-01-01"
-        , "1969--1-2 = 1969-01-02"
-        , "1969--1-27 = 1969-01-27"
-        , "1969--1-28 = 1969-01-28"
-        , "1969--1-29 = 1969-01-29"
-        , "1969--1-30 = 1969-01-30"
-        , "1969--1-31 = 1969-01-31"
-        , "1969--1-32 = 1969-01-31"
-        , "1969--1-40 = 1969-01-31"
-        , "1969-0--7 = 1969-01-01"
-        , "1969-0--1 = 1969-01-01"
-        , "1969-0-0 = 1969-01-01"
-        , "1969-0-1 = 1969-01-01"
-        , "1969-0-2 = 1969-01-02"
-        , "1969-0-27 = 1969-01-27"
-        , "1969-0-28 = 1969-01-28"
-        , "1969-0-29 = 1969-01-29"
-        , "1969-0-30 = 1969-01-30"
-        , "1969-0-31 = 1969-01-31"
-        , "1969-0-32 = 1969-01-31"
-        , "1969-0-40 = 1969-01-31"
-        , "1969-1--7 = 1969-01-01"
-        , "1969-1--1 = 1969-01-01"
-        , "1969-1-0 = 1969-01-01"
-        , "1969-1-1 = 1969-01-01"
-        , "1969-1-2 = 1969-01-02"
-        , "1969-1-27 = 1969-01-27"
-        , "1969-1-28 = 1969-01-28"
-        , "1969-1-29 = 1969-01-29"
-        , "1969-1-30 = 1969-01-30"
-        , "1969-1-31 = 1969-01-31"
-        , "1969-1-32 = 1969-01-31"
-        , "1969-1-40 = 1969-01-31"
-        , "1969-2--7 = 1969-02-01"
-        , "1969-2--1 = 1969-02-01"
-        , "1969-2-0 = 1969-02-01"
-        , "1969-2-1 = 1969-02-01"
-        , "1969-2-2 = 1969-02-02"
-        , "1969-2-27 = 1969-02-27"
-        , "1969-2-28 = 1969-02-28"
-        , "1969-2-29 = 1969-02-28"
-        , "1969-2-30 = 1969-02-28"
-        , "1969-2-31 = 1969-02-28"
-        , "1969-2-32 = 1969-02-28"
-        , "1969-2-40 = 1969-02-28"
-        , "1969-12--7 = 1969-12-01"
-        , "1969-12--1 = 1969-12-01"
-        , "1969-12-0 = 1969-12-01"
-        , "1969-12-1 = 1969-12-01"
-        , "1969-12-2 = 1969-12-02"
-        , "1969-12-27 = 1969-12-27"
-        , "1969-12-28 = 1969-12-28"
-        , "1969-12-29 = 1969-12-29"
-        , "1969-12-30 = 1969-12-30"
-        , "1969-12-31 = 1969-12-31"
-        , "1969-12-32 = 1969-12-31"
-        , "1969-12-40 = 1969-12-31"
-        , "1969-13--7 = 1969-12-01"
-        , "1969-13--1 = 1969-12-01"
-        , "1969-13-0 = 1969-12-01"
-        , "1969-13-1 = 1969-12-01"
-        , "1969-13-2 = 1969-12-02"
-        , "1969-13-27 = 1969-12-27"
-        , "1969-13-28 = 1969-12-28"
-        , "1969-13-29 = 1969-12-29"
-        , "1969-13-30 = 1969-12-30"
-        , "1969-13-31 = 1969-12-31"
-        , "1969-13-32 = 1969-12-31"
-        , "1969-13-40 = 1969-12-31"
-        , "1969-17--7 = 1969-12-01"
-        , "1969-17--1 = 1969-12-01"
-        , "1969-17-0 = 1969-12-01"
-        , "1969-17-1 = 1969-12-01"
-        , "1969-17-2 = 1969-12-02"
-        , "1969-17-27 = 1969-12-27"
-        , "1969-17-28 = 1969-12-28"
-        , "1969-17-29 = 1969-12-29"
-        , "1969-17-30 = 1969-12-30"
-        , "1969-17-31 = 1969-12-31"
-        , "1969-17-32 = 1969-12-31"
-        , "1969-17-40 = 1969-12-31"
-        , "1971--20--7 = 1971-01-01"
-        , "1971--20--1 = 1971-01-01"
-        , "1971--20-0 = 1971-01-01"
-        , "1971--20-1 = 1971-01-01"
-        , "1971--20-2 = 1971-01-02"
-        , "1971--20-27 = 1971-01-27"
-        , "1971--20-28 = 1971-01-28"
-        , "1971--20-29 = 1971-01-29"
-        , "1971--20-30 = 1971-01-30"
-        , "1971--20-31 = 1971-01-31"
-        , "1971--20-32 = 1971-01-31"
-        , "1971--20-40 = 1971-01-31"
-        , "1971--1--7 = 1971-01-01"
-        , "1971--1--1 = 1971-01-01"
-        , "1971--1-0 = 1971-01-01"
-        , "1971--1-1 = 1971-01-01"
-        , "1971--1-2 = 1971-01-02"
-        , "1971--1-27 = 1971-01-27"
-        , "1971--1-28 = 1971-01-28"
-        , "1971--1-29 = 1971-01-29"
-        , "1971--1-30 = 1971-01-30"
-        , "1971--1-31 = 1971-01-31"
-        , "1971--1-32 = 1971-01-31"
-        , "1971--1-40 = 1971-01-31"
-        , "1971-0--7 = 1971-01-01"
-        , "1971-0--1 = 1971-01-01"
-        , "1971-0-0 = 1971-01-01"
-        , "1971-0-1 = 1971-01-01"
-        , "1971-0-2 = 1971-01-02"
-        , "1971-0-27 = 1971-01-27"
-        , "1971-0-28 = 1971-01-28"
-        , "1971-0-29 = 1971-01-29"
-        , "1971-0-30 = 1971-01-30"
-        , "1971-0-31 = 1971-01-31"
-        , "1971-0-32 = 1971-01-31"
-        , "1971-0-40 = 1971-01-31"
-        , "1971-1--7 = 1971-01-01"
-        , "1971-1--1 = 1971-01-01"
-        , "1971-1-0 = 1971-01-01"
-        , "1971-1-1 = 1971-01-01"
-        , "1971-1-2 = 1971-01-02"
-        , "1971-1-27 = 1971-01-27"
-        , "1971-1-28 = 1971-01-28"
-        , "1971-1-29 = 1971-01-29"
-        , "1971-1-30 = 1971-01-30"
-        , "1971-1-31 = 1971-01-31"
-        , "1971-1-32 = 1971-01-31"
-        , "1971-1-40 = 1971-01-31"
-        , "1971-2--7 = 1971-02-01"
-        , "1971-2--1 = 1971-02-01"
-        , "1971-2-0 = 1971-02-01"
-        , "1971-2-1 = 1971-02-01"
-        , "1971-2-2 = 1971-02-02"
-        , "1971-2-27 = 1971-02-27"
-        , "1971-2-28 = 1971-02-28"
-        , "1971-2-29 = 1971-02-28"
-        , "1971-2-30 = 1971-02-28"
-        , "1971-2-31 = 1971-02-28"
-        , "1971-2-32 = 1971-02-28"
-        , "1971-2-40 = 1971-02-28"
-        , "1971-12--7 = 1971-12-01"
-        , "1971-12--1 = 1971-12-01"
-        , "1971-12-0 = 1971-12-01"
-        , "1971-12-1 = 1971-12-01"
-        , "1971-12-2 = 1971-12-02"
-        , "1971-12-27 = 1971-12-27"
-        , "1971-12-28 = 1971-12-28"
-        , "1971-12-29 = 1971-12-29"
-        , "1971-12-30 = 1971-12-30"
-        , "1971-12-31 = 1971-12-31"
-        , "1971-12-32 = 1971-12-31"
-        , "1971-12-40 = 1971-12-31"
-        , "1971-13--7 = 1971-12-01"
-        , "1971-13--1 = 1971-12-01"
-        , "1971-13-0 = 1971-12-01"
-        , "1971-13-1 = 1971-12-01"
-        , "1971-13-2 = 1971-12-02"
-        , "1971-13-27 = 1971-12-27"
-        , "1971-13-28 = 1971-12-28"
-        , "1971-13-29 = 1971-12-29"
-        , "1971-13-30 = 1971-12-30"
-        , "1971-13-31 = 1971-12-31"
-        , "1971-13-32 = 1971-12-31"
-        , "1971-13-40 = 1971-12-31"
-        , "1971-17--7 = 1971-12-01"
-        , "1971-17--1 = 1971-12-01"
-        , "1971-17-0 = 1971-12-01"
-        , "1971-17-1 = 1971-12-01"
-        , "1971-17-2 = 1971-12-02"
-        , "1971-17-27 = 1971-12-27"
-        , "1971-17-28 = 1971-12-28"
-        , "1971-17-29 = 1971-12-29"
-        , "1971-17-30 = 1971-12-30"
-        , "1971-17-31 = 1971-12-31"
-        , "1971-17-32 = 1971-12-31"
-        , "1971-17-40 = 1971-12-31"
-        , "ISOWeekDay"
-        , "1968-W-20--2 = 1968-W01-1"
-        , "1968-W-20--1 = 1968-W01-1"
-        , "1968-W-20-0 = 1968-W01-1"
-        , "1968-W-20-1 = 1968-W01-1"
-        , "1968-W-20-4 = 1968-W01-4"
-        , "1968-W-20-6 = 1968-W01-6"
-        , "1968-W-20-7 = 1968-W01-7"
-        , "1968-W-20-8 = 1968-W01-7"
-        , "1968-W-20-9 = 1968-W01-7"
-        , "1968-W-1--2 = 1968-W01-1"
-        , "1968-W-1--1 = 1968-W01-1"
-        , "1968-W-1-0 = 1968-W01-1"
-        , "1968-W-1-1 = 1968-W01-1"
-        , "1968-W-1-4 = 1968-W01-4"
-        , "1968-W-1-6 = 1968-W01-6"
-        , "1968-W-1-7 = 1968-W01-7"
-        , "1968-W-1-8 = 1968-W01-7"
-        , "1968-W-1-9 = 1968-W01-7"
-        , "1968-W0--2 = 1968-W01-1"
-        , "1968-W0--1 = 1968-W01-1"
-        , "1968-W0-0 = 1968-W01-1"
-        , "1968-W0-1 = 1968-W01-1"
-        , "1968-W0-4 = 1968-W01-4"
-        , "1968-W0-6 = 1968-W01-6"
-        , "1968-W0-7 = 1968-W01-7"
-        , "1968-W0-8 = 1968-W01-7"
-        , "1968-W0-9 = 1968-W01-7"
-        , "1968-W1--2 = 1968-W01-1"
-        , "1968-W1--1 = 1968-W01-1"
-        , "1968-W1-0 = 1968-W01-1"
-        , "1968-W1-1 = 1968-W01-1"
-        , "1968-W1-4 = 1968-W01-4"
-        , "1968-W1-6 = 1968-W01-6"
-        , "1968-W1-7 = 1968-W01-7"
-        , "1968-W1-8 = 1968-W01-7"
-        , "1968-W1-9 = 1968-W01-7"
-        , "1968-W20--2 = 1968-W20-1"
-        , "1968-W20--1 = 1968-W20-1"
-        , "1968-W20-0 = 1968-W20-1"
-        , "1968-W20-1 = 1968-W20-1"
-        , "1968-W20-4 = 1968-W20-4"
-        , "1968-W20-6 = 1968-W20-6"
-        , "1968-W20-7 = 1968-W20-7"
-        , "1968-W20-8 = 1968-W20-7"
-        , "1968-W20-9 = 1968-W20-7"
-        , "1968-W51--2 = 1968-W51-1"
-        , "1968-W51--1 = 1968-W51-1"
-        , "1968-W51-0 = 1968-W51-1"
-        , "1968-W51-1 = 1968-W51-1"
-        , "1968-W51-4 = 1968-W51-4"
-        , "1968-W51-6 = 1968-W51-6"
-        , "1968-W51-7 = 1968-W51-7"
-        , "1968-W51-8 = 1968-W51-7"
-        , "1968-W51-9 = 1968-W51-7"
-        , "1968-W52--2 = 1968-W52-1"
-        , "1968-W52--1 = 1968-W52-1"
-        , "1968-W52-0 = 1968-W52-1"
-        , "1968-W52-1 = 1968-W52-1"
-        , "1968-W52-4 = 1968-W52-4"
-        , "1968-W52-6 = 1968-W52-6"
-        , "1968-W52-7 = 1968-W52-7"
-        , "1968-W52-8 = 1968-W52-7"
-        , "1968-W52-9 = 1968-W52-7"
-        , "1968-W53--2 = 1968-W52-1"
-        , "1968-W53--1 = 1968-W52-1"
-        , "1968-W53-0 = 1968-W52-1"
-        , "1968-W53-1 = 1968-W52-1"
-        , "1968-W53-4 = 1968-W52-4"
-        , "1968-W53-6 = 1968-W52-6"
-        , "1968-W53-7 = 1968-W52-7"
-        , "1968-W53-8 = 1968-W52-7"
-        , "1968-W53-9 = 1968-W52-7"
-        , "1968-W54--2 = 1968-W52-1"
-        , "1968-W54--1 = 1968-W52-1"
-        , "1968-W54-0 = 1968-W52-1"
-        , "1968-W54-1 = 1968-W52-1"
-        , "1968-W54-4 = 1968-W52-4"
-        , "1968-W54-6 = 1968-W52-6"
-        , "1968-W54-7 = 1968-W52-7"
-        , "1968-W54-8 = 1968-W52-7"
-        , "1968-W54-9 = 1968-W52-7"
-        , "1969-W-20--2 = 1969-W01-1"
-        , "1969-W-20--1 = 1969-W01-1"
-        , "1969-W-20-0 = 1969-W01-1"
-        , "1969-W-20-1 = 1969-W01-1"
-        , "1969-W-20-4 = 1969-W01-4"
-        , "1969-W-20-6 = 1969-W01-6"
-        , "1969-W-20-7 = 1969-W01-7"
-        , "1969-W-20-8 = 1969-W01-7"
-        , "1969-W-20-9 = 1969-W01-7"
-        , "1969-W-1--2 = 1969-W01-1"
-        , "1969-W-1--1 = 1969-W01-1"
-        , "1969-W-1-0 = 1969-W01-1"
-        , "1969-W-1-1 = 1969-W01-1"
-        , "1969-W-1-4 = 1969-W01-4"
-        , "1969-W-1-6 = 1969-W01-6"
-        , "1969-W-1-7 = 1969-W01-7"
-        , "1969-W-1-8 = 1969-W01-7"
-        , "1969-W-1-9 = 1969-W01-7"
-        , "1969-W0--2 = 1969-W01-1"
-        , "1969-W0--1 = 1969-W01-1"
-        , "1969-W0-0 = 1969-W01-1"
-        , "1969-W0-1 = 1969-W01-1"
-        , "1969-W0-4 = 1969-W01-4"
-        , "1969-W0-6 = 1969-W01-6"
-        , "1969-W0-7 = 1969-W01-7"
-        , "1969-W0-8 = 1969-W01-7"
-        , "1969-W0-9 = 1969-W01-7"
-        , "1969-W1--2 = 1969-W01-1"
-        , "1969-W1--1 = 1969-W01-1"
-        , "1969-W1-0 = 1969-W01-1"
-        , "1969-W1-1 = 1969-W01-1"
-        , "1969-W1-4 = 1969-W01-4"
-        , "1969-W1-6 = 1969-W01-6"
-        , "1969-W1-7 = 1969-W01-7"
-        , "1969-W1-8 = 1969-W01-7"
-        , "1969-W1-9 = 1969-W01-7"
-        , "1969-W20--2 = 1969-W20-1"
-        , "1969-W20--1 = 1969-W20-1"
-        , "1969-W20-0 = 1969-W20-1"
-        , "1969-W20-1 = 1969-W20-1"
-        , "1969-W20-4 = 1969-W20-4"
-        , "1969-W20-6 = 1969-W20-6"
-        , "1969-W20-7 = 1969-W20-7"
-        , "1969-W20-8 = 1969-W20-7"
-        , "1969-W20-9 = 1969-W20-7"
-        , "1969-W51--2 = 1969-W51-1"
-        , "1969-W51--1 = 1969-W51-1"
-        , "1969-W51-0 = 1969-W51-1"
-        , "1969-W51-1 = 1969-W51-1"
-        , "1969-W51-4 = 1969-W51-4"
-        , "1969-W51-6 = 1969-W51-6"
-        , "1969-W51-7 = 1969-W51-7"
-        , "1969-W51-8 = 1969-W51-7"
-        , "1969-W51-9 = 1969-W51-7"
-        , "1969-W52--2 = 1969-W52-1"
-        , "1969-W52--1 = 1969-W52-1"
-        , "1969-W52-0 = 1969-W52-1"
-        , "1969-W52-1 = 1969-W52-1"
-        , "1969-W52-4 = 1969-W52-4"
-        , "1969-W52-6 = 1969-W52-6"
-        , "1969-W52-7 = 1969-W52-7"
-        , "1969-W52-8 = 1969-W52-7"
-        , "1969-W52-9 = 1969-W52-7"
-        , "1969-W53--2 = 1969-W52-1"
-        , "1969-W53--1 = 1969-W52-1"
-        , "1969-W53-0 = 1969-W52-1"
-        , "1969-W53-1 = 1969-W52-1"
-        , "1969-W53-4 = 1969-W52-4"
-        , "1969-W53-6 = 1969-W52-6"
-        , "1969-W53-7 = 1969-W52-7"
-        , "1969-W53-8 = 1969-W52-7"
-        , "1969-W53-9 = 1969-W52-7"
-        , "1969-W54--2 = 1969-W52-1"
-        , "1969-W54--1 = 1969-W52-1"
-        , "1969-W54-0 = 1969-W52-1"
-        , "1969-W54-1 = 1969-W52-1"
-        , "1969-W54-4 = 1969-W52-4"
-        , "1969-W54-6 = 1969-W52-6"
-        , "1969-W54-7 = 1969-W52-7"
-        , "1969-W54-8 = 1969-W52-7"
-        , "1969-W54-9 = 1969-W52-7"
-        , "2004-W-20--2 = 2004-W01-1"
-        , "2004-W-20--1 = 2004-W01-1"
-        , "2004-W-20-0 = 2004-W01-1"
-        , "2004-W-20-1 = 2004-W01-1"
-        , "2004-W-20-4 = 2004-W01-4"
-        , "2004-W-20-6 = 2004-W01-6"
-        , "2004-W-20-7 = 2004-W01-7"
-        , "2004-W-20-8 = 2004-W01-7"
-        , "2004-W-20-9 = 2004-W01-7"
-        , "2004-W-1--2 = 2004-W01-1"
-        , "2004-W-1--1 = 2004-W01-1"
-        , "2004-W-1-0 = 2004-W01-1"
-        , "2004-W-1-1 = 2004-W01-1"
-        , "2004-W-1-4 = 2004-W01-4"
-        , "2004-W-1-6 = 2004-W01-6"
-        , "2004-W-1-7 = 2004-W01-7"
-        , "2004-W-1-8 = 2004-W01-7"
-        , "2004-W-1-9 = 2004-W01-7"
-        , "2004-W0--2 = 2004-W01-1"
-        , "2004-W0--1 = 2004-W01-1"
-        , "2004-W0-0 = 2004-W01-1"
-        , "2004-W0-1 = 2004-W01-1"
-        , "2004-W0-4 = 2004-W01-4"
-        , "2004-W0-6 = 2004-W01-6"
-        , "2004-W0-7 = 2004-W01-7"
-        , "2004-W0-8 = 2004-W01-7"
-        , "2004-W0-9 = 2004-W01-7"
-        , "2004-W1--2 = 2004-W01-1"
-        , "2004-W1--1 = 2004-W01-1"
-        , "2004-W1-0 = 2004-W01-1"
-        , "2004-W1-1 = 2004-W01-1"
-        , "2004-W1-4 = 2004-W01-4"
-        , "2004-W1-6 = 2004-W01-6"
-        , "2004-W1-7 = 2004-W01-7"
-        , "2004-W1-8 = 2004-W01-7"
-        , "2004-W1-9 = 2004-W01-7"
-        , "2004-W20--2 = 2004-W20-1"
-        , "2004-W20--1 = 2004-W20-1"
-        , "2004-W20-0 = 2004-W20-1"
-        , "2004-W20-1 = 2004-W20-1"
-        , "2004-W20-4 = 2004-W20-4"
-        , "2004-W20-6 = 2004-W20-6"
-        , "2004-W20-7 = 2004-W20-7"
-        , "2004-W20-8 = 2004-W20-7"
-        , "2004-W20-9 = 2004-W20-7"
-        , "2004-W51--2 = 2004-W51-1"
-        , "2004-W51--1 = 2004-W51-1"
-        , "2004-W51-0 = 2004-W51-1"
-        , "2004-W51-1 = 2004-W51-1"
-        , "2004-W51-4 = 2004-W51-4"
-        , "2004-W51-6 = 2004-W51-6"
-        , "2004-W51-7 = 2004-W51-7"
-        , "2004-W51-8 = 2004-W51-7"
-        , "2004-W51-9 = 2004-W51-7"
-        , "2004-W52--2 = 2004-W52-1"
-        , "2004-W52--1 = 2004-W52-1"
-        , "2004-W52-0 = 2004-W52-1"
-        , "2004-W52-1 = 2004-W52-1"
-        , "2004-W52-4 = 2004-W52-4"
-        , "2004-W52-6 = 2004-W52-6"
-        , "2004-W52-7 = 2004-W52-7"
-        , "2004-W52-8 = 2004-W52-7"
-        , "2004-W52-9 = 2004-W52-7"
-        , "2004-W53--2 = 2004-W53-1"
-        , "2004-W53--1 = 2004-W53-1"
-        , "2004-W53-0 = 2004-W53-1"
-        , "2004-W53-1 = 2004-W53-1"
-        , "2004-W53-4 = 2004-W53-4"
-        , "2004-W53-6 = 2004-W53-6"
-        , "2004-W53-7 = 2004-W53-7"
-        , "2004-W53-8 = 2004-W53-7"
-        , "2004-W53-9 = 2004-W53-7"
-        , "2004-W54--2 = 2004-W53-1"
-        , "2004-W54--1 = 2004-W53-1"
-        , "2004-W54-0 = 2004-W53-1"
-        , "2004-W54-1 = 2004-W53-1"
-        , "2004-W54-4 = 2004-W53-4"
-        , "2004-W54-6 = 2004-W53-6"
-        , "2004-W54-7 = 2004-W53-7"
-        , "2004-W54-8 = 2004-W53-7"
-        , "2004-W54-9 = 2004-W53-7"
-        ]
+clipDatesYearAndDayRef :: [String]
+clipDatesYearAndDayRef =
+    [ "1968--4 = 1968-001"
+    , "1968-0 = 1968-001"
+    , "1968-1 = 1968-001"
+    , "1968-200 = 1968-200"
+    , "1968-364 = 1968-364"
+    , "1968-365 = 1968-365"
+    , "1968-366 = 1968-366"
+    , "1968-367 = 1968-366"
+    , "1968-700 = 1968-366"
+    , "1969--4 = 1969-001"
+    , "1969-0 = 1969-001"
+    , "1969-1 = 1969-001"
+    , "1969-200 = 1969-200"
+    , "1969-364 = 1969-364"
+    , "1969-365 = 1969-365"
+    , "1969-366 = 1969-365"
+    , "1969-367 = 1969-365"
+    , "1969-700 = 1969-365"
+    , "1971--4 = 1971-001"
+    , "1971-0 = 1971-001"
+    , "1971-1 = 1971-001"
+    , "1971-200 = 1971-200"
+    , "1971-364 = 1971-364"
+    , "1971-365 = 1971-365"
+    , "1971-366 = 1971-365"
+    , "1971-367 = 1971-365"
+    , "1971-700 = 1971-365"
+    ]
+
+clipDatesGregorianDayRef :: [String]
+clipDatesGregorianDayRef =
+    [ "1968--20--7 = 1968-01-01"
+    , "1968--20--1 = 1968-01-01"
+    , "1968--20-0 = 1968-01-01"
+    , "1968--20-1 = 1968-01-01"
+    , "1968--20-2 = 1968-01-02"
+    , "1968--20-27 = 1968-01-27"
+    , "1968--20-28 = 1968-01-28"
+    , "1968--20-29 = 1968-01-29"
+    , "1968--20-30 = 1968-01-30"
+    , "1968--20-31 = 1968-01-31"
+    , "1968--20-32 = 1968-01-31"
+    , "1968--20-40 = 1968-01-31"
+    , "1968--1--7 = 1968-01-01"
+    , "1968--1--1 = 1968-01-01"
+    , "1968--1-0 = 1968-01-01"
+    , "1968--1-1 = 1968-01-01"
+    , "1968--1-2 = 1968-01-02"
+    , "1968--1-27 = 1968-01-27"
+    , "1968--1-28 = 1968-01-28"
+    , "1968--1-29 = 1968-01-29"
+    , "1968--1-30 = 1968-01-30"
+    , "1968--1-31 = 1968-01-31"
+    , "1968--1-32 = 1968-01-31"
+    , "1968--1-40 = 1968-01-31"
+    , "1968-0--7 = 1968-01-01"
+    , "1968-0--1 = 1968-01-01"
+    , "1968-0-0 = 1968-01-01"
+    , "1968-0-1 = 1968-01-01"
+    , "1968-0-2 = 1968-01-02"
+    , "1968-0-27 = 1968-01-27"
+    , "1968-0-28 = 1968-01-28"
+    , "1968-0-29 = 1968-01-29"
+    , "1968-0-30 = 1968-01-30"
+    , "1968-0-31 = 1968-01-31"
+    , "1968-0-32 = 1968-01-31"
+    , "1968-0-40 = 1968-01-31"
+    , "1968-1--7 = 1968-01-01"
+    , "1968-1--1 = 1968-01-01"
+    , "1968-1-0 = 1968-01-01"
+    , "1968-1-1 = 1968-01-01"
+    , "1968-1-2 = 1968-01-02"
+    , "1968-1-27 = 1968-01-27"
+    , "1968-1-28 = 1968-01-28"
+    , "1968-1-29 = 1968-01-29"
+    , "1968-1-30 = 1968-01-30"
+    , "1968-1-31 = 1968-01-31"
+    , "1968-1-32 = 1968-01-31"
+    , "1968-1-40 = 1968-01-31"
+    , "1968-2--7 = 1968-02-01"
+    , "1968-2--1 = 1968-02-01"
+    , "1968-2-0 = 1968-02-01"
+    , "1968-2-1 = 1968-02-01"
+    , "1968-2-2 = 1968-02-02"
+    , "1968-2-27 = 1968-02-27"
+    , "1968-2-28 = 1968-02-28"
+    , "1968-2-29 = 1968-02-29"
+    , "1968-2-30 = 1968-02-29"
+    , "1968-2-31 = 1968-02-29"
+    , "1968-2-32 = 1968-02-29"
+    , "1968-2-40 = 1968-02-29"
+    , "1968-12--7 = 1968-12-01"
+    , "1968-12--1 = 1968-12-01"
+    , "1968-12-0 = 1968-12-01"
+    , "1968-12-1 = 1968-12-01"
+    , "1968-12-2 = 1968-12-02"
+    , "1968-12-27 = 1968-12-27"
+    , "1968-12-28 = 1968-12-28"
+    , "1968-12-29 = 1968-12-29"
+    , "1968-12-30 = 1968-12-30"
+    , "1968-12-31 = 1968-12-31"
+    , "1968-12-32 = 1968-12-31"
+    , "1968-12-40 = 1968-12-31"
+    , "1968-13--7 = 1968-12-01"
+    , "1968-13--1 = 1968-12-01"
+    , "1968-13-0 = 1968-12-01"
+    , "1968-13-1 = 1968-12-01"
+    , "1968-13-2 = 1968-12-02"
+    , "1968-13-27 = 1968-12-27"
+    , "1968-13-28 = 1968-12-28"
+    , "1968-13-29 = 1968-12-29"
+    , "1968-13-30 = 1968-12-30"
+    , "1968-13-31 = 1968-12-31"
+    , "1968-13-32 = 1968-12-31"
+    , "1968-13-40 = 1968-12-31"
+    , "1968-17--7 = 1968-12-01"
+    , "1968-17--1 = 1968-12-01"
+    , "1968-17-0 = 1968-12-01"
+    , "1968-17-1 = 1968-12-01"
+    , "1968-17-2 = 1968-12-02"
+    , "1968-17-27 = 1968-12-27"
+    , "1968-17-28 = 1968-12-28"
+    , "1968-17-29 = 1968-12-29"
+    , "1968-17-30 = 1968-12-30"
+    , "1968-17-31 = 1968-12-31"
+    , "1968-17-32 = 1968-12-31"
+    , "1968-17-40 = 1968-12-31"
+    , "1969--20--7 = 1969-01-01"
+    , "1969--20--1 = 1969-01-01"
+    , "1969--20-0 = 1969-01-01"
+    , "1969--20-1 = 1969-01-01"
+    , "1969--20-2 = 1969-01-02"
+    , "1969--20-27 = 1969-01-27"
+    , "1969--20-28 = 1969-01-28"
+    , "1969--20-29 = 1969-01-29"
+    , "1969--20-30 = 1969-01-30"
+    , "1969--20-31 = 1969-01-31"
+    , "1969--20-32 = 1969-01-31"
+    , "1969--20-40 = 1969-01-31"
+    , "1969--1--7 = 1969-01-01"
+    , "1969--1--1 = 1969-01-01"
+    , "1969--1-0 = 1969-01-01"
+    , "1969--1-1 = 1969-01-01"
+    , "1969--1-2 = 1969-01-02"
+    , "1969--1-27 = 1969-01-27"
+    , "1969--1-28 = 1969-01-28"
+    , "1969--1-29 = 1969-01-29"
+    , "1969--1-30 = 1969-01-30"
+    , "1969--1-31 = 1969-01-31"
+    , "1969--1-32 = 1969-01-31"
+    , "1969--1-40 = 1969-01-31"
+    , "1969-0--7 = 1969-01-01"
+    , "1969-0--1 = 1969-01-01"
+    , "1969-0-0 = 1969-01-01"
+    , "1969-0-1 = 1969-01-01"
+    , "1969-0-2 = 1969-01-02"
+    , "1969-0-27 = 1969-01-27"
+    , "1969-0-28 = 1969-01-28"
+    , "1969-0-29 = 1969-01-29"
+    , "1969-0-30 = 1969-01-30"
+    , "1969-0-31 = 1969-01-31"
+    , "1969-0-32 = 1969-01-31"
+    , "1969-0-40 = 1969-01-31"
+    , "1969-1--7 = 1969-01-01"
+    , "1969-1--1 = 1969-01-01"
+    , "1969-1-0 = 1969-01-01"
+    , "1969-1-1 = 1969-01-01"
+    , "1969-1-2 = 1969-01-02"
+    , "1969-1-27 = 1969-01-27"
+    , "1969-1-28 = 1969-01-28"
+    , "1969-1-29 = 1969-01-29"
+    , "1969-1-30 = 1969-01-30"
+    , "1969-1-31 = 1969-01-31"
+    , "1969-1-32 = 1969-01-31"
+    , "1969-1-40 = 1969-01-31"
+    , "1969-2--7 = 1969-02-01"
+    , "1969-2--1 = 1969-02-01"
+    , "1969-2-0 = 1969-02-01"
+    , "1969-2-1 = 1969-02-01"
+    , "1969-2-2 = 1969-02-02"
+    , "1969-2-27 = 1969-02-27"
+    , "1969-2-28 = 1969-02-28"
+    , "1969-2-29 = 1969-02-28"
+    , "1969-2-30 = 1969-02-28"
+    , "1969-2-31 = 1969-02-28"
+    , "1969-2-32 = 1969-02-28"
+    , "1969-2-40 = 1969-02-28"
+    , "1969-12--7 = 1969-12-01"
+    , "1969-12--1 = 1969-12-01"
+    , "1969-12-0 = 1969-12-01"
+    , "1969-12-1 = 1969-12-01"
+    , "1969-12-2 = 1969-12-02"
+    , "1969-12-27 = 1969-12-27"
+    , "1969-12-28 = 1969-12-28"
+    , "1969-12-29 = 1969-12-29"
+    , "1969-12-30 = 1969-12-30"
+    , "1969-12-31 = 1969-12-31"
+    , "1969-12-32 = 1969-12-31"
+    , "1969-12-40 = 1969-12-31"
+    , "1969-13--7 = 1969-12-01"
+    , "1969-13--1 = 1969-12-01"
+    , "1969-13-0 = 1969-12-01"
+    , "1969-13-1 = 1969-12-01"
+    , "1969-13-2 = 1969-12-02"
+    , "1969-13-27 = 1969-12-27"
+    , "1969-13-28 = 1969-12-28"
+    , "1969-13-29 = 1969-12-29"
+    , "1969-13-30 = 1969-12-30"
+    , "1969-13-31 = 1969-12-31"
+    , "1969-13-32 = 1969-12-31"
+    , "1969-13-40 = 1969-12-31"
+    , "1969-17--7 = 1969-12-01"
+    , "1969-17--1 = 1969-12-01"
+    , "1969-17-0 = 1969-12-01"
+    , "1969-17-1 = 1969-12-01"
+    , "1969-17-2 = 1969-12-02"
+    , "1969-17-27 = 1969-12-27"
+    , "1969-17-28 = 1969-12-28"
+    , "1969-17-29 = 1969-12-29"
+    , "1969-17-30 = 1969-12-30"
+    , "1969-17-31 = 1969-12-31"
+    , "1969-17-32 = 1969-12-31"
+    , "1969-17-40 = 1969-12-31"
+    , "1971--20--7 = 1971-01-01"
+    , "1971--20--1 = 1971-01-01"
+    , "1971--20-0 = 1971-01-01"
+    , "1971--20-1 = 1971-01-01"
+    , "1971--20-2 = 1971-01-02"
+    , "1971--20-27 = 1971-01-27"
+    , "1971--20-28 = 1971-01-28"
+    , "1971--20-29 = 1971-01-29"
+    , "1971--20-30 = 1971-01-30"
+    , "1971--20-31 = 1971-01-31"
+    , "1971--20-32 = 1971-01-31"
+    , "1971--20-40 = 1971-01-31"
+    , "1971--1--7 = 1971-01-01"
+    , "1971--1--1 = 1971-01-01"
+    , "1971--1-0 = 1971-01-01"
+    , "1971--1-1 = 1971-01-01"
+    , "1971--1-2 = 1971-01-02"
+    , "1971--1-27 = 1971-01-27"
+    , "1971--1-28 = 1971-01-28"
+    , "1971--1-29 = 1971-01-29"
+    , "1971--1-30 = 1971-01-30"
+    , "1971--1-31 = 1971-01-31"
+    , "1971--1-32 = 1971-01-31"
+    , "1971--1-40 = 1971-01-31"
+    , "1971-0--7 = 1971-01-01"
+    , "1971-0--1 = 1971-01-01"
+    , "1971-0-0 = 1971-01-01"
+    , "1971-0-1 = 1971-01-01"
+    , "1971-0-2 = 1971-01-02"
+    , "1971-0-27 = 1971-01-27"
+    , "1971-0-28 = 1971-01-28"
+    , "1971-0-29 = 1971-01-29"
+    , "1971-0-30 = 1971-01-30"
+    , "1971-0-31 = 1971-01-31"
+    , "1971-0-32 = 1971-01-31"
+    , "1971-0-40 = 1971-01-31"
+    , "1971-1--7 = 1971-01-01"
+    , "1971-1--1 = 1971-01-01"
+    , "1971-1-0 = 1971-01-01"
+    , "1971-1-1 = 1971-01-01"
+    , "1971-1-2 = 1971-01-02"
+    , "1971-1-27 = 1971-01-27"
+    , "1971-1-28 = 1971-01-28"
+    , "1971-1-29 = 1971-01-29"
+    , "1971-1-30 = 1971-01-30"
+    , "1971-1-31 = 1971-01-31"
+    , "1971-1-32 = 1971-01-31"
+    , "1971-1-40 = 1971-01-31"
+    , "1971-2--7 = 1971-02-01"
+    , "1971-2--1 = 1971-02-01"
+    , "1971-2-0 = 1971-02-01"
+    , "1971-2-1 = 1971-02-01"
+    , "1971-2-2 = 1971-02-02"
+    , "1971-2-27 = 1971-02-27"
+    , "1971-2-28 = 1971-02-28"
+    , "1971-2-29 = 1971-02-28"
+    , "1971-2-30 = 1971-02-28"
+    , "1971-2-31 = 1971-02-28"
+    , "1971-2-32 = 1971-02-28"
+    , "1971-2-40 = 1971-02-28"
+    , "1971-12--7 = 1971-12-01"
+    , "1971-12--1 = 1971-12-01"
+    , "1971-12-0 = 1971-12-01"
+    , "1971-12-1 = 1971-12-01"
+    , "1971-12-2 = 1971-12-02"
+    , "1971-12-27 = 1971-12-27"
+    , "1971-12-28 = 1971-12-28"
+    , "1971-12-29 = 1971-12-29"
+    , "1971-12-30 = 1971-12-30"
+    , "1971-12-31 = 1971-12-31"
+    , "1971-12-32 = 1971-12-31"
+    , "1971-12-40 = 1971-12-31"
+    , "1971-13--7 = 1971-12-01"
+    , "1971-13--1 = 1971-12-01"
+    , "1971-13-0 = 1971-12-01"
+    , "1971-13-1 = 1971-12-01"
+    , "1971-13-2 = 1971-12-02"
+    , "1971-13-27 = 1971-12-27"
+    , "1971-13-28 = 1971-12-28"
+    , "1971-13-29 = 1971-12-29"
+    , "1971-13-30 = 1971-12-30"
+    , "1971-13-31 = 1971-12-31"
+    , "1971-13-32 = 1971-12-31"
+    , "1971-13-40 = 1971-12-31"
+    , "1971-17--7 = 1971-12-01"
+    , "1971-17--1 = 1971-12-01"
+    , "1971-17-0 = 1971-12-01"
+    , "1971-17-1 = 1971-12-01"
+    , "1971-17-2 = 1971-12-02"
+    , "1971-17-27 = 1971-12-27"
+    , "1971-17-28 = 1971-12-28"
+    , "1971-17-29 = 1971-12-29"
+    , "1971-17-30 = 1971-12-30"
+    , "1971-17-31 = 1971-12-31"
+    , "1971-17-32 = 1971-12-31"
+    , "1971-17-40 = 1971-12-31"
+    ]
+
+clipDatesISOWeekDayRef :: [String]
+clipDatesISOWeekDayRef =
+    [ "1968-W-20--2 = 1968-W01-1"
+    , "1968-W-20--1 = 1968-W01-1"
+    , "1968-W-20-0 = 1968-W01-1"
+    , "1968-W-20-1 = 1968-W01-1"
+    , "1968-W-20-4 = 1968-W01-4"
+    , "1968-W-20-6 = 1968-W01-6"
+    , "1968-W-20-7 = 1968-W01-7"
+    , "1968-W-20-8 = 1968-W01-7"
+    , "1968-W-20-9 = 1968-W01-7"
+    , "1968-W-1--2 = 1968-W01-1"
+    , "1968-W-1--1 = 1968-W01-1"
+    , "1968-W-1-0 = 1968-W01-1"
+    , "1968-W-1-1 = 1968-W01-1"
+    , "1968-W-1-4 = 1968-W01-4"
+    , "1968-W-1-6 = 1968-W01-6"
+    , "1968-W-1-7 = 1968-W01-7"
+    , "1968-W-1-8 = 1968-W01-7"
+    , "1968-W-1-9 = 1968-W01-7"
+    , "1968-W0--2 = 1968-W01-1"
+    , "1968-W0--1 = 1968-W01-1"
+    , "1968-W0-0 = 1968-W01-1"
+    , "1968-W0-1 = 1968-W01-1"
+    , "1968-W0-4 = 1968-W01-4"
+    , "1968-W0-6 = 1968-W01-6"
+    , "1968-W0-7 = 1968-W01-7"
+    , "1968-W0-8 = 1968-W01-7"
+    , "1968-W0-9 = 1968-W01-7"
+    , "1968-W1--2 = 1968-W01-1"
+    , "1968-W1--1 = 1968-W01-1"
+    , "1968-W1-0 = 1968-W01-1"
+    , "1968-W1-1 = 1968-W01-1"
+    , "1968-W1-4 = 1968-W01-4"
+    , "1968-W1-6 = 1968-W01-6"
+    , "1968-W1-7 = 1968-W01-7"
+    , "1968-W1-8 = 1968-W01-7"
+    , "1968-W1-9 = 1968-W01-7"
+    , "1968-W20--2 = 1968-W20-1"
+    , "1968-W20--1 = 1968-W20-1"
+    , "1968-W20-0 = 1968-W20-1"
+    , "1968-W20-1 = 1968-W20-1"
+    , "1968-W20-4 = 1968-W20-4"
+    , "1968-W20-6 = 1968-W20-6"
+    , "1968-W20-7 = 1968-W20-7"
+    , "1968-W20-8 = 1968-W20-7"
+    , "1968-W20-9 = 1968-W20-7"
+    , "1968-W51--2 = 1968-W51-1"
+    , "1968-W51--1 = 1968-W51-1"
+    , "1968-W51-0 = 1968-W51-1"
+    , "1968-W51-1 = 1968-W51-1"
+    , "1968-W51-4 = 1968-W51-4"
+    , "1968-W51-6 = 1968-W51-6"
+    , "1968-W51-7 = 1968-W51-7"
+    , "1968-W51-8 = 1968-W51-7"
+    , "1968-W51-9 = 1968-W51-7"
+    , "1968-W52--2 = 1968-W52-1"
+    , "1968-W52--1 = 1968-W52-1"
+    , "1968-W52-0 = 1968-W52-1"
+    , "1968-W52-1 = 1968-W52-1"
+    , "1968-W52-4 = 1968-W52-4"
+    , "1968-W52-6 = 1968-W52-6"
+    , "1968-W52-7 = 1968-W52-7"
+    , "1968-W52-8 = 1968-W52-7"
+    , "1968-W52-9 = 1968-W52-7"
+    , "1968-W53--2 = 1968-W52-1"
+    , "1968-W53--1 = 1968-W52-1"
+    , "1968-W53-0 = 1968-W52-1"
+    , "1968-W53-1 = 1968-W52-1"
+    , "1968-W53-4 = 1968-W52-4"
+    , "1968-W53-6 = 1968-W52-6"
+    , "1968-W53-7 = 1968-W52-7"
+    , "1968-W53-8 = 1968-W52-7"
+    , "1968-W53-9 = 1968-W52-7"
+    , "1968-W54--2 = 1968-W52-1"
+    , "1968-W54--1 = 1968-W52-1"
+    , "1968-W54-0 = 1968-W52-1"
+    , "1968-W54-1 = 1968-W52-1"
+    , "1968-W54-4 = 1968-W52-4"
+    , "1968-W54-6 = 1968-W52-6"
+    , "1968-W54-7 = 1968-W52-7"
+    , "1968-W54-8 = 1968-W52-7"
+    , "1968-W54-9 = 1968-W52-7"
+    , "1969-W-20--2 = 1969-W01-1"
+    , "1969-W-20--1 = 1969-W01-1"
+    , "1969-W-20-0 = 1969-W01-1"
+    , "1969-W-20-1 = 1969-W01-1"
+    , "1969-W-20-4 = 1969-W01-4"
+    , "1969-W-20-6 = 1969-W01-6"
+    , "1969-W-20-7 = 1969-W01-7"
+    , "1969-W-20-8 = 1969-W01-7"
+    , "1969-W-20-9 = 1969-W01-7"
+    , "1969-W-1--2 = 1969-W01-1"
+    , "1969-W-1--1 = 1969-W01-1"
+    , "1969-W-1-0 = 1969-W01-1"
+    , "1969-W-1-1 = 1969-W01-1"
+    , "1969-W-1-4 = 1969-W01-4"
+    , "1969-W-1-6 = 1969-W01-6"
+    , "1969-W-1-7 = 1969-W01-7"
+    , "1969-W-1-8 = 1969-W01-7"
+    , "1969-W-1-9 = 1969-W01-7"
+    , "1969-W0--2 = 1969-W01-1"
+    , "1969-W0--1 = 1969-W01-1"
+    , "1969-W0-0 = 1969-W01-1"
+    , "1969-W0-1 = 1969-W01-1"
+    , "1969-W0-4 = 1969-W01-4"
+    , "1969-W0-6 = 1969-W01-6"
+    , "1969-W0-7 = 1969-W01-7"
+    , "1969-W0-8 = 1969-W01-7"
+    , "1969-W0-9 = 1969-W01-7"
+    , "1969-W1--2 = 1969-W01-1"
+    , "1969-W1--1 = 1969-W01-1"
+    , "1969-W1-0 = 1969-W01-1"
+    , "1969-W1-1 = 1969-W01-1"
+    , "1969-W1-4 = 1969-W01-4"
+    , "1969-W1-6 = 1969-W01-6"
+    , "1969-W1-7 = 1969-W01-7"
+    , "1969-W1-8 = 1969-W01-7"
+    , "1969-W1-9 = 1969-W01-7"
+    , "1969-W20--2 = 1969-W20-1"
+    , "1969-W20--1 = 1969-W20-1"
+    , "1969-W20-0 = 1969-W20-1"
+    , "1969-W20-1 = 1969-W20-1"
+    , "1969-W20-4 = 1969-W20-4"
+    , "1969-W20-6 = 1969-W20-6"
+    , "1969-W20-7 = 1969-W20-7"
+    , "1969-W20-8 = 1969-W20-7"
+    , "1969-W20-9 = 1969-W20-7"
+    , "1969-W51--2 = 1969-W51-1"
+    , "1969-W51--1 = 1969-W51-1"
+    , "1969-W51-0 = 1969-W51-1"
+    , "1969-W51-1 = 1969-W51-1"
+    , "1969-W51-4 = 1969-W51-4"
+    , "1969-W51-6 = 1969-W51-6"
+    , "1969-W51-7 = 1969-W51-7"
+    , "1969-W51-8 = 1969-W51-7"
+    , "1969-W51-9 = 1969-W51-7"
+    , "1969-W52--2 = 1969-W52-1"
+    , "1969-W52--1 = 1969-W52-1"
+    , "1969-W52-0 = 1969-W52-1"
+    , "1969-W52-1 = 1969-W52-1"
+    , "1969-W52-4 = 1969-W52-4"
+    , "1969-W52-6 = 1969-W52-6"
+    , "1969-W52-7 = 1969-W52-7"
+    , "1969-W52-8 = 1969-W52-7"
+    , "1969-W52-9 = 1969-W52-7"
+    , "1969-W53--2 = 1969-W52-1"
+    , "1969-W53--1 = 1969-W52-1"
+    , "1969-W53-0 = 1969-W52-1"
+    , "1969-W53-1 = 1969-W52-1"
+    , "1969-W53-4 = 1969-W52-4"
+    , "1969-W53-6 = 1969-W52-6"
+    , "1969-W53-7 = 1969-W52-7"
+    , "1969-W53-8 = 1969-W52-7"
+    , "1969-W53-9 = 1969-W52-7"
+    , "1969-W54--2 = 1969-W52-1"
+    , "1969-W54--1 = 1969-W52-1"
+    , "1969-W54-0 = 1969-W52-1"
+    , "1969-W54-1 = 1969-W52-1"
+    , "1969-W54-4 = 1969-W52-4"
+    , "1969-W54-6 = 1969-W52-6"
+    , "1969-W54-7 = 1969-W52-7"
+    , "1969-W54-8 = 1969-W52-7"
+    , "1969-W54-9 = 1969-W52-7"
+    , "2004-W-20--2 = 2004-W01-1"
+    , "2004-W-20--1 = 2004-W01-1"
+    , "2004-W-20-0 = 2004-W01-1"
+    , "2004-W-20-1 = 2004-W01-1"
+    , "2004-W-20-4 = 2004-W01-4"
+    , "2004-W-20-6 = 2004-W01-6"
+    , "2004-W-20-7 = 2004-W01-7"
+    , "2004-W-20-8 = 2004-W01-7"
+    , "2004-W-20-9 = 2004-W01-7"
+    , "2004-W-1--2 = 2004-W01-1"
+    , "2004-W-1--1 = 2004-W01-1"
+    , "2004-W-1-0 = 2004-W01-1"
+    , "2004-W-1-1 = 2004-W01-1"
+    , "2004-W-1-4 = 2004-W01-4"
+    , "2004-W-1-6 = 2004-W01-6"
+    , "2004-W-1-7 = 2004-W01-7"
+    , "2004-W-1-8 = 2004-W01-7"
+    , "2004-W-1-9 = 2004-W01-7"
+    , "2004-W0--2 = 2004-W01-1"
+    , "2004-W0--1 = 2004-W01-1"
+    , "2004-W0-0 = 2004-W01-1"
+    , "2004-W0-1 = 2004-W01-1"
+    , "2004-W0-4 = 2004-W01-4"
+    , "2004-W0-6 = 2004-W01-6"
+    , "2004-W0-7 = 2004-W01-7"
+    , "2004-W0-8 = 2004-W01-7"
+    , "2004-W0-9 = 2004-W01-7"
+    , "2004-W1--2 = 2004-W01-1"
+    , "2004-W1--1 = 2004-W01-1"
+    , "2004-W1-0 = 2004-W01-1"
+    , "2004-W1-1 = 2004-W01-1"
+    , "2004-W1-4 = 2004-W01-4"
+    , "2004-W1-6 = 2004-W01-6"
+    , "2004-W1-7 = 2004-W01-7"
+    , "2004-W1-8 = 2004-W01-7"
+    , "2004-W1-9 = 2004-W01-7"
+    , "2004-W20--2 = 2004-W20-1"
+    , "2004-W20--1 = 2004-W20-1"
+    , "2004-W20-0 = 2004-W20-1"
+    , "2004-W20-1 = 2004-W20-1"
+    , "2004-W20-4 = 2004-W20-4"
+    , "2004-W20-6 = 2004-W20-6"
+    , "2004-W20-7 = 2004-W20-7"
+    , "2004-W20-8 = 2004-W20-7"
+    , "2004-W20-9 = 2004-W20-7"
+    , "2004-W51--2 = 2004-W51-1"
+    , "2004-W51--1 = 2004-W51-1"
+    , "2004-W51-0 = 2004-W51-1"
+    , "2004-W51-1 = 2004-W51-1"
+    , "2004-W51-4 = 2004-W51-4"
+    , "2004-W51-6 = 2004-W51-6"
+    , "2004-W51-7 = 2004-W51-7"
+    , "2004-W51-8 = 2004-W51-7"
+    , "2004-W51-9 = 2004-W51-7"
+    , "2004-W52--2 = 2004-W52-1"
+    , "2004-W52--1 = 2004-W52-1"
+    , "2004-W52-0 = 2004-W52-1"
+    , "2004-W52-1 = 2004-W52-1"
+    , "2004-W52-4 = 2004-W52-4"
+    , "2004-W52-6 = 2004-W52-6"
+    , "2004-W52-7 = 2004-W52-7"
+    , "2004-W52-8 = 2004-W52-7"
+    , "2004-W52-9 = 2004-W52-7"
+    , "2004-W53--2 = 2004-W53-1"
+    , "2004-W53--1 = 2004-W53-1"
+    , "2004-W53-0 = 2004-W53-1"
+    , "2004-W53-1 = 2004-W53-1"
+    , "2004-W53-4 = 2004-W53-4"
+    , "2004-W53-6 = 2004-W53-6"
+    , "2004-W53-7 = 2004-W53-7"
+    , "2004-W53-8 = 2004-W53-7"
+    , "2004-W53-9 = 2004-W53-7"
+    , "2004-W54--2 = 2004-W53-1"
+    , "2004-W54--1 = 2004-W53-1"
+    , "2004-W54-0 = 2004-W53-1"
+    , "2004-W54-1 = 2004-W53-1"
+    , "2004-W54-4 = 2004-W53-4"
+    , "2004-W54-6 = 2004-W53-6"
+    , "2004-W54-7 = 2004-W53-7"
+    , "2004-W54-8 = 2004-W53-7"
+    , "2004-W54-9 = 2004-W53-7"
+    ]
diff --git a/test/main/Test/Calendar/ConvertBack.hs b/test/main/Test/Calendar/ConvertBack.hs
--- a/test/main/Test/Calendar/ConvertBack.hs
+++ b/test/main/Test/Calendar/ConvertBack.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.ConvertBack
-    ( convertBack
-    ) where
+module Test.Calendar.ConvertBack (
+    convertBack,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.Julian
@@ -9,20 +9,22 @@
 import Test.Tasty
 import Test.Tasty.HUnit
 
-checkDay :: (Show t) => (Day -> t) -> (t -> Day) -> (t -> Maybe Day) -> Day -> String
-checkDay encodeDay decodeDay decodeDayValid day = let
-    st = encodeDay day
-    day' = decodeDay st
-    mday' = decodeDayValid st
-    a =
-        if day /= day'
-            then unwords [show day, "-> ", show st, "-> ", show day', "(diff", show (diffDays day' day) ++ ")"]
-            else ""
-    b =
-        if Just day /= mday'
-            then unwords [show day, "->", show st, "->", show mday']
-            else ""
-    in a ++ b
+checkDay :: Show t => (Day -> t) -> (t -> Day) -> (t -> Maybe Day) -> Day -> String
+checkDay encodeDay decodeDay decodeDayValid day =
+    let
+        st = encodeDay day
+        day' = decodeDay st
+        mday' = decodeDayValid st
+        a =
+            if day /= day'
+                then unwords [show day, "-> ", show st, "-> ", show day', "(diff", show (diffDays day' day) ++ ")"]
+                else ""
+        b =
+            if Just day /= mday'
+                then unwords [show day, "->", show st, "->", show mday']
+                else ""
+    in
+        a ++ b
 
 checkers :: [Day -> String]
 checkers =
diff --git a/test/main/Test/Calendar/DayPeriod.hs b/test/main/Test/Calendar/DayPeriod.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/Calendar/DayPeriod.hs
@@ -0,0 +1,181 @@
+module Test.Calendar.DayPeriod (
+    testDayPeriod,
+) where
+
+import Data.Time.Calendar
+import Data.Time.Calendar.Month
+import Data.Time.Calendar.Quarter
+import Test.Arbitrary ()
+import Test.Tasty
+import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
+
+newtype WDay = MkWDay Day
+    deriving (Eq, Show)
+
+instance Arbitrary WDay where
+    arbitrary = do
+        (MkWYear y) <- arbitrary
+        (MkWMonthOfYear m) <- arbitrary
+        (MkWDayOfMonth d) <- arbitrary
+        pure $ MkWDay $ YearMonthDay y m d
+
+newtype WYear = MkWYear Year
+    deriving (Eq, Show)
+
+instance Arbitrary WYear where
+    arbitrary = fmap MkWYear $ choose (-1000, 3000)
+
+newtype WMonthOfYear = MkWMonthOfYear MonthOfYear
+    deriving (Eq, Show)
+
+instance Arbitrary WMonthOfYear where
+    arbitrary = fmap MkWMonthOfYear $ choose (-5, 17)
+
+newtype WMonth = MkWMonth Month
+    deriving (Eq, Show)
+
+instance Arbitrary WMonth where
+    arbitrary = do
+        (MkWYear y) <- arbitrary
+        (MkWMonthOfYear m) <- arbitrary
+        pure $ MkWMonth $ YearMonth y m
+
+newtype WDayOfMonth = MkWDayOfMonth DayOfMonth
+    deriving (Eq, Show)
+
+instance Arbitrary WDayOfMonth where
+    arbitrary = fmap MkWDayOfMonth $ choose (-5, 35)
+
+newtype WQuarterOfYear = MkWQuarterOfYear QuarterOfYear
+    deriving (Eq, Show)
+
+instance Arbitrary WQuarterOfYear where
+    arbitrary = fmap MkWQuarterOfYear $ elements [Q1 .. Q4]
+
+newtype WQuarter = MkWQuarter Quarter
+    deriving (Eq, Show)
+
+instance Arbitrary WQuarter where
+    arbitrary = do
+        (MkWYear y) <- arbitrary
+        (MkWQuarterOfYear q) <- arbitrary
+        pure $ MkWQuarter $ YearQuarter y q
+
+testDayPeriod :: TestTree
+testDayPeriod =
+    testGroup
+        "DayPeriod"
+        [ testGroup "Day" testDay
+        , testGroup "Month" testMonth
+        , testGroup "Quarter" testQuarter
+        , testGroup "Year" testYear
+        , testGroup "Week" testWeek
+        ]
+
+testDay :: [TestTree]
+testDay =
+    [ testProperty "periodFirstDay" $ \(MkWDay d) ->
+        periodFirstDay d == d
+    , testProperty "periodLastDay" $ \(MkWDay d) ->
+        periodLastDay d == d
+    , testProperty "dayPeriod" $ \(MkWDay d) ->
+        dayPeriod d == d
+    , testProperty "periodAllDays" $ \(MkWDay d) ->
+        periodAllDays d == [d]
+    , testProperty "periodLength" $ \(MkWDay d) ->
+        periodLength d == 1
+    ]
+
+testMonth :: [TestTree]
+testMonth =
+    [ testProperty "periodFirstDay" $ \(MkWMonth my@(YearMonth y m)) ->
+        periodFirstDay my == YearMonthDay y m 1
+    , testGroup
+        "periodLastDay"
+        [ testCase "leap year" $
+            periodLastDay (YearMonth 2024 February) @?= YearMonthDay 2024 February 29
+        , testCase "regular year" $
+            periodLastDay (YearMonth 2023 February) @?= YearMonthDay 2023 February 28
+        ]
+    , testProperty "dayPeriod" $ \(MkWMonth my@(YearMonth y m), MkWDayOfMonth d) ->
+        dayPeriod (YearMonthDay y m d) == my
+    , testProperty "periodAllDays" $ \(MkWMonth my@(YearMonth y1 m1)) ->
+        all (== (y1, m1)) $ map (\(YearMonthDay y2 m2 _) -> (y2, m2)) $ periodAllDays my
+    , testGroup
+        "periodLength"
+        [ testProperty "property tests" $ \(MkWMonth my) ->
+            periodLength my >= 28
+        , testCase "leap year" $
+            periodLength (YearMonth 2024 February) @?= 29
+        , testCase "regular year" $
+            periodLength (YearMonth 2023 February) @?= 28
+        ]
+    ]
+
+testQuarter :: [TestTree]
+testQuarter =
+    [ testGroup
+        "periodFirstDay"
+        [ testProperty "Q1" $ \(MkWYear y) ->
+            periodFirstDay (YearQuarter y Q1) == YearMonthDay y January 1
+        , testProperty "Q2" $ \(MkWYear y) ->
+            periodFirstDay (YearQuarter y Q2) == YearMonthDay y April 1
+        , testProperty "Q3" $ \(MkWYear y) ->
+            periodFirstDay (YearQuarter y Q3) == YearMonthDay y July 1
+        , testProperty "Q4" $ \(MkWYear y) ->
+            periodFirstDay (YearQuarter y Q4) == YearMonthDay y October 1
+        ]
+    , testGroup
+        "periodLastDay"
+        [ testProperty "Q1" $ \(MkWYear y) ->
+            periodLastDay (YearQuarter y Q1) == YearMonthDay y March 31
+        , testProperty "Q2" $ \(MkWYear y) ->
+            periodLastDay (YearQuarter y Q2) == YearMonthDay y June 30
+        , testProperty "Q3" $ \(MkWYear y) ->
+            periodLastDay (YearQuarter y Q3) == YearMonthDay y September 30
+        , testProperty "Q4" $ \(MkWYear y) ->
+            periodLastDay (YearQuarter y Q4) == YearMonthDay y December 31
+        ]
+    , testProperty "dayPeriod" $ \(MkWMonth my@(YearMonth y m), MkWDayOfMonth d) ->
+        dayPeriod (YearMonthDay y m d) == monthQuarter my
+    , testProperty "periodAllDays" $ \(MkWQuarter q) ->
+        all (== q) $ map dayQuarter $ periodAllDays q
+    , testProperty "periodLength" $ \(MkWQuarter q) ->
+        periodLength q >= 90
+    ]
+
+testYear :: [TestTree]
+testYear =
+    [ testProperty "periodFirstDay" $ \(MkWYear y) ->
+        periodFirstDay y == YearMonthDay y January 1
+    , testProperty "periodLastDay" $ \(MkWYear y) ->
+        periodLastDay y == YearMonthDay y December 31
+    , testProperty "dayPeriod" $ \(MkWYear y, MkWMonthOfYear m, MkWDayOfMonth d) ->
+        dayPeriod (YearMonthDay y m d) == y
+    , testProperty "periodAllDays" $ \(MkWYear y1) ->
+        all (== y1) $ map (\(YearMonthDay y2 _ _) -> y2) $ periodAllDays y1
+    , testProperty "periodLength" $ \(MkWYear y) ->
+        periodLength y >= 365
+    ]
+
+testWeek :: [TestTree]
+testWeek =
+    [ testProperty "weekFirstDay/weekLastDay range" $ \dw (MkWDay d) ->
+        let
+            f = weekFirstDay dw d
+            l = weekLastDay dw d
+        in
+            f <= d && d <= l
+    , testProperty "weekFirstDay/weekLastDay range" $ \dw (MkWDay d) ->
+        let
+            f = weekFirstDay dw d
+            l = weekLastDay dw d
+        in
+            addDays 6 f == l
+    , testProperty "weekFirstDay dayOfWeek" $ \dw (MkWDay d) ->
+        let
+            f = weekFirstDay dw d
+        in
+            dayOfWeek f == dw
+    ]
diff --git a/test/main/Test/Calendar/Duration.hs b/test/main/Test/Calendar/Duration.hs
--- a/test/main/Test/Calendar/Duration.hs
+++ b/test/main/Test/Calendar/Duration.hs
@@ -1,46 +1,106 @@
-module Test.Calendar.Duration
-    ( testDuration
-    ) where
+module Test.Calendar.Duration (
+    testDuration,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.Julian
+import Test.AddDiff
 import Test.Arbitrary ()
 import Test.Tasty
 import Test.Tasty.HUnit
 import Test.Tasty.QuickCheck hiding (reason)
 
-testAddDiff :: TestTree
-testAddDiff =
+type CalendarAddDiff = (AddDiff CalendarDiffDays Day, Integer -> Int -> Int -> Day)
+
+gregorianClip :: CalendarAddDiff
+gregorianClip = (MkAddDiff "gregorianClip" addGregorianDurationClip diffGregorianDurationClip, fromGregorian)
+
+gregorianRollOver :: CalendarAddDiff
+gregorianRollOver = (MkAddDiff "gregorianRollOver" addGregorianDurationRollOver diffGregorianDurationRollOver, fromGregorian)
+
+julianClip :: CalendarAddDiff
+julianClip = (MkAddDiff "julianClip" addJulianDurationClip diffJulianDurationClip, fromJulian)
+
+julianRollOver :: CalendarAddDiff
+julianRollOver = (MkAddDiff "julianRollOver" addJulianDurationRollOver diffJulianDurationRollOver, fromJulian)
+
+addDiffs :: [CalendarAddDiff]
+addDiffs =
+    [ gregorianClip
+    , gregorianRollOver
+    , julianClip
+    , julianRollOver
+    ]
+
+testAddDiffs :: TestTree
+testAddDiffs =
     testGroup
-        "add diff"
-        [ testProperty "add diff GregorianDurationClip" $ \day1 day2 ->
-              addGregorianDurationClip (diffGregorianDurationClip day2 day1) day1 == day2
-        , testProperty "add diff GregorianDurationRollOver" $ \day1 day2 ->
-              addGregorianDurationRollOver (diffGregorianDurationRollOver day2 day1) day1 == day2
-        , testProperty "add diff JulianDurationClip" $ \day1 day2 ->
-              addJulianDurationClip (diffJulianDurationClip day2 day1) day1 == day2
-        , testProperty "add diff JulianDurationRollOver" $ \day1 day2 ->
-              addJulianDurationRollOver (diffJulianDurationRollOver day2 day1) day1 == day2
-        ]
+        "add-diff"
+        $ fmap (testAddDiff . fst) addDiffs
 
-testClip :: (Integer, Int, Int) -> (Integer, Int, Int) -> (Integer, Integer) -> TestTree
-testClip (y1, m1, d1) (y2, m2, d2) (em, ed) = let
-    day1 = fromGregorian y1 m1 d1
-    day2 = fromGregorian y2 m2 d2
-    expected = CalendarDiffDays em ed
-    found = diffGregorianDurationClip day1 day2
-    in testCase (show day1 ++ " - " ++ show day2) $ assertEqual "" expected found
+newtype Smallish = MkSmallish Integer deriving (Eq, Ord)
 
-testDiffs :: TestTree
-testDiffs =
+deriving newtype instance Show Smallish
+
+instance Arbitrary Smallish where
+    arbitrary = do
+        b <- arbitrary
+        n <- if b then choose (0, 60) else return 30
+        return $ MkSmallish n
+
+testPositiveDiff :: CalendarAddDiff -> TestTree
+testPositiveDiff (MkAddDiff{..}, _) = testProperty adName $ \day1 (MkSmallish i) ->
+    let
+        day2 = addDays i day1
+        r = adDifference day2 day1
+    in
+        property $ cdMonths r >= 0 && cdDays r >= 0
+
+testPositiveDiffs :: TestTree
+testPositiveDiffs =
     testGroup
-        "diffs"
-        [ testClip (2017, 04, 07) (2017, 04, 07) (0, 0)
-        , testClip (2017, 04, 07) (2017, 04, 01) (0, 6)
-        , testClip (2017, 04, 01) (2017, 04, 07) (0, -6)
-        , testClip (2017, 04, 07) (2017, 02, 01) (2, 6)
-        , testClip (2017, 02, 01) (2017, 04, 07) (-2, -6)
+        "positive-diff"
+        $ fmap testPositiveDiff addDiffs
+
+testSpecific :: CalendarAddDiff -> (Integer, Int, Int) -> (Integer, Int, Int) -> (Integer, Integer) -> TestTree
+testSpecific (MkAddDiff{..}, fromYMD) (y2, m2, d2) (y1, m1, d1) (em, ed) =
+    let
+        day1 = fromYMD y1 m1 d1
+        day2 = fromYMD y2 m2 d2
+        expected = CalendarDiffDays em ed
+        found = adDifference day2 day1
+    in
+        testCase (adName ++ ": " ++ show day2 ++ " - " ++ show day1) $ do
+            assertEqual "add" day2 $ adAdd found day1
+            assertEqual "diff" expected found
+
+testSpecificPair :: (Integer, Int, Int) -> (Integer, Int, Int) -> (Integer, Integer) -> (Integer, Integer) -> TestTree
+testSpecificPair day2 day1 clipD rollD =
+    testGroup
+        (show day2 ++ " - " ++ show day1)
+        [ testSpecific gregorianClip day2 day1 clipD
+        , testSpecific gregorianRollOver day2 day1 rollD
+        , testSpecific julianClip day2 day1 clipD
+        , testSpecific julianRollOver day2 day1 rollD
         ]
 
+testSpecifics :: TestTree
+testSpecifics =
+    testGroup
+        "specific"
+        [ testSpecificPair (2017, 04, 07) (2017, 04, 07) (0, 0) (0, 0)
+        , testSpecific gregorianClip (2017, 04, 07) (2017, 04, 01) (0, 6)
+        , testSpecific gregorianClip (2017, 04, 01) (2017, 04, 07) (0, -6)
+        , testSpecific gregorianClip (2017, 04, 07) (2017, 02, 01) (2, 6)
+        , testSpecific gregorianClip (2017, 02, 01) (2017, 04, 07) (-2, -6)
+        , testSpecificPair (2000, 03, 01) (2000, 01, 30) (1, 1) (1, 0)
+        , testSpecificPair (2001, 03, 01) (2001, 01, 30) (1, 1) (0, 30)
+        , testSpecificPair (2001, 03, 01) (2000, 01, 30) (13, 1) (12, 30)
+        , testSpecificPair (2000, 03, 01) (2000, 01, 31) (1, 1) (0, 30)
+        , testSpecificPair (2001, 03, 01) (2001, 01, 31) (1, 1) (0, 29)
+        , testSpecificPair (2001, 03, 01) (2000, 01, 31) (13, 1) (12, 29)
+        , testSpecificPair (2001, 10, 01) (2001, 08, 31) (1, 1) (1, 0)
+        ]
+
 testDuration :: TestTree
-testDuration = testGroup "CalendarDiffDays" [testAddDiff, testDiffs]
+testDuration = testGroup "CalendarDiffDays" [testAddDiffs, testPositiveDiffs, testSpecifics]
diff --git a/test/main/Test/Calendar/Easter.hs b/test/main/Test/Calendar/Easter.hs
--- a/test/main/Test/Calendar/Easter.hs
+++ b/test/main/Test/Calendar/Easter.hs
@@ -1,11 +1,10 @@
-module Test.Calendar.Easter
-    ( testEaster
-    ) where
+module Test.Calendar.Easter (
+    testEaster,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.Easter
 import Data.Time.Format
-
 import Test.Calendar.EasterRef
 import Test.Tasty
 import Test.Tasty.HUnit
@@ -19,20 +18,22 @@
 
 testEaster :: TestTree
 testEaster =
-    testCase "testEaster" $ let
-        ds = unlines $ map (\day -> unwords [showWithWDay day, "->", showWithWDay (sundayAfter day)]) days
-        f y =
-            unwords
-                [ show y ++ ", Gregorian: moon,"
-                , show (gregorianPaschalMoon y) ++ ": Easter,"
-                , showWithWDay (gregorianEaster y)
-                ] ++
-            "\n"
-        g y =
-            unwords
-                [ show y ++ ", Orthodox : moon,"
-                , show (orthodoxPaschalMoon y) ++ ": Easter,"
-                , showWithWDay (orthodoxEaster y)
-                ] ++
-            "\n"
-        in assertEqual "" testEasterRef $ ds ++ concatMap (\y -> f y ++ g y) [2000 .. 2020]
+    testCase "testEaster" $
+        let
+            ds = unlines $ map (\day -> unwords [showWithWDay day, "->", showWithWDay (sundayAfter day)]) days
+            f y =
+                unwords
+                    [ show y ++ ", Gregorian: moon,"
+                    , show (gregorianPaschalMoon y) ++ ": Easter,"
+                    , showWithWDay (gregorianEaster y)
+                    ]
+                    ++ "\n"
+            g y =
+                unwords
+                    [ show y ++ ", Orthodox : moon,"
+                    , show (orthodoxPaschalMoon y) ++ ": Easter,"
+                    , showWithWDay (orthodoxEaster y)
+                    ]
+                    ++ "\n"
+        in
+            assertEqual "" testEasterRef $ ds ++ concatMap (\y -> f y ++ g y) [2000 .. 2020]
diff --git a/test/main/Test/Calendar/LongWeekYears.hs b/test/main/Test/Calendar/LongWeekYears.hs
--- a/test/main/Test/Calendar/LongWeekYears.hs
+++ b/test/main/Test/Calendar/LongWeekYears.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.LongWeekYears
-    ( longWeekYears
-    ) where
+module Test.Calendar.LongWeekYears (
+    longWeekYears,
+) where
 
 import Data.Time.Calendar
 import Data.Time.Calendar.WeekDate
@@ -18,12 +18,14 @@
 showLongYear year =
     unwords
         [ show year ++ ":"
-        , (if isLeapYear year
-               then "L"
-               else " ") ++
-          (if longYear year
-               then "*"
-               else " ")
+        , ( if isLeapYear year
+                then "L"
+                else " "
+          )
+            ++ ( if longYear year
+                    then "*"
+                    else " "
+               )
         ]
 
 longWeekYears :: TestTree
diff --git a/test/main/Test/Calendar/MonthDay.hs b/test/main/Test/Calendar/MonthDay.hs
--- a/test/main/Test/Calendar/MonthDay.hs
+++ b/test/main/Test/Calendar/MonthDay.hs
@@ -1,7 +1,9 @@
-module Test.Calendar.MonthDay
-    ( testMonthDay
-    ) where
+module Test.Calendar.MonthDay (
+    testMonthDay,
+) where
 
+import Data.Time.Calendar
+import Data.Time.Calendar.Month
 import Data.Time.Calendar.MonthDay
 import Test.Calendar.MonthDayRef
 import Test.Tasty
@@ -14,8 +16,23 @@
 
 testMonthDay :: TestTree
 testMonthDay =
-    testCase "testMonthDay" $
-    assertEqual "" testMonthDayRef $ concat $ map (\isL -> unlines (leap isL : yearDays isL)) [False, True]
+    testGroup
+        "MonthDay"
+        [ testCase "good" $
+            assertEqual "" testMonthDayRef $
+                concat $
+                    map (\isL -> unlines (leap isL : yearDays isL)) [False, True]
+        , testGroup
+            "clip"
+            [ testCase "12" $ assertEqual "" (YearMonthDay 2005 05 12) (MonthDay (MkMonth 24064) 12)
+            , testCase "1" $ assertEqual "" (YearMonthDay 2005 05 1) (MonthDay (MkMonth 24064) 1)
+            , testCase "0" $ assertEqual "" (YearMonthDay 2005 05 1) (MonthDay (MkMonth 24064) 0)
+            , testCase "-1" $ assertEqual "" (YearMonthDay 2005 05 1) (MonthDay (MkMonth 24064) (-1))
+            , testCase "31" $ assertEqual "" (YearMonthDay 2005 05 31) (MonthDay (MkMonth 24064) 31)
+            , testCase "32" $ assertEqual "" (YearMonthDay 2005 05 31) (MonthDay (MkMonth 24064) 32)
+            , testCase "33" $ assertEqual "" (YearMonthDay 2005 05 31) (MonthDay (MkMonth 24064) 33)
+            ]
+        ]
   where
     leap isLeap =
         if isLeap
@@ -23,9 +40,12 @@
             else "Regular:"
     yearDays isLeap =
         map
-            (\yd -> let
-                 (m, d) = dayOfYearToMonthAndDay isLeap yd
-                 yd' = monthAndDayToDayOfYear isLeap m d
-                 mdtext = show m ++ "-" ++ show d
-                 in showCompare yd mdtext yd')
+            ( \yd ->
+                let
+                    (m, d) = dayOfYearToMonthAndDay isLeap yd
+                    yd' = monthAndDayToDayOfYear isLeap m d
+                    mdtext = show m ++ "-" ++ show d
+                in
+                    showCompare yd mdtext yd'
+            )
             [-2 .. 369]
diff --git a/test/main/Test/Calendar/MonthOfYear.hs b/test/main/Test/Calendar/MonthOfYear.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/Calendar/MonthOfYear.hs
@@ -0,0 +1,26 @@
+module Test.Calendar.MonthOfYear (
+    testMonthOfYear,
+) where
+
+import Data.Foldable
+import Data.Time.Calendar
+import Test.Tasty
+import Test.Tasty.HUnit
+
+matchMonthOfYear :: MonthOfYear -> Int
+matchMonthOfYear m = case m of
+    January -> 1
+    February -> 2
+    March -> 3
+    April -> 4
+    May -> 5
+    June -> 6
+    July -> 7
+    August -> 8
+    September -> 9
+    October -> 10
+    November -> 11
+    December -> 12
+
+testMonthOfYear :: TestTree
+testMonthOfYear = testCase "MonthOfYear" $ for_ [1 .. 12] $ \m -> assertEqual (show m) m $ matchMonthOfYear m
diff --git a/test/main/Test/Calendar/Valid.hs b/test/main/Test/Calendar/Valid.hs
--- a/test/main/Test/Calendar/Valid.hs
+++ b/test/main/Test/Calendar/Valid.hs
@@ -1,6 +1,6 @@
-module Test.Calendar.Valid
-    ( testValid
-    ) where
+module Test.Calendar.Valid (
+    testValid,
+) where
 
 import Data.Time
 import Data.Time.Calendar.Julian
@@ -11,39 +11,47 @@
 import Test.Tasty.QuickCheck hiding (reason)
 
 validResult :: (Eq c, Show c, Eq t, Show t) => (s -> c) -> Bool -> (t -> c) -> (c -> t) -> (c -> Maybe t) -> s -> Result
-validResult sc valid toComponents fromComponents fromComponentsValid s = let
-    c = sc s
-    mt = fromComponentsValid c
-    t' = fromComponents c
-    c' = toComponents t'
-    in if valid
-           then case mt of
-                    Nothing -> rejected
-                    Just t ->
-                        if t' /= t
-                            then failed {reason = "'fromValid' gives " ++ show t ++ ", but 'from' gives " ++ show t'}
-                            else if c' /= c
-                                     then failed
-                                              { reason =
-                                                    "found valid, but converts " ++
-                                                    show c ++ " -> " ++ show t' ++ " -> " ++ show c'
-                                              }
-                                     else succeeded
-           else case mt of
-                    Nothing ->
-                        if c' /= c
-                            then succeeded
-                            else failed {reason = show c ++ " found invalid, but converts with " ++ show t'}
-                    Just _ -> rejected
+validResult sc valid toComponents fromComponents fromComponentsValid s =
+    let
+        c = sc s
+        mt = fromComponentsValid c
+        t' = fromComponents c
+        c' = toComponents t'
+    in
+        if valid
+            then case mt of
+                Nothing -> rejected
+                Just t ->
+                    if t' /= t
+                        then failed{reason = "'fromValid' gives " ++ show t ++ ", but 'from' gives " ++ show t'}
+                        else
+                            if c' /= c
+                                then
+                                    failed
+                                        { reason =
+                                            "found valid, but converts "
+                                                ++ show c
+                                                ++ " -> "
+                                                ++ show t'
+                                                ++ " -> "
+                                                ++ show c'
+                                        }
+                                else succeeded
+            else case mt of
+                Nothing ->
+                    if c' /= c
+                        then succeeded
+                        else failed{reason = show c ++ " found invalid, but converts with " ++ show t'}
+                Just _ -> rejected
 
 validTest ::
-       (Arbitrary s, Show s, Eq c, Show c, Eq t, Show t)
-    => String
-    -> (s -> c)
-    -> (t -> c)
-    -> (c -> t)
-    -> (c -> Maybe t)
-    -> TestTree
+    (Arbitrary s, Show s, Eq c, Show c, Eq t, Show t) =>
+    String ->
+    (s -> c) ->
+    (t -> c) ->
+    (c -> t) ->
+    (c -> Maybe t) ->
+    TestTree
 validTest name sc toComponents fromComponents fromComponentsValid =
     testGroup
         name
@@ -52,101 +60,105 @@
         ]
 
 toSundayStartWeek :: Day -> (Integer, Int, Int)
-toSundayStartWeek day = let
-    (y, _) = toOrdinalDate day
-    (w, d) = sundayStartWeek day
-    in (y, w, d)
+toSundayStartWeek day =
+    let
+        (y, _) = toOrdinalDate day
+        (w, d) = sundayStartWeek day
+    in
+        (y, w, d)
 
 toMondayStartWeek :: Day -> (Integer, Int, Int)
-toMondayStartWeek day = let
-    (y, _) = toOrdinalDate day
-    (w, d) = mondayStartWeek day
-    in (y, w, d)
+toMondayStartWeek day =
+    let
+        (y, _) = toOrdinalDate day
+        (w, d) = mondayStartWeek day
+    in
+        (y, w, d)
 
-newtype Year =
-    MkYear Integer
+newtype WYear
+    = MkWYear Year
     deriving (Eq, Show)
 
-instance Arbitrary Year where
-    arbitrary = fmap MkYear $ choose (-1000, 3000)
+instance Arbitrary WYear where
+    arbitrary = fmap MkWYear $ choose (-1000, 3000)
 
-newtype YearMonth =
-    MkYearMonth Int
+newtype WMonthOfYear
+    = MkWMonthOfYear MonthOfYear
     deriving (Eq, Show)
 
-instance Arbitrary YearMonth where
-    arbitrary = fmap MkYearMonth $ choose (-5, 17)
+instance Arbitrary WMonthOfYear where
+    arbitrary = fmap MkWMonthOfYear $ choose (-5, 17)
 
-newtype MonthDay =
-    MkMonthDay Int
+newtype WDayOfMonth
+    = MkWDayOfMonth DayOfMonth
     deriving (Eq, Show)
 
-instance Arbitrary MonthDay where
-    arbitrary = fmap MkMonthDay $ choose (-5, 35)
+instance Arbitrary WDayOfMonth where
+    arbitrary = fmap MkWDayOfMonth $ choose (-5, 35)
 
-newtype YearDay =
-    MkYearDay Int
+newtype WDayOfYear
+    = MkWDayOfYear DayOfYear
     deriving (Eq, Show)
 
-instance Arbitrary YearDay where
-    arbitrary = fmap MkYearDay $ choose (-20, 400)
+instance Arbitrary WDayOfYear where
+    arbitrary = fmap MkWDayOfYear $ choose (-20, 400)
 
-newtype YearWeek =
-    MkYearWeek Int
+newtype WWeekOfYear
+    = MkWWeekOfYear WeekOfYear
     deriving (Eq, Show)
 
-instance Arbitrary YearWeek where
-    arbitrary = fmap MkYearWeek $ choose (-5, 60)
+instance Arbitrary WWeekOfYear where
+    arbitrary = fmap MkWWeekOfYear $ choose (-5, 60)
 
-newtype WeekDay =
-    MkWeekDay Int
+newtype WDayOfWeek
+    = MkWDayOfWeek Int
     deriving (Eq, Show)
 
-instance Arbitrary WeekDay where
-    arbitrary = fmap MkWeekDay $ choose (-5, 15)
+instance Arbitrary WDayOfWeek where
+    arbitrary = fmap MkWDayOfWeek $ choose (-5, 15)
 
-fromYMD :: (Year, YearMonth, MonthDay) -> (Integer, Int, Int)
-fromYMD (MkYear y, MkYearMonth ym, MkMonthDay md) = (y, ym, md)
+fromYMD :: (WYear, WMonthOfYear, WDayOfMonth) -> (Year, MonthOfYear, DayOfMonth)
+fromYMD (MkWYear y, MkWMonthOfYear ym, MkWDayOfMonth md) = (y, ym, md)
 
-fromYD :: (Year, YearDay) -> (Integer, Int)
-fromYD (MkYear y, MkYearDay yd) = (y, yd)
+fromYD :: (WYear, WDayOfYear) -> (Year, DayOfYear)
+fromYD (MkWYear y, MkWDayOfYear yd) = (y, yd)
 
-fromYWD :: (Year, YearWeek, WeekDay) -> (Integer, Int, Int)
-fromYWD (MkYear y, MkYearWeek yw, MkWeekDay wd) = (y, yw, wd)
+fromYWD :: (WYear, WWeekOfYear, WDayOfWeek) -> (Year, WeekOfYear, Int)
+fromYWD (MkWYear y, MkWWeekOfYear yw, MkWDayOfWeek wd) = (y, yw, wd)
 
 testValid :: TestTree
 testValid =
     testGroup
         "testValid"
         [ validTest
-              "Gregorian"
-              fromYMD
-              toGregorian
-              (\(y, m, d) -> fromGregorian y m d)
-              (\(y, m, d) -> fromGregorianValid y m d)
+            "Gregorian"
+            fromYMD
+            toGregorian
+            (\(y, m, d) -> fromGregorian y m d)
+            (\(y, m, d) -> fromGregorianValid y m d)
         , validTest
-              "OrdinalDate"
-              fromYD
-              toOrdinalDate
-              (\(y, d) -> fromOrdinalDate y d)
-              (\(y, d) -> fromOrdinalDateValid y d)
+            "OrdinalDate"
+            fromYD
+            toOrdinalDate
+            (\(y, d) -> fromOrdinalDate y d)
+            (\(y, d) -> fromOrdinalDateValid y d)
         , validTest
-              "WeekDate"
-              fromYWD
-              toWeekDate
-              (\(y, w, d) -> fromWeekDate y w d)
-              (\(y, w, d) -> fromWeekDateValid y w d)
+            "WeekDate"
+            fromYWD
+            toWeekDate
+            (\(y, w, d) -> fromWeekDate y w d)
+            (\(y, w, d) -> fromWeekDateValid y w d)
         , validTest
-              "SundayStartWeek"
-              fromYWD
-              toSundayStartWeek
-              (\(y, w, d) -> fromSundayStartWeek y w d)
-              (\(y, w, d) -> fromSundayStartWeekValid y w d)
+            "SundayStartWeek"
+            fromYWD
+            toSundayStartWeek
+            (\(y, w, d) -> fromSundayStartWeek y w d)
+            (\(y, w, d) -> fromSundayStartWeekValid y w d)
         , validTest
-              "MondayStartWeek"
-              fromYWD
-              toMondayStartWeek
-              (\(y, w, d) -> fromMondayStartWeek y w d)
-              (\(y, w, d) -> fromMondayStartWeekValid y w d)
+            "MondayStartWeek"
+            fromYWD
+            toMondayStartWeek
+            (\(y, w, d) -> fromMondayStartWeek y w d)
+            (\(y, w, d) -> fromMondayStartWeekValid y w d)
         , validTest "Julian" fromYMD toJulian (\(y, m, d) -> fromJulian y m d) (\(y, m, d) -> fromJulianValid y m d)
         ]
diff --git a/test/main/Test/Calendar/Week.hs b/test/main/Test/Calendar/Week.hs
--- a/test/main/Test/Calendar/Week.hs
+++ b/test/main/Test/Calendar/Week.hs
@@ -1,16 +1,20 @@
-module Test.Calendar.Week
-    ( testWeek
-    ) where
+module Test.Calendar.Week (
+    testWeek,
+) where
 
 import Data.Time.Calendar
+import Data.Time.Calendar.OrdinalDate
 import Data.Time.Calendar.WeekDate
+import Test.Arbitrary ()
 import Test.Tasty
 import Test.Tasty.HUnit
+import Test.TestUtil
 
 testDay :: TestTree
 testDay =
-    testCase "day" $ do
-        let day = fromGregorian 2018 1 9
+    nameTest "day" $ do
+        let
+            day = fromGregorian 2018 1 9
         assertEqual "" (ModifiedJulianDay 58127) day
         assertEqual "" (2018, 2, 2) $ toWeekDate day
         assertEqual "" Tuesday $ dayOfWeek day
@@ -19,7 +23,7 @@
 allDaysOfWeek = [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
 
 testAllDays :: String -> (DayOfWeek -> IO ()) -> TestTree
-testAllDays name f = testGroup name $ fmap (\wd -> testCase (show wd) $ f wd) allDaysOfWeek
+testAllDays name f = nameTest name $ fmap (\wd -> nameTest (show wd) $ f wd) allDaysOfWeek
 
 testSucc :: TestTree
 testSucc = testAllDays "succ" $ \wd -> assertEqual "" (toEnum $ succ $ fromEnum wd) $ succ wd
@@ -29,65 +33,216 @@
 
 testSequences :: TestTree
 testSequences =
-    testGroup
+    nameTest
         "sequence"
-        [ testCase "[Monday .. Sunday]" $ assertEqual "" allDaysOfWeek [Monday .. Sunday]
-        , testCase "[Wednesday .. Wednesday]" $ assertEqual "" [Wednesday] [Wednesday .. Wednesday]
-        , testCase "[Sunday .. Saturday]" $
-          assertEqual "" [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] [Sunday .. Saturday]
-        , testCase "[Thursday .. Wednesday]" $
-          assertEqual "" [Thursday, Friday, Saturday, Sunday, Monday, Tuesday, Wednesday] [Thursday .. Wednesday]
-        , testCase "[Tuesday ..]" $
-          assertEqual
-              ""
-              [ Tuesday
-              , Wednesday
-              , Thursday
-              , Friday
-              , Saturday
-              , Sunday
-              , Monday
-              , Tuesday
-              , Wednesday
-              , Thursday
-              , Friday
-              , Saturday
-              , Sunday
-              , Monday
-              , Tuesday
-              ] $
-          take 15 [Tuesday ..]
-        , testCase "[Wednesday, Tuesday ..]" $
-          assertEqual
-              ""
-              [ Wednesday
-              , Tuesday
-              , Monday
-              , Sunday
-              , Saturday
-              , Friday
-              , Thursday
-              , Wednesday
-              , Tuesday
-              , Monday
-              , Sunday
-              , Saturday
-              , Friday
-              , Thursday
-              , Wednesday
-              ] $
-          take 15 [Wednesday,Tuesday ..]
-        , testCase "[Sunday, Friday ..]" $
-          assertEqual "" [Sunday, Friday, Wednesday, Monday, Saturday, Thursday, Tuesday, Sunday] $
-          take 8 [Sunday,Friday ..]
-        , testCase "[Monday,Sunday .. Tuesday]" $
-          assertEqual "" [Monday, Sunday, Saturday, Friday, Thursday, Wednesday, Tuesday] [Monday,Sunday .. Tuesday]
-        , testCase "[Thursday, Saturday .. Tuesday]" $
-          assertEqual "" [Thursday, Saturday, Monday, Wednesday, Friday, Sunday, Tuesday] [Thursday,Saturday .. Tuesday]
+        [ nameTest "[Monday .. Sunday]" $ assertEqual "" allDaysOfWeek [Monday .. Sunday]
+        , nameTest "[Wednesday .. Wednesday]" $ assertEqual "" [Wednesday] [Wednesday .. Wednesday]
+        , nameTest "[Sunday .. Saturday]" $
+            assertEqual "" [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] [Sunday .. Saturday]
+        , nameTest "[Thursday .. Wednesday]" $
+            assertEqual "" [Thursday, Friday, Saturday, Sunday, Monday, Tuesday, Wednesday] [Thursday .. Wednesday]
+        , nameTest "[Tuesday ..]"
+            $ assertEqual
+                ""
+                [ Tuesday
+                , Wednesday
+                , Thursday
+                , Friday
+                , Saturday
+                , Sunday
+                , Monday
+                , Tuesday
+                , Wednesday
+                , Thursday
+                , Friday
+                , Saturday
+                , Sunday
+                , Monday
+                , Tuesday
+                ]
+            $ take 15 [Tuesday ..]
+        , nameTest "[Wednesday, Tuesday ..]"
+            $ assertEqual
+                ""
+                [ Wednesday
+                , Tuesday
+                , Monday
+                , Sunday
+                , Saturday
+                , Friday
+                , Thursday
+                , Wednesday
+                , Tuesday
+                , Monday
+                , Sunday
+                , Saturday
+                , Friday
+                , Thursday
+                , Wednesday
+                ]
+            $ take 15 [Wednesday, Tuesday ..]
+        , nameTest "[Sunday, Friday ..]" $
+            assertEqual "" [Sunday, Friday, Wednesday, Monday, Saturday, Thursday, Tuesday, Sunday] $
+                take 8 [Sunday, Friday ..]
+        , nameTest "[Monday,Sunday .. Tuesday]" $
+            assertEqual "" [Monday, Sunday, Saturday, Friday, Thursday, Wednesday, Tuesday] [Monday, Sunday .. Tuesday]
+        , nameTest "[Thursday, Saturday .. Tuesday]" $
+            assertEqual "" [Thursday, Saturday, Monday, Wednesday, Friday, Sunday, Tuesday] [Thursday, Saturday .. Tuesday]
         ]
 
 testReadShow :: TestTree
 testReadShow = testAllDays "read show" $ \wd -> assertEqual "" wd $ read $ show wd
 
+prop_firstDayOfWeekOnAfter_onAfter :: DayOfWeek -> Day -> Bool
+prop_firstDayOfWeekOnAfter_onAfter dw d = firstDayOfWeekOnAfter dw d >= d
+
+prop_firstDayOfWeekOnAfter_Day :: DayOfWeek -> Day -> Bool
+prop_firstDayOfWeekOnAfter_Day dw d = dayOfWeek (firstDayOfWeekOnAfter dw d) == dw
+
+prop_toFromWeekCalendar :: FirstWeekType -> DayOfWeek -> Day -> Bool
+prop_toFromWeekCalendar wt ws d =
+    let
+        (y, wy, dw) = toWeekCalendar wt ws d
+    in
+        fromWeekCalendar wt ws y wy dw == d
+
+prop_weekChanges :: FirstWeekType -> DayOfWeek -> Day -> Bool
+prop_weekChanges wt ws d =
+    let
+        (_, wy0, _) = toWeekCalendar wt ws d
+        (_, wy1, dw) = toWeekCalendar wt ws $ succ d
+    in
+        if dw == ws then wy0 /= wy1 else wy0 == wy1
+
+prop_weekYearWholeStart :: DayOfWeek -> Year -> Bool
+prop_weekYearWholeStart ws y =
+    let
+        d = fromWeekCalendar FirstWholeWeek ws y 1 ws
+        (y', dy) = toOrdinalDate d
+    in
+        y == y' && dy >= 1 && dy <= 7
+
+prop_weekYearMostStart :: DayOfWeek -> Year -> Bool
+prop_weekYearMostStart ws y =
+    let
+        d = fromWeekCalendar FirstMostWeek ws y 2 ws
+        (y', dy) = toOrdinalDate d
+    in
+        y == y' && dy >= 5 && dy <= 11
+
+testDiff :: TestTree
+testDiff =
+    nameTest
+        "diff"
+        [ nameTest "Friday - Tuesday" $ assertEqual "" 3 $ dayOfWeekDiff Friday Tuesday
+        , nameTest "Tuesday - Friday" $ assertEqual "" 4 $ dayOfWeekDiff Tuesday Friday
+        , nameTest "firstDayOfWeekOnAfter_onAfter" prop_firstDayOfWeekOnAfter_onAfter
+        , nameTest "firstDayOfWeekOnAfter_Day" prop_firstDayOfWeekOnAfter_Day
+        , nameTest "toFromWeekCalendar" prop_toFromWeekCalendar
+        , nameTest "weekChanges" prop_weekChanges
+        , nameTest "weekYearWholeStart" prop_weekYearWholeStart
+        , nameTest "weekYearMostStart" prop_weekYearMostStart
+        ]
+
+testWeekDays :: TestTree
+testWeekDays =
+    nameTest
+        "Week Days"
+        [ testGroup "weekAllDays" weekAllDaysTests
+        , testGroup "weekFirstDay" weekFirstDayTests
+        , testGroup "weekLastDay" weekLastDayTests
+        ]
+
+weekAllDaysTests :: [TestTree]
+weekAllDaysTests =
+    [ testGroup
+        "Property Tests"
+        [ nameTest "Week have 7 days" weekHaveSevenDays
+        , nameTest "Day is part of the week" dayIsPartOfWeek
+        ]
+    , testGroup
+        "Unit Tests"
+        [ nameTest "FirstDay is less than Day-DayOfWeek" $
+            assertEqual
+                ""
+                [YearMonthDay 2023 12 31 .. YearMonthDay 2024 1 6]
+                (weekAllDays Sunday (YearMonthDay 2024 1 1))
+        , nameTest "FirstDay is equal to Day-DayOfWeek" $
+            assertEqual
+                ""
+                [YearMonthDay 2024 2 26 .. YearMonthDay 2024 3 3]
+                (weekAllDays Monday (YearMonthDay 2024 2 26))
+        , nameTest "FirstDay is greater than Day-DayOfWeek" $
+            assertEqual
+                ""
+                [YearMonthDay 2022 2 15 .. YearMonthDay 2022 2 21]
+                (weekAllDays Tuesday (YearMonthDay 2022 2 21))
+        ]
+    ]
+  where
+    weekHaveSevenDays :: DayOfWeek -> Day -> Bool
+    weekHaveSevenDays fd d = length (weekAllDays fd d) == 7
+
+    dayIsPartOfWeek :: DayOfWeek -> Day -> Bool
+    dayIsPartOfWeek fd d = d `elem` weekAllDays fd d
+
+weekFirstDayTests :: [TestTree]
+weekFirstDayTests =
+    [ testGroup
+        "Property Tests"
+        [ nameTest "FirsyDay matches the Day-DayOfWeek" firstDayMatchesDay
+        ]
+    , testGroup
+        "Unit Tests"
+        [ nameTest "FirstDay is less than Day-DayOfWeek" $
+            assertEqual
+                ""
+                (YearMonthDay 2022 2 20)
+                (weekFirstDay Sunday (YearMonthDay 2022 2 21))
+        , nameTest "FirstDay is equal to Day-DayOfWeek" $
+            assertEqual
+                ""
+                (YearMonthDay 2022 2 21)
+                (weekFirstDay Monday (YearMonthDay 2022 2 21))
+        , nameTest "FirstDay is greater than Day-DayOfWeek" $
+            assertEqual
+                ""
+                (YearMonthDay 2022 2 15)
+                (weekFirstDay Tuesday (YearMonthDay 2022 2 21))
+        ]
+    ]
+  where
+    firstDayMatchesDay :: DayOfWeek -> Day -> Bool
+    firstDayMatchesDay fd d = dayOfWeek (weekFirstDay fd d) == fd
+
+weekLastDayTests :: [TestTree]
+weekLastDayTests =
+    [ nameTest "FirstDay is less than Day-DayOfWeek" $
+        assertEqual
+            ""
+            (YearMonthDay 2022 2 26)
+            (weekLastDay Sunday (YearMonthDay 2022 2 21))
+    , nameTest "FirstDay is equal to Day-DayOfWeek" $
+        assertEqual
+            ""
+            (YearMonthDay 2022 2 27)
+            (weekLastDay Monday (YearMonthDay 2022 2 21))
+    , nameTest "FirstDay is greater than Day-DayOfWeek" $
+        assertEqual
+            ""
+            (YearMonthDay 2022 2 21)
+            (weekLastDay Tuesday (YearMonthDay 2022 2 21))
+    ]
+
 testWeek :: TestTree
-testWeek = testGroup "Week" [testDay, testSucc, testPred, testSequences, testReadShow]
+testWeek =
+    nameTest
+        "Week"
+        [ testDay
+        , testSucc
+        , testPred
+        , testSequences
+        , testReadShow
+        , testDiff
+        , testWeekDays
+        ]
diff --git a/test/main/Test/Calendar/Year.hs b/test/main/Test/Calendar/Year.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/Calendar/Year.hs
@@ -0,0 +1,29 @@
+module Test.Calendar.Year (
+    testYear,
+) where
+
+import Data.Time.Calendar
+import Data.Time.Calendar.OrdinalDate
+import Test.Arbitrary ()
+import Test.Tasty
+import Test.Tasty.HUnit
+import Test.TestUtil
+
+cbRoundTrip :: TestTree
+cbRoundTrip = nameTest "CE-BCE" $ \(YearDay y _) -> case y of
+    CommonEra n -> case id y of
+        BeforeCommonEra _ -> False
+        _ -> n >= 1 && y == CommonEra n
+    _ -> case id y of
+        BeforeCommonEra n -> n >= 1 && y == BeforeCommonEra n
+        _ -> False
+
+testYear :: TestTree
+testYear =
+    nameTest
+        "Year"
+        [ cbRoundTrip
+        , nameTest "succ 1" $ assertEqual "" (BeforeCommonEra 1) $ succ $ BeforeCommonEra 2
+        , nameTest "succ 2" $ assertEqual "" (CommonEra 1) $ succ $ BeforeCommonEra 1
+        , nameTest "succ 3" $ assertEqual "" (CommonEra 2) $ succ $ CommonEra 1
+        ]
diff --git a/test/main/Test/Clock/Conversion.hs b/test/main/Test/Clock/Conversion.hs
--- a/test/main/Test/Clock/Conversion.hs
+++ b/test/main/Test/Clock/Conversion.hs
@@ -1,6 +1,6 @@
-module Test.Clock.Conversion
-    ( testClockConversion
-    ) where
+module Test.Clock.Conversion (
+    testClockConversion,
+) where
 
 import Data.Time.Clock
 import Data.Time.Clock.System
@@ -9,17 +9,19 @@
 
 testClockConversion :: TestTree
 testClockConversion =
-    testGroup "clock conversion" $ let
-        testPair :: (SystemTime, UTCTime) -> TestTree
-        testPair (st, ut) =
-            testGroup (show ut) $
-            [ testCase "systemToUTCTime" $ assertEqual (show ut) ut $ systemToUTCTime st
-            , testCase "utcToSystemTime" $ assertEqual (show ut) st $ utcToSystemTime ut
+    testGroup "clock conversion" $
+        let
+            testPair :: (SystemTime, UTCTime) -> TestTree
+            testPair (st, ut) =
+                testGroup (show ut) $
+                    [ testCase "systemToUTCTime" $ assertEqual (show ut) ut $ systemToUTCTime st
+                    , testCase "utcToSystemTime" $ assertEqual (show ut) st $ utcToSystemTime ut
+                    ]
+        in
+            [ testPair (MkSystemTime 0 0, UTCTime systemEpochDay 0)
+            , testPair (MkSystemTime 86399 0, UTCTime systemEpochDay 86399)
+            , testPair (MkSystemTime 86399 999999999, UTCTime systemEpochDay 86399.999999999)
+            , testPair (MkSystemTime 86399 1000000000, UTCTime systemEpochDay 86400)
+            , testPair (MkSystemTime 86399 1999999999, UTCTime systemEpochDay 86400.999999999)
+            , testPair (MkSystemTime 86400 0, UTCTime (succ systemEpochDay) 0)
             ]
-        in [ testPair (MkSystemTime 0 0, UTCTime systemEpochDay 0)
-           , testPair (MkSystemTime 86399 0, UTCTime systemEpochDay 86399)
-           , testPair (MkSystemTime 86399 999999999, UTCTime systemEpochDay 86399.999999999)
-           , testPair (MkSystemTime 86399 1000000000, UTCTime systemEpochDay 86400)
-           , testPair (MkSystemTime 86399 1999999999, UTCTime systemEpochDay 86400.999999999)
-           , testPair (MkSystemTime 86400 0, UTCTime (succ systemEpochDay) 0)
-           ]
diff --git a/test/main/Test/Clock/Pattern.hs b/test/main/Test/Clock/Pattern.hs
new file mode 100644
--- /dev/null
+++ b/test/main/Test/Clock/Pattern.hs
@@ -0,0 +1,32 @@
+module Test.Clock.Pattern (
+    testClockPatterns,
+) where
+
+import Data.Time.Clock
+import Test.Tasty
+import Test.Tasty.HUnit
+
+testClockPatterns :: TestTree
+testClockPatterns =
+    let
+        testSame :: forall a. (Eq a, Show a) => TestName -> a -> a -> TestTree
+        testSame name expected found = testCase name $ assertEqual "" expected found
+    in
+        testGroup "pattern" $
+            [ testGroup
+                "construct"
+                [ testSame "Seconds" 52.4 (Seconds 52.4)
+                , testSame "Seconds-Picoseconds" (Picoseconds 7_276_000_000_000) (Seconds 7.276)
+                , testSame "Minutes-Seconds" (Seconds 210) (Minutes 3.5)
+                , testSame "Hours-Minutes" (Minutes 120) (Hours 2)
+                , testSame "Nominal" 37.4 (Nominal 37.4)
+                ]
+            , testGroup
+                "deconstruct"
+                [ testSame "Seconds" 52.4 ((\(Seconds x) -> x) 52.4)
+                , testSame "Seconds-Picoseconds" 7.276 ((\(Seconds x) -> x) $ Picoseconds 7_276_000_000_000)
+                , testSame "Minutes-Seconds" 3.5 ((\(Minutes x) -> x) $ Seconds 210)
+                , testSame "Hours-Minutes" 2 ((\(Hours x) -> x) $ Minutes 120)
+                , testSame "Nominal" 37.4 ((\(Nominal x) -> x) 37.4)
+                ]
+            ]
diff --git a/test/main/Test/Clock/Resolution.hs b/test/main/Test/Clock/Resolution.hs
--- a/test/main/Test/Clock/Resolution.hs
+++ b/test/main/Test/Clock/Resolution.hs
@@ -1,6 +1,6 @@
-module Test.Clock.Resolution
-    ( testResolutions
-    ) where
+module Test.Clock.Resolution (
+    testResolutions,
+) where
 
 import Control.Concurrent
 import Data.Fixed
@@ -24,7 +24,7 @@
 gcdAll = foldr gcd' 0
 
 testResolution :: (Show dt, Real dt) => String -> (at -> at -> dt) -> (dt, IO at) -> TestTree
-testResolution name timeDiff (res, getTime) =
+testResolution name timeDiff (reportedRes, getTime) =
     testCase name $ do
         t0 <- getTime
         times0 <-
@@ -33,31 +33,33 @@
                 getTime
         times1 <-
             repeatN 100 $ -- 100us
-             do
-                threadDelay 1 -- 1us
-                getTime
+                do
+                    threadDelay 1 -- 1us
+                    getTime
         times2 <-
             repeatN 100 $ -- 1ms
-             do
-                threadDelay 10 -- 10us
-                getTime
+                do
+                    threadDelay 10 -- 10us
+                    getTime
         times3 <-
             repeatN 100 $ -- 10ms
-             do
-                threadDelay 100 -- 100us
-                getTime
+                do
+                    threadDelay 100 -- 100us
+                    getTime
         times4 <-
             repeatN 100 $ -- 100ms
-             do
-                threadDelay 1000 -- 1ms
-                getTime
-        let times = fmap (\t -> timeDiff t t0) $ times0 ++ times1 ++ times2 ++ times3 ++ times4
-        assertEqual "resolution" res $ gcdAll times
+                do
+                    threadDelay 1000 -- 1ms
+                    getTime
+        let
+            times = fmap (\t -> timeDiff t t0) $ times0 ++ times1 ++ times2 ++ times3 ++ times4
+            foundGrid = gcdAll times
+        assertBool ("reported resolution: " <> show reportedRes <> ", found: " <> show foundGrid) $ foundGrid <= reportedRes
 
 testResolutions :: TestTree
 testResolutions =
     testGroup "resolution" $
-    [testResolution "getCurrentTime" diffUTCTime (realToFrac getTime_resolution, getCurrentTime)] ++
-    case taiClock of
-        Just clock -> [testResolution "taiClock" diffAbsoluteTime clock]
-        Nothing -> []
+        [testResolution "getCurrentTime" diffUTCTime (realToFrac getTime_resolution, getCurrentTime)]
+            ++ case taiClock of
+                Just clock -> [testResolution "taiClock" diffAbsoluteTime clock]
+                Nothing -> []
diff --git a/test/main/Test/Clock/TAI.hs b/test/main/Test/Clock/TAI.hs
--- a/test/main/Test/Clock/TAI.hs
+++ b/test/main/Test/Clock/TAI.hs
@@ -1,6 +1,6 @@
-module Test.Clock.TAI
-    ( testTAI
-    ) where
+module Test.Clock.TAI (
+    testTAI,
+) where
 
 import Data.Time
 import Data.Time.Clock.TAI
@@ -19,40 +19,42 @@
 
 testTAI :: TestTree
 testTAI =
-    testGroup "leap second transition" $ let
-        dayA = fromGregorian 1972 6 30
-        dayB = fromGregorian 1972 7 1
-        utcTime1 = UTCTime dayA 86399
-        utcTime2 = UTCTime dayA 86400
-        utcTime3 = UTCTime dayB 0
-        mAbsTime1 = utcToTAITime sampleLeapSecondMap utcTime1
-        mAbsTime2 = utcToTAITime sampleLeapSecondMap utcTime2
-        mAbsTime3 = utcToTAITime sampleLeapSecondMap utcTime3
-        in [ testCase "mapping" $ do
-                 assertEqual "dayA" (Just 10) $ sampleLeapSecondMap dayA
-                 assertEqual "dayB" (Just 11) $ sampleLeapSecondMap dayB
-           , testCase "day length" $ do
-                 assertEqual "dayA" (Just 86401) $ utcDayLength sampleLeapSecondMap dayA
-                 assertEqual "dayB" (Just 86400) $ utcDayLength sampleLeapSecondMap dayB
-           , testCase "differences" $ do
-                 absTime1 <- assertJust mAbsTime1
-                 absTime2 <- assertJust mAbsTime2
-                 absTime3 <- assertJust mAbsTime3
-                 assertEqual "absTime2 - absTime1" 1 $ diffAbsoluteTime absTime2 absTime1
-                 assertEqual "absTime3 - absTime2" 1 $ diffAbsoluteTime absTime3 absTime2
-           , testGroup
-                 "round-trip"
-                 [ testCase "1" $ do
-                       absTime <- assertJust mAbsTime1
-                       utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
-                       assertEqual "round-trip" utcTime1 utcTime
-                 , testCase "2" $ do
-                       absTime <- assertJust mAbsTime2
-                       utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
-                       assertEqual "round-trip" utcTime2 utcTime
-                 , testCase "3" $ do
-                       absTime <- assertJust mAbsTime3
-                       utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
-                       assertEqual "round-trip" utcTime3 utcTime
-                 ]
-           ]
+    testGroup "leap second transition" $
+        let
+            dayA = fromGregorian 1972 6 30
+            dayB = fromGregorian 1972 7 1
+            utcTime1 = UTCTime dayA 86399
+            utcTime2 = UTCTime dayA 86400
+            utcTime3 = UTCTime dayB 0
+            mAbsTime1 = utcToTAITime sampleLeapSecondMap utcTime1
+            mAbsTime2 = utcToTAITime sampleLeapSecondMap utcTime2
+            mAbsTime3 = utcToTAITime sampleLeapSecondMap utcTime3
+        in
+            [ testCase "mapping" $ do
+                assertEqual "dayA" (Just 10) $ sampleLeapSecondMap dayA
+                assertEqual "dayB" (Just 11) $ sampleLeapSecondMap dayB
+            , testCase "day length" $ do
+                assertEqual "dayA" (Just 86401) $ utcDayLength sampleLeapSecondMap dayA
+                assertEqual "dayB" (Just 86400) $ utcDayLength sampleLeapSecondMap dayB
+            , testCase "differences" $ do
+                absTime1 <- assertJust mAbsTime1
+                absTime2 <- assertJust mAbsTime2
+                absTime3 <- assertJust mAbsTime3
+                assertEqual "absTime2 - absTime1" 1 $ diffAbsoluteTime absTime2 absTime1
+                assertEqual "absTime3 - absTime2" 1 $ diffAbsoluteTime absTime3 absTime2
+            , testGroup
+                "round-trip"
+                [ testCase "1" $ do
+                    absTime <- assertJust mAbsTime1
+                    utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
+                    assertEqual "round-trip" utcTime1 utcTime
+                , testCase "2" $ do
+                    absTime <- assertJust mAbsTime2
+                    utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
+                    assertEqual "round-trip" utcTime2 utcTime
+                , testCase "3" $ do
+                    absTime <- assertJust mAbsTime3
+                    utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
+                    assertEqual "round-trip" utcTime3 utcTime
+                ]
+            ]
diff --git a/test/main/Test/Format/Compile.hs b/test/main/Test/Format/Compile.hs
--- a/test/main/Test/Format/Compile.hs
+++ b/test/main/Test/Format/Compile.hs
@@ -1,16 +1,14 @@
 -- Tests succeed if module compiles
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Test.Format.Compile (
 
-module Test.Format.Compile
-    (
-    ) where
+) where
 
 import Data.Time
 
-newtype WrappedUTCTime =
-    MkWrappedUTCTime UTCTime
+newtype WrappedUTCTime
+    = MkWrappedUTCTime UTCTime
     deriving (FormatTime, ParseTime)
 
-newtype Wrapped t =
-    MkWrapped t
+newtype Wrapped t
+    = MkWrapped t
     deriving (FormatTime, ParseTime)
diff --git a/test/main/Test/Format/Format.hs b/test/main/Test/Format/Format.hs
--- a/test/main/Test/Format/Format.hs
+++ b/test/main/Test/Format/Format.hs
@@ -1,6 +1,6 @@
-module Test.Format.Format
-    ( testFormat
-    ) where
+module Test.Format.Format (
+    testFormat,
+) where
 
 import Data.Proxy
 import Data.Time
@@ -9,12 +9,12 @@
 import Test.TestUtil
 
 -- as found in http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
--- plus FgGklz
+-- plus FgGklvz
 -- f not supported
 -- P not always supported
 -- s time-zone dependent
 chars :: [Char]
-chars = "aAbBcCdDeFgGhHIjklmMnprRStTuUVwWxXyYzZ%"
+chars = "aAbBcCdDeFgGhHIjklmMnprRStTuUvVwWxXyYzZ%"
 
 -- as found in "man strftime" on a glibc system. '#' is different, though
 modifiers :: [Char]
@@ -25,12 +25,13 @@
 
 formats :: [String]
 formats =
-    ["%G-W%V-%u", "%U-%w", "%W-%u"] ++
-    (fmap (\char -> '%' : [char]) chars) ++
-    (concat $
-     fmap
-         (\char -> concat $ fmap (\width -> fmap (\modifier -> "%" ++ [modifier] ++ width ++ [char]) modifiers) widths)
-         chars)
+    ["%G-W%V-%u", "%U-%w", "%W-%u"]
+        ++ (fmap (\char -> '%' : [char]) chars)
+        ++ ( concat $
+                fmap
+                    (\char -> concat $ fmap (\width -> fmap (\modifier -> "%" ++ [modifier] ++ width ++ [char]) modifiers) widths)
+                    chars
+           )
 
 somestrings :: [String]
 somestrings = ["", " ", "-", "\n"]
@@ -61,11 +62,13 @@
 testDayOfWeek :: TestTree
 testDayOfWeek =
     testGroup "DayOfWeek" $
-    tgroup "uwaA" $ \fmt ->
-        tgroup days $ \day -> let
-            dayFormat = formatTime defaultTimeLocale ['%', fmt] day
-            dowFormat = formatTime defaultTimeLocale ['%', fmt] $ dayOfWeek day
-            in assertEqual "" dayFormat dowFormat
+        tgroup "uwaA" $ \fmt ->
+            tgroup days $ \day ->
+                let
+                    dayFormat = formatTime defaultTimeLocale ['%', fmt] day
+                    dowFormat = formatTime defaultTimeLocale ['%', fmt] $ dayOfWeek day
+                in
+                    assertEqual "" dayFormat dowFormat
 
 testZone :: String -> String -> Int -> TestTree
 testZone fmt expected minutes =
@@ -116,17 +119,17 @@
         , testAFormat "%dd %hh %mm %ss %Ess" "0d 0h 0m 0s 0.74s" $ (fromRational $ 0.74 :: NominalDiffTime)
         , testAFormat "%dd %hh %mm %ss %Ess" "0d 0h 0m 0s -0.74s" $ (fromRational $ negate $ 0.74 :: NominalDiffTime)
         , testAFormat "%dd %hh %mm %ss %Ess %0Ess" "23d 554h 33262m 1995728s 1995728.21s 1995728.210000000000s" $
-          (fromRational $ 23 * 86400 + 8528.21 :: NominalDiffTime)
+            (fromRational $ 23 * 86400 + 8528.21 :: NominalDiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%Ss" "-3w-2d-2h-22m-8s" $
-          (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%ESs" "-3w-2d-2h-22m-8.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%Ss" "-3w-2d-2h-22m0s" $
-          (fromRational $ negate $ 23 * 86400 + 8520.21 :: NominalDiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8520.21 :: NominalDiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%ESs" "-3w-2d-2h-22m-0.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8520.21 :: NominalDiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8520.21 :: NominalDiffTime)
         , testAFormat "%dd %hh %mm %Ess" "-23d -554h -33262m -1995728.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8528.21 :: NominalDiffTime)
         , testAFormat "%3Es" "1.200" (1.2 :: NominalDiffTime)
         , testAFormat "%3ES" "01.200" (1.2 :: NominalDiffTime)
         , testAFormat "%3ES" "01.200" (61.2 :: NominalDiffTime)
@@ -143,15 +146,15 @@
         , testAFormat "%dd %hh %mm %ss %Ess" "0d 0h 0m 0s 0.74s" $ (fromRational $ 0.74 :: DiffTime)
         , testAFormat "%dd %hh %mm %ss %Ess" "0d 0h 0m 0s -0.74s" $ (fromRational $ negate $ 0.74 :: DiffTime)
         , testAFormat "%dd %hh %mm %ss %Ess %0Ess" "23d 554h 33262m 1995728s 1995728.21s 1995728.210000000000s" $
-          (fromRational $ 23 * 86400 + 8528.21 :: DiffTime)
+            (fromRational $ 23 * 86400 + 8528.21 :: DiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%Ss" "-3w-2d-2h-22m-8s" $ (fromRational $ negate $ 23 * 86400 + 8528.21 :: DiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%ESs" "-3w-2d-2h-22m-8.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8528.21 :: DiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8528.21 :: DiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%Ss" "-3w-2d-2h-22m0s" $ (fromRational $ negate $ 23 * 86400 + 8520.21 :: DiffTime)
         , testAFormat "%ww%Dd%Hh%Mm%ESs" "-3w-2d-2h-22m-0.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8520.21 :: DiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8520.21 :: DiffTime)
         , testAFormat "%dd %hh %mm %Ess" "-23d -554h -33262m -1995728.21s" $
-          (fromRational $ negate $ 23 * 86400 + 8528.21 :: DiffTime)
+            (fromRational $ negate $ 23 * 86400 + 8528.21 :: DiffTime)
         , testAFormat "%3Es" "1.200" (1.2 :: DiffTime)
         , testAFormat "%3ES" "01.200" (1.2 :: DiffTime)
         , testAFormat "%3ES" "01.200" (61.2 :: DiffTime)
@@ -160,42 +163,50 @@
         , testAFormat "%3ES" "01.245" (61.24582 :: DiffTime)
         ]
 
-testCalenderDiffDays :: TestTree
-testCalenderDiffDays =
+testCalendarDiffDays :: TestTree
+testCalendarDiffDays =
     testGroup
-        "CalenderDiffDays"
+        "CalendarDiffDays"
         [ testAFormat "%yy%Bm%ww%Dd" "5y4m3w2d" $ CalendarDiffDays 64 23
         , testAFormat "%bm %dd" "64m 23d" $ CalendarDiffDays 64 23
         , testAFormat "%yy%Bm%ww%Dd" "-5y-4m-3w-2d" $ CalendarDiffDays (-64) (-23)
         , testAFormat "%bm %dd" "-64m -23d" $ CalendarDiffDays (-64) (-23)
         ]
 
-testCalenderDiffTime :: TestTree
-testCalenderDiffTime =
+testCalendarDiffTime :: TestTree
+testCalendarDiffTime =
     testGroup
-        "CalenderDiffTime"
+        "CalendarDiffTime"
         [ testAFormat "%yy%Bm%ww%Dd%Hh%Mm%Ss" "5y4m3w2d2h22m8s" $ CalendarDiffTime 64 $ 23 * 86400 + 8528.21
         , testAFormat "%yy%Bm%ww%Dd%Hh%Mm%ESs" "5y4m3w2d2h22m8.21s" $ CalendarDiffTime 64 $ 23 * 86400 + 8528.21
         , testAFormat "%yy%Bm%ww%Dd%Hh%Mm%0ESs" "5y4m3w2d2h22m08.210000000000s" $
-          CalendarDiffTime 64 $ 23 * 86400 + 8528.21
+            CalendarDiffTime 64 $
+                23 * 86400 + 8528.21
         , testAFormat "%bm %dd %hh %mm %Ess" "64m 23d 554h 33262m 1995728.21s" $
-          CalendarDiffTime 64 $ 23 * 86400 + 8528.21
+            CalendarDiffTime 64 $
+                23 * 86400 + 8528.21
         , testAFormat "%yy%Bm%ww%Dd%Hh%Mm%Ss" "-5y-4m-3w-2d-2h-22m-8s" $
-          CalendarDiffTime (-64) $ negate $ 23 * 86400 + 8528.21
+            CalendarDiffTime (-64) $
+                negate $
+                    23 * 86400 + 8528.21
         , testAFormat "%yy%Bm%ww%Dd%Hh%Mm%ESs" "-5y-4m-3w-2d-2h-22m-8.21s" $
-          CalendarDiffTime (-64) $ negate $ 23 * 86400 + 8528.21
+            CalendarDiffTime (-64) $
+                negate $
+                    23 * 86400 + 8528.21
         , testAFormat "%bm %dd %hh %mm %Ess" "-64m -23d -554h -33262m -1995728.21s" $
-          CalendarDiffTime (-64) $ negate $ 23 * 86400 + 8528.21
+            CalendarDiffTime (-64) $
+                negate $
+                    23 * 86400 + 8528.21
         ]
 
 testFormat :: TestTree
 testFormat =
     testGroup "testFormat" $
-    [ testCheckParse
-    , testDayOfWeek
-    , testTimeZone
-    , testNominalDiffTime
-    , testDiffTime
-    , testCalenderDiffDays
-    , testCalenderDiffTime
-    ]
+        [ testCheckParse
+        , testDayOfWeek
+        , testTimeZone
+        , testNominalDiffTime
+        , testDiffTime
+        , testCalendarDiffDays
+        , testCalendarDiffTime
+        ]
diff --git a/test/main/Test/Format/ISO8601.hs b/test/main/Test/Format/ISO8601.hs
--- a/test/main/Test/Format/ISO8601.hs
+++ b/test/main/Test/Format/ISO8601.hs
@@ -1,9 +1,10 @@
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Test.Format.ISO8601
-    ( testISO8601
-    ) where
+module Test.Format.ISO8601 (
+    testISO8601,
+) where
 
+import Data.Coerce
 import Data.Ratio
 import Data.Time
 import Data.Time.Format.ISO8601
@@ -16,27 +17,62 @@
 
 deriving instance Eq ZonedTime
 
-readShowProperty :: (Eq a, Show a) => Format a -> a -> Property
-readShowProperty fmt val =
+readShowProperty :: (Eq a, Show a) => (a -> Bool) -> Format a -> a -> Property
+readShowProperty skip _ val | skip val = property Discard
+readShowProperty _ fmt val =
     case formatShowM fmt val of
         Nothing -> property Discard
-        Just str -> let
-            found = formatParseM fmt str
-            expected = Just val
-            in property $
-               if expected == found
-                   then succeeded
-                   else failed {reason = show str ++ ": expected " ++ (show expected) ++ ", found " ++ (show found)}
+        Just str ->
+            let
+                found = formatParseM fmt str
+                expected = Just val
+            in
+                property $
+                    if expected == found
+                        then succeeded
+                        else failed{reason = show str ++ ": expected " ++ (show expected) ++ ", found " ++ (show found)}
 
+class SpecialTestValues a where
+    testGen :: Gen a
+    default testGen :: Arbitrary a => Gen a
+    testGen = arbitrary
+
+    -- | values that should always be tested
+    specialTestValues :: [a]
+    specialTestValues = []
+
+instance {-# OVERLAPPABLE #-} Arbitrary a => SpecialTestValues a
+
+instance SpecialTestValues TimeOfDay where
+    specialTestValues = [TimeOfDay 0 0 0, TimeOfDay 0 0 60, TimeOfDay 1 0 60, TimeOfDay 24 0 0]
+
+instance SpecialTestValues (Integer, Int) where
+    testGen = do
+        Small y <- arbitrary
+        woy <- choose (-10, 120)
+        pure (y, woy)
+
+readShowTestCheck :: (Eq a, Show a, SpecialTestValues a) => (a -> Bool) -> Format a -> [TestTree]
+readShowTestCheck skip fmt =
+    [ nameTest "random" $ fmap (readShowProperty skip fmt) testGen
+    , nameTest "special" $ fmap (\a -> nameTest (show a) $ readShowProperty skip fmt a) $ filter (not . skip) specialTestValues
+    ]
+
+readShowTest :: (Eq a, Show a, SpecialTestValues a) => Format a -> [TestTree]
+readShowTest = readShowTestCheck $ \_ -> False
+
 readBoth :: NameTest t => (FormatExtension -> t) -> [TestTree]
 readBoth fmts = [nameTest "extended" $ fmts ExtendedFormat, nameTest "basic" $ fmts BasicFormat]
 
-readShowProperties :: (Eq a, Show a, Arbitrary a) => (FormatExtension -> Format a) -> [TestTree]
-readShowProperties fmts = readBoth $ \fe -> readShowProperty $ fmts fe
+readShowTestsCheck :: (Eq a, Show a, SpecialTestValues a) => (a -> Bool) -> (FormatExtension -> Format a) -> [TestTree]
+readShowTestsCheck skip fmts = readBoth $ \fe -> readShowTestCheck skip $ fmts fe
 
-newtype Durational t =
-    MkDurational t
+readShowTests :: (Eq a, Show a, SpecialTestValues a) => (FormatExtension -> Format a) -> [TestTree]
+readShowTests = readShowTestsCheck $ \_ -> False
 
+newtype Durational t = MkDurational t
+    deriving Eq
+
 instance Show t => Show (Durational t) where
     show (MkDurational t) = show t
 
@@ -47,199 +83,272 @@
         return $ MkDurational $ CalendarDiffDays mm dd
 
 instance Arbitrary (Durational CalendarDiffTime) where
-    arbitrary = let
-        limit = 40 * 86400
-        picofactor = 10 ^ (12 :: Int)
-        in do
-               mm <- choose (-10000, 10000)
-               ss <- choose (negate limit * picofactor, limit * picofactor)
-               return $ MkDurational $ CalendarDiffTime mm $ fromRational $ ss % picofactor
+    arbitrary =
+        let
+            limit = 40 * 86400
+            picofactor = 10 ^ (12 :: Int)
+        in
+            do
+                mm <- choose (-10000, 10000)
+                ss <- choose (negate limit * picofactor, limit * picofactor)
+                return $ MkDurational $ CalendarDiffTime mm $ fromRational $ ss % picofactor
 
+durationalFormat :: Format a -> Format (Durational a)
+durationalFormat = coerce
+
 testReadShowFormat :: TestTree
 testReadShowFormat =
+    localOption (QuickCheckTests 1000) $
+        nameTest
+            "read-show format"
+            [ nameTest "calendarFormat" $ readShowTests $ calendarFormat
+            , nameTest "yearMonthFormat" $ readShowTest $ yearMonthFormat
+            , nameTest "yearFormat" $ readShowTest $ yearFormat
+            , nameTest "centuryFormat" $ readShowTest $ centuryFormat
+            , nameTest "expandedCalendarFormat" $ readShowTests $ expandedCalendarFormat 6
+            , nameTest "expandedYearMonthFormat" $ readShowTest $ expandedYearMonthFormat 6
+            , nameTest "expandedYearFormat" $ readShowTest $ expandedYearFormat 6
+            , nameTest "expandedCenturyFormat" $ readShowTest $ expandedCenturyFormat 4
+            , nameTest "ordinalDateFormat" $ readShowTests $ ordinalDateFormat
+            , nameTest "expandedOrdinalDateFormat" $ readShowTests $ expandedOrdinalDateFormat 6
+            , nameTest "weekDateFormat" $ readShowTests $ weekDateFormat
+            , nameTest "yearWeekFormat" $ readShowTests $ yearWeekFormat
+            , nameTest "expandedWeekDateFormat" $ readShowTests $ expandedWeekDateFormat 6
+            , nameTest "expandedYearWeekFormat" $ readShowTests $ expandedYearWeekFormat 6
+            , nameTest "timeOfDayFormat" $ readShowTests $ timeOfDayFormat
+            , nameTest "hourMinuteFormat" $ readShowTestsCheck (\(TimeOfDay _ _ s) -> s >= 60) $ hourMinuteFormat
+            , nameTest "hourFormat" $ readShowTestCheck (\(TimeOfDay _ _ s) -> s >= 60) $ hourFormat
+            , nameTest "withTimeDesignator" $ readShowTests $ \fe -> withTimeDesignator $ timeOfDayFormat fe
+            , nameTest "withUTCDesignator" $ readShowTests $ \fe -> withUTCDesignator $ timeOfDayFormat fe
+            , nameTest "timeOffsetFormat" $ readShowTests $ timeOffsetFormat
+            , nameTest "timeOfDayAndOffsetFormat" $ readShowTests $ timeOfDayAndOffsetFormat
+            , nameTest "localTimeFormat" $
+                readShowTests $
+                    \fe -> localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
+            , nameTest "zonedTimeFormat" $
+                readShowTests $
+                    \fe -> zonedTimeFormat (calendarFormat fe) (timeOfDayFormat fe) fe
+            , nameTest "utcTimeFormat" $ readShowTests $ \fe -> utcTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
+            , nameTest "dayAndTimeFormat" $
+                readShowTests $
+                    \fe -> dayAndTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
+            , nameTest "timeAndOffsetFormat" $ readShowTests $ \fe -> timeAndOffsetFormat (timeOfDayFormat fe) fe
+            , nameTest "durationDaysFormat" $ readShowTest $ durationDaysFormat
+            , nameTest "durationTimeFormat" $ readShowTest $ durationTimeFormat
+            , nameTest "alternativeDurationDaysFormat" $
+                readBoth $
+                    \fe -> readShowTest (durationalFormat $ alternativeDurationDaysFormat fe)
+            , nameTest "alternativeDurationTimeFormat" $
+                readBoth $
+                    \fe -> readShowTest (durationalFormat $ alternativeDurationTimeFormat fe)
+            , nameTest "intervalFormat" $
+                readShowTests $ \fe ->
+                    intervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
+            , nameTest "recurringIntervalFormat" $
+                readShowTests $ \fe ->
+                    recurringIntervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
+            ]
+
+testShowReadFormat :: (Show t, Eq t) => String -> Format t -> String -> t -> TestTree
+testShowReadFormat name fmt str val =
     nameTest
-        "read-show format"
-        [ nameTest "calendarFormat" $ readShowProperties $ calendarFormat
-        , nameTest "yearMonthFormat" $ readShowProperty $ yearMonthFormat
-        , nameTest "yearFormat" $ readShowProperty $ yearFormat
-        , nameTest "centuryFormat" $ readShowProperty $ centuryFormat
-        , nameTest "expandedCalendarFormat" $ readShowProperties $ expandedCalendarFormat 6
-        , nameTest "expandedYearMonthFormat" $ readShowProperty $ expandedYearMonthFormat 6
-        , nameTest "expandedYearFormat" $ readShowProperty $ expandedYearFormat 6
-        , nameTest "expandedCenturyFormat" $ readShowProperty $ expandedCenturyFormat 4
-        , nameTest "ordinalDateFormat" $ readShowProperties $ ordinalDateFormat
-        , nameTest "expandedOrdinalDateFormat" $ readShowProperties $ expandedOrdinalDateFormat 6
-        , nameTest "weekDateFormat" $ readShowProperties $ weekDateFormat
-        , nameTest "yearWeekFormat" $ readShowProperties $ yearWeekFormat
-        , nameTest "expandedWeekDateFormat" $ readShowProperties $ expandedWeekDateFormat 6
-        , nameTest "expandedYearWeekFormat" $ readShowProperties $ expandedYearWeekFormat 6
-        , nameTest "timeOfDayFormat" $ readShowProperties $ timeOfDayFormat
-        , nameTest "hourMinuteFormat" $ readShowProperties $ hourMinuteFormat
-        , nameTest "hourFormat" $ readShowProperty $ hourFormat
-        , nameTest "withTimeDesignator" $ readShowProperties $ \fe -> withTimeDesignator $ timeOfDayFormat fe
-        , nameTest "withUTCDesignator" $ readShowProperties $ \fe -> withUTCDesignator $ timeOfDayFormat fe
-        , nameTest "timeOffsetFormat" $ readShowProperties $ timeOffsetFormat
-        , nameTest "timeOfDayAndOffsetFormat" $ readShowProperties $ timeOfDayAndOffsetFormat
-        , nameTest "localTimeFormat" $
-          readShowProperties $ \fe -> localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
-        , nameTest "zonedTimeFormat" $
-          readShowProperties $ \fe -> zonedTimeFormat (calendarFormat fe) (timeOfDayFormat fe) fe
-        , nameTest "utcTimeFormat" $ readShowProperties $ \fe -> utcTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
-        , nameTest "dayAndTimeFormat" $
-          readShowProperties $ \fe -> dayAndTimeFormat (calendarFormat fe) (timeOfDayFormat fe)
-        , nameTest "timeAndOffsetFormat" $ readShowProperties $ \fe -> timeAndOffsetFormat (timeOfDayFormat fe) fe
-        , nameTest "durationDaysFormat" $ readShowProperty $ durationDaysFormat
-        , nameTest "durationTimeFormat" $ readShowProperty $ durationTimeFormat
-        , nameTest "alternativeDurationDaysFormat" $
-          readBoth $ \fe (MkDurational t) -> readShowProperty (alternativeDurationDaysFormat fe) t
-        , nameTest "alternativeDurationTimeFormat" $
-          readBoth $ \fe (MkDurational t) -> readShowProperty (alternativeDurationTimeFormat fe) t
-        , nameTest "intervalFormat" $
-          readShowProperties $ \fe ->
-              intervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
-        , nameTest "recurringIntervalFormat" $
-          readShowProperties $ \fe ->
-              recurringIntervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
+        (name ++ ": " ++ str)
+        [ nameTest "show" $ assertEqual "" (Just str) $ formatShowM fmt val
+        , nameTest "read" $ assertEqual "" (Just val) $ formatParseM fmt str
         ]
 
-testShowFormat :: String -> Format t -> String -> t -> TestTree
-testShowFormat name fmt str t = nameTest (name ++ ": " ++ str) $ assertEqual "" (Just str) $ formatShowM fmt t
+testReadFormat :: (Show t, Eq t) => String -> Format t -> String -> t -> TestTree
+testReadFormat name fmt str val = nameTest (name ++ ": " ++ str) $ assertEqual "" (Just val) $ formatParseM fmt str
 
 testShowFormats :: TestTree
 testShowFormats =
     nameTest
         "show format"
-        [ testShowFormat "durationDaysFormat" durationDaysFormat "P0D" $ CalendarDiffDays 0 0
-        , testShowFormat "durationDaysFormat" durationDaysFormat "P4Y" $ CalendarDiffDays 48 0
-        , testShowFormat "durationDaysFormat" durationDaysFormat "P7M" $ CalendarDiffDays 7 0
-        , testShowFormat "durationDaysFormat" durationDaysFormat "P5D" $ CalendarDiffDays 0 5
-        , testShowFormat "durationDaysFormat" durationDaysFormat "P2Y3M81D" $ CalendarDiffDays 27 81
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P0D" $ CalendarDiffTime 0 0
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P4Y" $ CalendarDiffTime 48 0
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P7M" $ CalendarDiffTime 7 0
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P5D" $ CalendarDiffTime 0 $ 5 * nominalDay
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P2Y3M81D" $ CalendarDiffTime 27 $ 81 * nominalDay
-        , testShowFormat "durationTimeFormat" durationTimeFormat "PT2H" $ CalendarDiffTime 0 $ 7200
-        , testShowFormat "durationTimeFormat" durationTimeFormat "PT3M" $ CalendarDiffTime 0 $ 180
-        , testShowFormat "durationTimeFormat" durationTimeFormat "PT12S" $ CalendarDiffTime 0 $ 12
-        , testShowFormat "durationTimeFormat" durationTimeFormat "PT1M18.77634S" $ CalendarDiffTime 0 $ 78.77634
-        , testShowFormat "durationTimeFormat" durationTimeFormat "PT2H1M18.77634S" $ CalendarDiffTime 0 $ 7278.77634
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P5DT2H1M18.77634S" $
-          CalendarDiffTime 0 $ 5 * nominalDay + 7278.77634
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10M5DT2H1M18.77634S" $
-          CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10MT2H1M18.77634S" $
-          CalendarDiffTime 94 $ 7278.77634
-        , testShowFormat "durationTimeFormat" durationTimeFormat "P8YT2H1M18.77634S" $ CalendarDiffTime 96 $ 7278.77634
-        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0001-00-00" $
-          CalendarDiffDays 12 0
-        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0002-03-29" $
-          CalendarDiffDays 27 29
-        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0561-08-29" $
-          CalendarDiffDays (561 * 12 + 8) 29
-        , testShowFormat
-              "alternativeDurationTimeFormat"
-              (alternativeDurationTimeFormat ExtendedFormat)
-              "P0000-00-01T00:00:00" $
-          CalendarDiffTime 0 86400
-        , testShowFormat
-              "alternativeDurationTimeFormat"
-              (alternativeDurationTimeFormat ExtendedFormat)
-              "P0007-10-05T02:01:18.77634" $
-          CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634
-        , testShowFormat
-              "alternativeDurationTimeFormat"
-              (alternativeDurationTimeFormat ExtendedFormat)
-              "P4271-10-05T02:01:18.77634" $
-          CalendarDiffTime (12 * 4271 + 10) $ 5 * nominalDay + 7278.77634
-        , testShowFormat "centuryFormat" centuryFormat "02" 2
-        , testShowFormat "centuryFormat" centuryFormat "21" 21
-        , testShowFormat
-              "intervalFormat etc."
-              (intervalFormat
-                   (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
-                   durationTimeFormat)
-              "2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
-              ( LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
-              , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34)
-        , testShowFormat
-              "recurringIntervalFormat etc."
-              (recurringIntervalFormat
-                   (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
-                   durationTimeFormat)
-              "R74/2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
-              ( 74
-              , LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
-              , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34)
-        , testShowFormat
-              "recurringIntervalFormat etc."
-              (recurringIntervalFormat (calendarFormat ExtendedFormat) durationDaysFormat)
-              "R74/2015-06-13/P1Y2M7D"
-              (74, fromGregorian 2015 6 13, CalendarDiffDays 14 7)
-        , testShowFormat "timeOffsetFormat" iso8601Format "-06:30" (minutesToTimeZone (-390))
-        , testShowFormat "timeOffsetFormat" iso8601Format "+00:00" (minutesToTimeZone 0)
-        , testShowFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+0000" (minutesToTimeZone 0)
-        , testShowFormat "timeOffsetFormat" iso8601Format "+00:10" (minutesToTimeZone 10)
-        , testShowFormat "timeOffsetFormat" iso8601Format "-00:10" (minutesToTimeZone (-10))
-        , testShowFormat "timeOffsetFormat" iso8601Format "+01:35" (minutesToTimeZone 95)
-        , testShowFormat "timeOffsetFormat" iso8601Format "-01:35" (minutesToTimeZone (-95))
-        , testShowFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+0135" (minutesToTimeZone 95)
-        , testShowFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "-0135" (minutesToTimeZone (-95))
-        , testShowFormat
-              "timeOffsetFormat"
-              (timeOffsetFormat BasicFormat)
-              "-1100"
-              (minutesToTimeZone $ negate $ 11 * 60)
-        , testShowFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+1015" (minutesToTimeZone $ 615)
-        , testShowFormat
-              "zonedTimeFormat"
-              iso8601Format
-              "2024-07-06T08:45:56.553-06:30"
-              (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone (-390)))
-        , testShowFormat
-              "zonedTimeFormat"
-              iso8601Format
-              "2024-07-06T08:45:56.553+06:30"
-              (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone 390))
-        , testShowFormat
-              "utcTimeFormat"
-              iso8601Format
-              "2024-07-06T08:45:56.553Z"
-              (UTCTime (fromGregorian 2024 07 06) (timeOfDayToTime $ TimeOfDay 8 45 56.553))
-        , testShowFormat
-              "utcTimeFormat"
-              iso8601Format
-              "2028-12-31T23:59:60.9Z"
-              (UTCTime (fromGregorian 2028 12 31) (timeOfDayToTime $ TimeOfDay 23 59 60.9))
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1994-W52-7" (fromGregorian 1995 1 1)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1995-W01-1" (fromGregorian 1995 1 2)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1996-W52-7" (fromGregorian 1996 12 29)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1997-W01-2" (fromGregorian 1996 12 31)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1997-W01-3" (fromGregorian 1997 1 1)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1974-W32-6" (fromGregorian 1974 8 10)
-        , testShowFormat "weekDateFormat" (weekDateFormat BasicFormat) "1974W326" (fromGregorian 1974 8 10)
-        , testShowFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1995-W05-6" (fromGregorian 1995 2 4)
-        , testShowFormat "weekDateFormat" (weekDateFormat BasicFormat) "1995W056" (fromGregorian 1995 2 4)
-        , testShowFormat
-              "weekDateFormat"
-              (expandedWeekDateFormat 6 ExtendedFormat)
-              "+001995-W05-6"
-              (fromGregorian 1995 2 4)
-        , testShowFormat "weekDateFormat" (expandedWeekDateFormat 6 BasicFormat) "+001995W056" (fromGregorian 1995 2 4)
-        , testShowFormat "ordinalDateFormat" (ordinalDateFormat ExtendedFormat) "1846-235" (fromGregorian 1846 8 23)
-        , testShowFormat "ordinalDateFormat" (ordinalDateFormat BasicFormat) "1844236" (fromGregorian 1844 8 23)
-        , testShowFormat
-              "ordinalDateFormat"
-              (expandedOrdinalDateFormat 5 ExtendedFormat)
-              "+01846-235"
-              (fromGregorian 1846 8 23)
-        , testShowFormat "hourMinuteFormat" (hourMinuteFormat ExtendedFormat) "13:17.25" (TimeOfDay 13 17 15)
-        , testShowFormat "hourMinuteFormat" (hourMinuteFormat ExtendedFormat) "01:12.4" (TimeOfDay 1 12 24)
-        , testShowFormat "hourMinuteFormat" (hourMinuteFormat BasicFormat) "1317.25" (TimeOfDay 13 17 15)
-        , testShowFormat "hourMinuteFormat" (hourMinuteFormat BasicFormat) "0112.4" (TimeOfDay 1 12 24)
-        , testShowFormat "hourFormat" hourFormat "22" (TimeOfDay 22 0 0)
-        , testShowFormat "hourFormat" hourFormat "06" (TimeOfDay 6 0 0)
-        , testShowFormat "hourFormat" hourFormat "18.9475" (TimeOfDay 18 56 51)
+        [ testShowReadFormat "durationDaysFormat" durationDaysFormat "P0D" $ CalendarDiffDays 0 0
+        , testShowReadFormat "durationDaysFormat" durationDaysFormat "P4Y" $ CalendarDiffDays 48 0
+        , testShowReadFormat "durationDaysFormat" durationDaysFormat "P7M" $ CalendarDiffDays 7 0
+        , testShowReadFormat "durationDaysFormat" durationDaysFormat "P5D" $ CalendarDiffDays 0 5
+        , testShowReadFormat "durationDaysFormat" durationDaysFormat "P2Y3M81D" $ CalendarDiffDays 27 81
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P0D" $ CalendarDiffTime 0 0
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P4Y" $ CalendarDiffTime 48 0
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P7M" $ CalendarDiffTime 7 0
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P5D" $ CalendarDiffTime 0 $ 5 * nominalDay
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P2Y3M81D" $ CalendarDiffTime 27 $ 81 * nominalDay
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "PT2H" $ CalendarDiffTime 0 $ 7200
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "PT3M" $ CalendarDiffTime 0 $ 180
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "PT12S" $ CalendarDiffTime 0 $ 12
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "PT1M18.77634S" $ CalendarDiffTime 0 $ 78.77634
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "PT2H1M18.77634S" $ CalendarDiffTime 0 $ 7278.77634
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P5DT2H1M18.77634S" $
+            CalendarDiffTime 0 $
+                5 * nominalDay + 7278.77634
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P7Y10M5DT2H1M18.77634S" $
+            CalendarDiffTime 94 $
+                5 * nominalDay + 7278.77634
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P7Y10MT2H1M18.77634S" $
+            CalendarDiffTime 94 $
+                7278.77634
+        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P8YT2H1M18.77634S" $ CalendarDiffTime 96 $ 7278.77634
+        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0001-00-00" $
+            CalendarDiffDays 12 0
+        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0002-03-29" $
+            CalendarDiffDays 27 29
+        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0561-08-29" $
+            CalendarDiffDays (561 * 12 + 8) 29
+        , testShowReadFormat
+            "alternativeDurationTimeFormat"
+            (alternativeDurationTimeFormat ExtendedFormat)
+            "P0000-00-01T00:00:00"
+            $ CalendarDiffTime 0 86400
+        , testShowReadFormat
+            "alternativeDurationTimeFormat"
+            (alternativeDurationTimeFormat ExtendedFormat)
+            "P0007-10-05T02:01:18.77634"
+            $ CalendarDiffTime 94
+            $ 5 * nominalDay + 7278.77634
+        , testShowReadFormat
+            "alternativeDurationTimeFormat"
+            (alternativeDurationTimeFormat ExtendedFormat)
+            "P4271-10-05T02:01:18.77634"
+            $ CalendarDiffTime (12 * 4271 + 10)
+            $ 5 * nominalDay + 7278.77634
+        , testShowReadFormat "centuryFormat" centuryFormat "02" 2
+        , testShowReadFormat "centuryFormat" centuryFormat "21" 21
+        , testShowReadFormat
+            "intervalFormat etc."
+            ( intervalFormat
+                (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
+                durationTimeFormat
+            )
+            "2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
+            ( LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
+            , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34
+            )
+        , testShowReadFormat
+            "recurringIntervalFormat etc."
+            ( recurringIntervalFormat
+                (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
+                durationTimeFormat
+            )
+            "R74/2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
+            ( 74
+            , LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
+            , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34
+            )
+        , testShowReadFormat
+            "recurringIntervalFormat etc."
+            (recurringIntervalFormat (calendarFormat ExtendedFormat) durationDaysFormat)
+            "R74/2015-06-13/P1Y2M7D"
+            (74, fromGregorian 2015 6 13, CalendarDiffDays 14 7)
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "-06:30" (minutesToTimeZone (-390))
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "-06:00" (minutesToTimeZone (-360))
+        , testReadFormat "timeOffsetFormat" iso8601Format "-06" (minutesToTimeZone (-360))
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "+11:00" (minutesToTimeZone 660)
+        , testReadFormat "timeOffsetFormat" iso8601Format "+11" (minutesToTimeZone 660)
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "+00:00" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" iso8601Format "+00" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" iso8601Format "-00:00" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" iso8601Format "-00" (minutesToTimeZone 0)
+        , testShowReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+0000" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+00" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "-0000" (minutesToTimeZone 0)
+        , testReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "-00" (minutesToTimeZone 0)
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "+00:10" (minutesToTimeZone 10)
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "-00:10" (minutesToTimeZone (-10))
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "+01:35" (minutesToTimeZone 95)
+        , testShowReadFormat "timeOffsetFormat" iso8601Format "-01:35" (minutesToTimeZone (-95))
+        , testShowReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+0135" (minutesToTimeZone 95)
+        , testShowReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "-0135" (minutesToTimeZone (-95))
+        , testShowReadFormat
+            "timeOffsetFormat"
+            (timeOffsetFormat BasicFormat)
+            "-1100"
+            (minutesToTimeZone $ negate $ 11 * 60)
+        , testShowReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+1015" (minutesToTimeZone $ 615)
+        , testShowReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553-06:30"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone (-390)))
+        , testShowReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553-06:00"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone (-360)))
+        , testReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553-06"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone (-360)))
+        , testShowReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553+06:30"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone 390))
+        , testShowReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553+06:00"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone 360))
+        , testReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553+06"
+            (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone 360))
+        , testReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-05-30T16:15:18Z"
+            (ZonedTime (LocalTime (fromGregorian 2024 05 30) (TimeOfDay 16 15 18)) utc)
+        , testReadFormat
+            "zonedTimeFormat"
+            iso8601Format
+            "2024-05-30T16:15:18"
+            (ZonedTime (LocalTime (fromGregorian 2024 05 30) (TimeOfDay 16 15 18)) utc)
+        , testShowReadFormat
+            "utcTimeFormat"
+            iso8601Format
+            "2024-07-06T08:45:56.553Z"
+            (UTCTime (fromGregorian 2024 07 06) (timeOfDayToTime $ TimeOfDay 8 45 56.553))
+        , testShowReadFormat
+            "utcTimeFormat"
+            iso8601Format
+            "2028-12-31T23:59:60.9Z"
+            (UTCTime (fromGregorian 2028 12 31) (timeOfDayToTime $ TimeOfDay 23 59 60.9))
+        , testReadFormat
+            "utcTimeFormat"
+            iso8601Format
+            "2028-12-31T23:59:60.9"
+            (UTCTime (fromGregorian 2028 12 31) (timeOfDayToTime $ TimeOfDay 23 59 60.9))
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1994-W52-7" (fromGregorian 1995 1 1)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1995-W01-1" (fromGregorian 1995 1 2)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1996-W52-7" (fromGregorian 1996 12 29)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1997-W01-2" (fromGregorian 1996 12 31)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1997-W01-3" (fromGregorian 1997 1 1)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1974-W32-6" (fromGregorian 1974 8 10)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat BasicFormat) "1974W326" (fromGregorian 1974 8 10)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat ExtendedFormat) "1995-W05-6" (fromGregorian 1995 2 4)
+        , testShowReadFormat "weekDateFormat" (weekDateFormat BasicFormat) "1995W056" (fromGregorian 1995 2 4)
+        , testShowReadFormat
+            "weekDateFormat"
+            (expandedWeekDateFormat 6 ExtendedFormat)
+            "+001995-W05-6"
+            (fromGregorian 1995 2 4)
+        , testShowReadFormat "weekDateFormat" (expandedWeekDateFormat 6 BasicFormat) "+001995W056" (fromGregorian 1995 2 4)
+        , testShowReadFormat "ordinalDateFormat" (ordinalDateFormat ExtendedFormat) "1846-235" (fromGregorian 1846 8 23)
+        , testShowReadFormat "ordinalDateFormat" (ordinalDateFormat BasicFormat) "1844236" (fromGregorian 1844 8 23)
+        , testShowReadFormat
+            "ordinalDateFormat"
+            (expandedOrdinalDateFormat 5 ExtendedFormat)
+            "+01846-235"
+            (fromGregorian 1846 8 23)
+        , testShowReadFormat "hourMinuteFormat" (hourMinuteFormat ExtendedFormat) "13:17.25" (TimeOfDay 13 17 15)
+        , testShowReadFormat "hourMinuteFormat" (hourMinuteFormat ExtendedFormat) "01:12.4" (TimeOfDay 1 12 24)
+        , testShowReadFormat "hourMinuteFormat" (hourMinuteFormat BasicFormat) "1317.25" (TimeOfDay 13 17 15)
+        , testShowReadFormat "hourMinuteFormat" (hourMinuteFormat BasicFormat) "0112.4" (TimeOfDay 1 12 24)
+        , testShowReadFormat "hourFormat" hourFormat "22" (TimeOfDay 22 0 0)
+        , testShowReadFormat "hourFormat" hourFormat "06" (TimeOfDay 6 0 0)
+        , testShowReadFormat "hourFormat" hourFormat "18.9475" (TimeOfDay 18 56 51)
         ]
 
 testISO8601 :: TestTree
diff --git a/test/main/Test/Format/ParseTime.hs b/test/main/Test/Format/ParseTime.hs
--- a/test/main/Test/Format/ParseTime.hs
+++ b/test/main/Test/Format/ParseTime.hs
@@ -1,28 +1,25 @@
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Test.Format.ParseTime
-    ( testParseTime
-    , test_parse_format
-    ) where
+module Test.Format.ParseTime (
+    testParseTime,
+    test_parse_format,
+) where
 
-#if MIN_VERSION_base(4,11,0)
-#else
-import Data.Semigroup hiding (option)
-#endif
 import Control.Monad
 import Data.Char
 import Data.Maybe
 import Data.Proxy
 import Data.Time
+import Data.Time.Calendar.Month
 import Data.Time.Calendar.OrdinalDate
+import Data.Time.Calendar.Quarter
 import Data.Time.Calendar.WeekDate
-import Test.Arbitrary ()
+import Test.Arbitrary (supportedDayRange)
 import Test.QuickCheck.Property
 import Test.Tasty
 import Test.Tasty.HUnit
 import Test.Tasty.QuickCheck hiding (reason)
 import Test.TestUtil
-import Text.Read
 
 format :: FormatTime t => String -> t -> String
 format f t = formatTime defaultTimeLocale f t
@@ -42,15 +39,17 @@
     }
 
 instance Show (FormatCode pf t) where
-    show (MkFormatCode m w a s) = let
-        ms = m
-        ws = fromMaybe "" $ fmap show w
-        as =
-            if a
-                then "E"
-                else ""
-        ss = [s]
-        in '%' : (ms <> ws <> as <> ss)
+    show (MkFormatCode m w a s) =
+        let
+            ms = m
+            ws = fromMaybe "" $ fmap show w
+            as =
+                if a
+                    then "E"
+                    else ""
+            ss = [s]
+        in
+            '%' : (ms <> ws <> as <> ss)
 
 formatCode :: FormatTime t => FormatCode pf t -> t -> String
 formatCode fc = format $ show fc
@@ -60,27 +59,28 @@
 
 class HasFormatCodes t where
     allFormatCodes :: Proxy t -> [(Bool, Char)]
+    incompleteS :: Maybe t
+    incompleteS = Nothing
 
 minCodeWidth :: Char -> Int
 minCodeWidth _ = 0
 
 fcShrink :: FormatCode pf t -> [FormatCode pf t]
-fcShrink fc = let
-    fc1 =
-        case fcWidth fc of
+fcShrink fc =
+    let
+        fc1 = case fcWidth fc of
             Nothing -> []
             Just w
-                | w > (minCodeWidth $ fcSpecifier fc) -> [fc {fcWidth = Nothing}, fc {fcWidth = Just $ w - 1}]
-            Just _ -> [fc {fcWidth = Nothing}]
-    fc2 =
-        case fcAlt fc of
+                | w > (minCodeWidth $ fcSpecifier fc) -> [fc{fcWidth = Nothing}, fc{fcWidth = Just $ w - 1}]
+            Just _ -> [fc{fcWidth = Nothing}]
+        fc2 = case fcAlt fc of
             False -> []
-            True -> [fc {fcAlt = False}]
-    fc3 =
-        case fcModifier fc of
+            True -> [fc{fcAlt = False}]
+        fc3 = case fcModifier fc of
             "" -> []
-            _ -> [fc {fcModifier = ""}]
-    in fc1 ++ fc2 ++ fc3
+            _ -> [fc{fcModifier = ""}]
+    in
+        fc1 ++ fc2 ++ fc3
 
 instance HasFormatCodes t => Arbitrary (FormatCode FormatOnly t) where
     arbitrary = do
@@ -108,10 +108,10 @@
 testParseTime =
     testGroup
         "testParseTime"
-        [ readOtherTypesTest
-        , readTests
+        [ readsTests
         , simpleFormatTests
         , extests
+        , spacingTests
         , particularParseTests
         , badParseTests
         , defaultTimeZoneTests
@@ -129,69 +129,71 @@
 extests =
     testGroup
         "exhaustive"
-        ([ makeExhaustiveTest "parse %y" [0 .. 99] parseYY
-         , makeExhaustiveTest "parse %-C %y 1900s" [0, 1, 50, 99] (parseCYY 19)
-         , makeExhaustiveTest "parse %-C %y 2000s" [0, 1, 50, 99] (parseCYY 20)
-         , makeExhaustiveTest "parse %-C %y 1400s" [0, 1, 50, 99] (parseCYY 14)
-         , makeExhaustiveTest "parse %C %y 0700s" [0, 1, 50, 99] (parseCYY2 7)
-         , makeExhaustiveTest "parse %-C %y 700s" [0, 1, 50, 99] (parseCYY 7)
-         , makeExhaustiveTest "parse %-C %y -700s" [0, 1, 50, 99] (parseCYY (-7))
-         , makeExhaustiveTest "parse %-C %y -70000s" [0, 1, 50, 99] (parseCYY (-70000))
-         , makeExhaustiveTest "parse %-C %y 10000s" [0, 1, 50, 99] (parseCYY 100)
-         , makeExhaustiveTest "parse %-C centuries" [20 .. 100] (parseCentury " ")
-         , makeExhaustiveTest "parse %-C century X" [1, 10, 20, 100] (parseCentury "X")
-         , makeExhaustiveTest "parse %-C century 2sp" [1, 10, 20, 100] (parseCentury "  ")
-         , makeExhaustiveTest "parse %-C century 5sp" [1, 10, 20, 100] (parseCentury "     ")
-         ] ++
-         (concat $
-          fmap
-              (\y ->
-                   [ (makeExhaustiveTest "parse %Y%m%d" (yearDays y) parseYMD)
-                   , (makeExhaustiveTest "parse %Y %m %d" (yearDays y) parseYearDayD)
-                   , (makeExhaustiveTest "parse %Y %-m %e" (yearDays y) parseYearDayE)
-                   ])
-              [1, 4, 20, 753, 2000, 2011, 10001, (-1166)]))
+        ( [ makeExhaustiveTest "parse %y" [0 .. 99] parseYY
+          , makeExhaustiveTest "parse %-C %y 1900s" [0, 1, 50, 99] (parseCYY 19)
+          , makeExhaustiveTest "parse %-C %y 2000s" [0, 1, 50, 99] (parseCYY 20)
+          , makeExhaustiveTest "parse %-C %y 1400s" [0, 1, 50, 99] (parseCYY 14)
+          , makeExhaustiveTest "parse %C %y 0700s" [0, 1, 50, 99] (parseCYY2 7)
+          , makeExhaustiveTest "parse %-C %y 700s" [0, 1, 50, 99] (parseCYY 7)
+          , makeExhaustiveTest "parse %-C %y -700s" [0, 1, 50, 99] (parseCYY (-7))
+          , makeExhaustiveTest "parse %-C %y -70000s" [0, 1, 50, 99] (parseCYY (-70000))
+          , makeExhaustiveTest "parse %-C %y 10000s" [0, 1, 50, 99] (parseCYY 100)
+          , makeExhaustiveTest "parse %-C centuries" [20 .. 100] (parseCentury " ")
+          , makeExhaustiveTest "parse %-C century X" [1, 10, 20, 100] (parseCentury "X")
+          , makeExhaustiveTest "parse %-C century 2sp" [1, 10, 20, 100] (parseCentury "  ")
+          , makeExhaustiveTest "parse %-C century 5sp" [1, 10, 20, 100] (parseCentury "     ")
+          ]
+            ++ ( concat $
+                    fmap
+                        ( \y ->
+                            [ {- (makeExhaustiveTest "parse %Y%m%d" (yearDays y) parseYMD)
+                              , -} (makeExhaustiveTest "parse %Y %m %d" (yearDays y) parseYearDayD)
+                            , (makeExhaustiveTest "parse %Y %-m %e" (yearDays y) parseYearDayE)
+                            ]
+                        )
+                        [1, 4, 20, 753, 2000, 2011, 10001, (-1166)]
+               )
+        )
 
-readTest :: (Eq a, Show a, Read a) => [(a, String)] -> String -> TestTree
-readTest expected target = let
-    found = reads target
-    result = assertEqual "" expected found
-    name = show target
-    in Test.Tasty.HUnit.testCase name result
+testReads :: (Eq a, Show a, Read a) => [(a, String)] -> String -> TestTree
+testReads expected target =
+    let
+        found = reads target
+        result = assertEqual "" expected found
+        name = show target
+    in
+        Test.Tasty.HUnit.testCase name result
 
-readTestsParensSpaces ::
-       forall a. (Eq a, Show a, Read a)
-    => a
-    -> String
-    -> TestTree
-readTestsParensSpaces expected target =
+readsTestsParensSpaces ::
+    forall a.
+    (Eq a, Show a, Read a) =>
+    a ->
+    String ->
+    TestTree
+readsTestsParensSpaces expected target =
     testGroup
         target
-        [ readTest [(expected, "")] $ target
-        , readTest [(expected, "")] $ "(" ++ target ++ ")"
-        , readTest [(expected, "")] $ " (" ++ target ++ ")"
-        , readTest [(expected, " ")] $ " ( " ++ target ++ " ) "
-        , readTest [(expected, " ")] $ " (( " ++ target ++ " )) "
-        , readTest ([] :: [(a, String)]) $ "(" ++ target
-        , readTest [(expected, ")")] $ "" ++ target ++ ")"
-        , readTest [(expected, "")] $ "((" ++ target ++ "))"
-        , readTest [(expected, " ")] $ "  (   (     " ++ target ++ "   )  ) "
+        [ testReads [(expected, "")] $ target
+        , testReads [(expected, "")] $ "(" ++ target ++ ")"
+        , testReads [(expected, "")] $ " (" ++ target ++ ")"
+        , testReads [(expected, " ")] $ " ( " ++ target ++ " ) "
+        , testReads [(expected, " ")] $ " (( " ++ target ++ " )) "
+        , testReads ([] :: [(a, String)]) $ "(" ++ target
+        , testReads [(expected, ")")] $ "" ++ target ++ ")"
+        , testReads [(expected, "")] $ "((" ++ target ++ "))"
+        , testReads [(expected, " ")] $ "  (   (     " ++ target ++ "   )  ) "
         ]
-  where
 
-
-readOtherTypesTest :: TestTree
-readOtherTypesTest =
-    testGroup "read other types" [readTestsParensSpaces (3 :: Integer) "3", readTestsParensSpaces "a" "\"a\""]
-
-readTests :: TestTree
-readTests =
+readsTests :: TestTree
+readsTests =
     testGroup
-        "read times"
-        [ readTestsParensSpaces testDay "1912-07-08"
-    --readTestsParensSpaces testDay "1912-7-8",
-        , readTestsParensSpaces testTimeOfDay "08:04:02"
-    --,readTestsParensSpaces testTimeOfDay "8:4:2"
+        "reads"
+        [ readsTestsParensSpaces (3 :: Integer) "3"
+        , readsTestsParensSpaces "a" "\"a\""
+        , readsTestsParensSpaces testDay "1912-07-08"
+        , -- , readsTestsParensSpaces testDay "1912-7-8"
+          readsTestsParensSpaces testTimeOfDay "08:04:02"
+          -- , readsTestsParensSpaces testTimeOfDay "8:4:2"
         ]
   where
     testDay = fromGregorian 1912 7 8
@@ -200,43 +202,45 @@
 epoch :: LocalTime
 epoch = LocalTime (fromGregorian 1970 0 0) midnight
 
+testReadSTime :: (Show a, Eq a, ParseTime a) => [(a, String)] -> String -> String -> TestTree
+testReadSTime expected formatStr target =
+    let
+        found = readSTime False defaultTimeLocale formatStr target
+        result = assertEqual "" expected found
+        name = (show formatStr) ++ " of " ++ (show target)
+    in
+        Test.Tasty.HUnit.testCase name result
+
 simpleFormatTests :: TestTree
 simpleFormatTests =
     testGroup
         "simple"
-        [ readsTest [(epoch, "")] "" ""
-        , readsTest [(epoch, " ")] "" " "
-        , readsTest [(epoch, "")] " " " "
-        , readsTest [(epoch, "")] " " "  "
-        , readsTest [(epoch, "")] "%k" "0"
-        , readsTest [(epoch, "")] "%k" " 0"
-        , readsTest [(epoch, "")] "%m" "01"
-        , readsTest [(epoch, " ")] "%m" "01 "
-        , readsTest [(epoch, " ")] " %m" " 01 "
-        , readsTest [(epoch, "")] " %m" " 01"
-    -- https://ghc.haskell.org/trac/ghc/ticket/9150
-        , readsTest [(epoch, "")] " %M" " 00"
-        , readsTest [(epoch, "")] "%M " "00 "
-        , readsTest [(epoch, "")] "%Q" ""
-        , readsTest [(epoch, " ")] "%Q" " "
-        , readsTest [(epoch, "X")] "%Q" "X"
-        , readsTest [(epoch, " X")] "%Q" " X"
-        , readsTest [(epoch, "")] "%Q " " "
-        , readsTest [(epoch, "")] "%Q X" " X"
-        , readsTest [(epoch, "")] "%QX" "X"
+        [ testReadSTime [(epoch, "")] "" ""
+        , testReadSTime [(epoch, " ")] "" " "
+        , testReadSTime [(epoch, "")] " " " "
+        , testReadSTime [(epoch, "")] " " "  "
+        , testReadSTime [(epoch, "")] "%k" "0"
+        , testReadSTime [(epoch, "")] "%k" " 0"
+        , testReadSTime [(epoch, "")] "%m" "01"
+        , testReadSTime [(epoch, " ")] "%m" "01 "
+        , testReadSTime [(epoch, " ")] " %m" " 01 "
+        , testReadSTime [(epoch, "")] " %m" " 01"
+        , -- https://ghc.haskell.org/trac/ghc/ticket/9150
+          testReadSTime [(epoch, "")] " %M" " 00"
+        , testReadSTime [(epoch, "")] "%M " "00 "
+        , testReadSTime [(epoch, "")] "%Q" ""
+        , testReadSTime [(epoch, " ")] "%Q" " "
+        , testReadSTime [(epoch, "X")] "%Q" "X"
+        , testReadSTime [(epoch, " X")] "%Q" " X"
+        , testReadSTime [(epoch, "")] "%Q " " "
+        , testReadSTime [(epoch, "")] "%Q X" " X"
+        , testReadSTime [(epoch, "")] "%QX" "X"
         ]
-  where
-    readsTest :: (Show a, Eq a, ParseTime a) => [(a, String)] -> String -> String -> TestTree
-    readsTest expected formatStr target = let
-        found = readSTime False defaultTimeLocale formatStr target
-        result = assertEqual "" expected found
-        name = (show formatStr) ++ " of " ++ (show target)
-        in Test.Tasty.HUnit.testCase name result
 
-spacingTests :: (Show t, Eq t, ParseTime t) => t -> String -> String -> TestTree
-spacingTests expected formatStr target =
+spacingForFormatTests :: (Show t, Eq t, ParseTime t) => t -> String -> String -> TestTree
+spacingForFormatTests expected formatStr target =
     testGroup
-        "particular"
+        formatStr
         [ parseTest False (Just expected) formatStr target
         , parseTest True (Just expected) formatStr target
         , parseTest False (Just expected) (formatStr ++ " ") (target ++ " ")
@@ -247,42 +251,48 @@
         , parseTest True (Just expected) (" " ++ formatStr) ("  " ++ target)
         ]
 
+spacingTests :: TestTree
+spacingTests =
+    testGroup
+        "spacing"
+        [ spacingForFormatTests epoch "%Q" ""
+        , spacingForFormatTests epoch "%Q" ".0"
+        , spacingForFormatTests epoch "%k" " 0"
+        , spacingForFormatTests epoch "%M" "00"
+        , spacingForFormatTests epoch "%m" "01"
+        , spacingForFormatTests (TimeZone 120 False "") "%z" "+0200"
+        , spacingForFormatTests (TimeZone 120 False "") "%Z" "+0200"
+        , spacingForFormatTests (TimeZone (-480) False "PST") "%Z" "PST"
+        ]
+
 particularParseTests :: TestTree
 particularParseTests =
     testGroup
         "particular"
-        [ spacingTests epoch "%Q" ""
-        , spacingTests epoch "%Q" ".0"
-        , spacingTests epoch "%k" " 0"
-        , spacingTests epoch "%M" "00"
-        , spacingTests epoch "%m" "01"
-        , spacingTests (TimeZone 120 False "") "%z" "+0200"
-        , spacingTests (TimeZone 120 False "") "%Z" "+0200"
-        , spacingTests (TimeZone (-480) False "PST") "%Z" "PST"
+        [ parseTest @Day True Nothing "%-d%-m%0Y" "2122012" -- ISSUE #232
+        , parseTest @Day True Nothing "%-d%-m%0Y" "2132012" -- ISSUE #232
         ]
 
 badParseTests :: TestTree
 badParseTests = testGroup "bad" [parseTest False (Nothing :: Maybe Day) "%Y" ""]
 
+{-
 parseYMD :: Day -> TestTree
-parseYMD day =
-    case toGregorian day of
-        (y, m, d) -> parseTest False (Just day) "%Y%m%d" ((show y) ++ (show2 m) ++ (show2 d))
+parseYMD day = case toGregorian day of
+    (y, m, d) -> parseTest False (Just day) "%Y%m%d" ((show y) ++ (show2 m) ++ (show2 d))
+-}
 
 parseYearDayD :: Day -> TestTree
-parseYearDayD day =
-    case toGregorian day of
-        (y, m, d) -> parseTest False (Just day) "%Y %m %d" ((show y) ++ " " ++ (show2 m) ++ " " ++ (show2 d))
+parseYearDayD day = case toGregorian day of
+    (y, m, d) -> parseTest False (Just day) "%Y %m %d" ((show y) ++ " " ++ (show2 m) ++ " " ++ (show2 d))
 
 parseYearDayE :: Day -> TestTree
-parseYearDayE day =
-    case toGregorian day of
-        (y, m, d) -> parseTest False (Just day) "%Y %-m %e" ((show y) ++ " " ++ (show m) ++ " " ++ (show d))
+parseYearDayE day = case toGregorian day of
+    (y, m, d) -> parseTest False (Just day) "%Y %-m %e" ((show y) ++ " " ++ (show m) ++ " " ++ (show d))
 
 -- | 1969 - 2068
 expectedYear :: Integer -> Integer
-expectedYear i
-    | i >= 69 = 1900 + i
+expectedYear i | i >= 69 = 1900 + i
 expectedYear i = 2000 + i
 
 show2 :: (Show n, Integral n) => n -> String
@@ -301,33 +311,29 @@
 parseCentury int c =
     parseTest False (Just (fromGregorian (c * 100) 1 1)) ("%-C" ++ int ++ "%y") ((show c) ++ int ++ "00")
 
-parseTest :: (Show t, Eq t, ParseTime t) => Bool -> Maybe t -> String -> String -> TestTree
-parseTest sp expected formatStr target = let
-    found = parse sp formatStr target
-    result = assertEqual "" expected found
-    name =
-        (show formatStr) ++
-        " of " ++
-        (show target) ++
-        (if sp
-             then " allowing spaces"
-             else "")
-    in Test.Tasty.HUnit.testCase name result
+parseTest :: forall t. (Show t, Eq t, ParseTime t) => Bool -> Maybe t -> String -> String -> TestTree
+parseTest sp expected formatStr target =
+    let
+        found = parse sp formatStr target
+        result = assertEqual "" expected found
+        name =
+            (show formatStr)
+                ++ " of "
+                ++ (show target)
+                ++ ( if sp
+                        then " allowing spaces"
+                        else ""
+                   )
+    in
+        Test.Tasty.HUnit.testCase name result
 
-{-
-readsTest :: forall t. (Show t, Eq t, ParseTime t) => Maybe t -> String -> String -> TestTree
-readsTest (Just e) = readsTest' [(e,"")]
-readsTest Nothing = readsTest' ([] :: [(t,String)])
--}
-enumAdd :: (Enum a) => Int -> a -> a
+enumAdd :: Enum a => Int -> a -> a
 enumAdd i a = toEnum (i + fromEnum a)
 
 getMilZoneLetter :: Int -> Char
 getMilZoneLetter 0 = 'Z'
-getMilZoneLetter h
-    | h < 0 = enumAdd (negate h) 'M'
-getMilZoneLetter h
-    | h < 10 = enumAdd (h - 1) 'A'
+getMilZoneLetter h | h < 0 = enumAdd (negate h) 'M'
+getMilZoneLetter h | h < 10 = enumAdd (h - 1) 'A'
 getMilZoneLetter h = enumAdd (h - 10) 'K'
 
 getMilZone :: Int -> TimeZone
@@ -349,35 +355,56 @@
 compareResult' :: (Eq a, Show a) => String -> a -> a -> Result
 compareResult' extra expected found
     | expected == found = succeeded
-    | otherwise = failed {reason = "expected " ++ (show expected) ++ ", found " ++ (show found) ++ extra}
+    | otherwise = failed{reason = "expected " ++ (show expected) ++ ", found " ++ (show found) ++ extra}
 
 compareResult :: (Eq a, Show a) => a -> a -> Result
 compareResult = compareResult' ""
 
 compareParse ::
-       forall a. (Eq a, Show a, ParseTime a)
-    => a
-    -> String
-    -> String
-    -> Result
+    forall a.
+    (Eq a, Show a, ParseTime a) =>
+    a ->
+    String ->
+    String ->
+    Result
 compareParse expected fmt text = compareResult' (", parsing " ++ (show text)) (Just expected) (parse False fmt text)
 
 --
+
 -- * tests for debugging failing cases
+
 --
 test_parse_format :: (FormatTime t, ParseTime t, Show t) => String -> t -> (String, String, Maybe t)
-test_parse_format f t = let
-    s = format f t
-    in (show t, s, parse False f s `asTypeOf` Just t)
+test_parse_format f t =
+    let
+        s = format f t
+    in
+        (show t, s, parse False f s `asTypeOf` Just t)
 
 --
+
 -- * show and read
+
 --
+reads_expect :: a -> [(a, String)]
+reads_expect t = [(t, "")]
+
 prop_read_show :: (Read a, Show a, Eq a) => a -> Result
-prop_read_show t = compareResult (Just t) (readMaybe (show t))
+prop_read_show t = compareResult (reads_expect t) (reads (show t))
 
+prop_read_show_ZonedUTC :: ZonedTime -> Result
+prop_read_show_ZonedUTC t = compareResult (reads_expect $ zonedTimeToUTC t) (reads (show t))
+
+prop_read_show_LocalUTC :: LocalTime -> Result
+prop_read_show_LocalUTC t = compareResult (reads_expect $ localTimeToUTC utc t) (reads (show t))
+
+prop_read_show_UTC_no_TZ :: UTCTime -> Result
+prop_read_show_UTC_no_TZ t = compareResult (reads_expect t) $ reads $ show $ utcToLocalTime utc t
+
 --
+
 -- * special show functions
+
 --
 prop_parse_showWeekDate :: Day -> Result
 prop_parse_showWeekDate d = compareParse d "%G-W%V-%u" (showWeekDate d)
@@ -389,19 +416,25 @@
 prop_parse_showOrdinalDate d = compareParse d "%Y-%j" (showOrdinalDate d)
 
 --
+
 -- * fromMondayStartWeek and fromSundayStartWeek
+
 --
 prop_fromMondayStartWeek :: Day -> Result
-prop_fromMondayStartWeek d = let
-    (w, wd) = mondayStartWeek d
-    (y, _, _) = toGregorian d
-    in compareResult d (fromMondayStartWeek y w wd)
+prop_fromMondayStartWeek d =
+    let
+        (w, wd) = mondayStartWeek d
+        (y, _, _) = toGregorian d
+    in
+        compareResult d (fromMondayStartWeek y w wd)
 
 prop_fromSundayStartWeek :: Day -> Result
-prop_fromSundayStartWeek d = let
-    (w, wd) = sundayStartWeek d
-    (y, _, _) = toGregorian d
-    in compareResult d (fromSundayStartWeek y w wd)
+prop_fromSundayStartWeek d =
+    let
+        (w, wd) = sundayStartWeek d
+        (y, _, _) = toGregorian d
+    in
+        compareResult d (fromSundayStartWeek y w wd)
 
 -- t == parse (format t)
 prop_parse_format :: (Eq t, FormatTime t, ParseTime t, Show t) => FormatString t -> t -> Result
@@ -416,29 +449,30 @@
 prop_parse_format_lower (FormatString f) t = compareParse t f (map toLower $ format f t)
 
 -- Default time is 1970-01-01 00:00:00 +0000 (which was a Thursday)
-in1970 :: Char -> String -> Bool
-in1970 'j' "366" = False -- 1970 was not a leap year
-in1970 'U' "53" = False -- last day of 1970 was Sunday-start-week 52
-in1970 'W' "53" = False -- last day of 1970 was Monday-start-week 52
-in1970 _ _ = True
+in1970 :: Maybe String -> Char -> String -> Maybe String
+in1970 _ 'j' "366" = Nothing -- 1970 was not a leap year
+in1970 _ 'U' "53" = Nothing -- last day of 1970 was Sunday-start-week 52
+in1970 _ 'W' "53" = Nothing -- last day of 1970 was Monday-start-week 52
+in1970 (Just s) 'S' "60" = Just s -- no leap second without other data
+in1970 _ _ s = Just s
 
 -- format t == format (parse (format t))
 prop_format_parse_format ::
-       forall t. (FormatTime t, ParseTime t)
-    => Proxy t
-    -> FormatCode ParseAndFormat t
-    -> t
-    -> Result
-prop_format_parse_format _ fc v = let
-    s1 = formatCode fc v
-    ms1 =
-        if in1970 (fcSpecifier fc) s1
-            then Just s1
-            else Nothing
-    mv2 :: Maybe t
-    mv2 = parseCode fc s1
-    ms2 = fmap (formatCode fc) mv2
-    in compareResult ms1 ms2
+    forall t.
+    (HasFormatCodes t, FormatTime t, ParseTime t) =>
+    Proxy t ->
+    FormatCode ParseAndFormat t ->
+    t ->
+    Result
+prop_format_parse_format _ fc v =
+    let
+        s1 = formatCode fc v
+        ms1 = in1970 (fmap (formatCode fc) (incompleteS :: Maybe t)) (fcSpecifier fc) s1
+        mv2 :: Maybe t
+        mv2 = parseCode fc s1
+        ms2 = fmap (formatCode fc) mv2
+    in
+        compareResult ms1 ms2
 
 instance HasFormatCodes Day where
     allFormatCodes _ = [(False, s) | s <- "DFxYyCBbhmdejfVUW"]
@@ -446,6 +480,18 @@
 instance HasFormatCodes TimeOfDay where
     allFormatCodes _ = [(False, s) | s <- "RTXrPpHkIlMSqQ"]
 
+instance HasFormatCodes DayOfWeek where
+    allFormatCodes _ = [(False, s) | s <- "uwaA"]
+
+instance HasFormatCodes Month where
+    allFormatCodes _ = [(False, s) | s <- "YyCBbhm"]
+
+instance HasFormatCodes QuarterOfYear where
+    allFormatCodes _ = [(False, s) | s <- "v"]
+
+instance HasFormatCodes Quarter where
+    allFormatCodes _ = allFormatCodes (Proxy :: Proxy QuarterOfYear) ++ [(False, s) | s <- "YyC"]
+
 instance HasFormatCodes LocalTime where
     allFormatCodes _ = allFormatCodes (Proxy :: Proxy Day) ++ allFormatCodes (Proxy :: Proxy TimeOfDay)
 
@@ -454,20 +500,24 @@
 
 instance HasFormatCodes ZonedTime where
     allFormatCodes _ =
-        [(False, s) | s <- "cs"] ++
-        allFormatCodes (Proxy :: Proxy LocalTime) ++ allFormatCodes (Proxy :: Proxy TimeZone)
+        [(False, s) | s <- "cs"]
+            ++ allFormatCodes (Proxy :: Proxy LocalTime)
+            ++ allFormatCodes (Proxy :: Proxy TimeZone)
 
 instance HasFormatCodes UTCTime where
     allFormatCodes _ = [(False, s) | s <- "cs"] ++ allFormatCodes (Proxy :: Proxy LocalTime)
+    incompleteS = Just $ UTCTime (fromGregorian 2000 1 1) 0
 
 instance HasFormatCodes UniversalTime where
     allFormatCodes _ = allFormatCodes (Proxy :: Proxy LocalTime)
 
 --
+
 -- * crashes in parse
+
 --
-newtype Input =
-    Input String
+newtype Input
+    = Input String
 
 instance Show Input where
     show (Input s) = s
@@ -484,15 +534,15 @@
 prop_no_crash_bad_input :: (Eq t, ParseTime t) => FormatString t -> Input -> Property
 prop_no_crash_bad_input fs@(FormatString f) (Input s) =
     property $
-    case parse False f s of
-        Nothing -> True
-        Just t -> t == t `asTypeOf` formatType fs
+        case parse False f s of
+            Nothing -> True
+            Just t -> t == t `asTypeOf` formatType fs
 
 --
 --
 --
-newtype FormatString a =
-    FormatString String
+newtype FormatString a
+    = FormatString String
 
 formatType :: FormatString t -> t
 formatType _ = undefined
@@ -503,26 +553,33 @@
 typedTests :: (forall t. (Eq t, FormatTime t, ParseTime t, Show t) => FormatString t -> t -> Result) -> [TestTree]
 typedTests prop =
     [ nameTest "Day" $ tgroup dayFormats prop
+    , nameTest "Month" $ tgroup monthFormats prop
+    , nameTest "Quarter" $ tgroup quarterFormats prop
     , nameTest "TimeOfDay" $ tgroup timeOfDayFormats prop
     , nameTest "LocalTime" $ tgroup localTimeFormats prop
     , nameTest "TimeZone" $ tgroup timeZoneFormats prop
     , nameTest "ZonedTime" $ tgroup zonedTimeFormats prop
     , nameTest "ZonedTime" $
-      tgroup zonedTimeAlmostFormats $ \fmt t -> (todSec $ localTimeOfDay $ zonedTimeToLocalTime t) < 60 ==> prop fmt t
+        tgroup zonedTimeAlmostFormats $
+            \fmt t -> (todSec $ localTimeOfDay $ zonedTimeToLocalTime t) < 60 ==> prop fmt t
     , nameTest "UTCTime" $ tgroup utcTimeAlmostFormats $ \fmt t -> utctDayTime t < 86400 ==> prop fmt t
     , nameTest "UniversalTime" $ tgroup universalTimeFormats prop
     , nameTest "CalendarDiffDays" $ tgroup calendarDiffDaysFormats prop
-    , nameTest "CalenderDiffTime" $ tgroup calendarDiffTimeFormats prop
+    , nameTest "CalendarDiffTime" $ tgroup calendarDiffTimeFormats prop
     , nameTest "DiffTime" $ tgroup diffTimeFormats prop
     , nameTest "NominalDiffTime" $ tgroup nominalDiffTimeFormats prop
     ]
 
 allTypes ::
-       (forall t. (Eq t, Show t, Arbitrary t, FormatTime t, ParseTime t, HasFormatCodes t) => String -> Proxy t -> r)
-    -> [r]
+    (forall t. (Eq t, Show t, Arbitrary t, FormatTime t, ParseTime t, HasFormatCodes t) => String -> Proxy t -> r) ->
+    [r]
 allTypes f =
     [ f "Day" (Proxy :: Proxy Day)
     , f "TimeOfDay" (Proxy :: Proxy TimeOfDay)
+    , f "DayOfWeek" (Proxy :: Proxy DayOfWeek)
+    , f "Month" (Proxy :: Proxy Month)
+    , f "QuarterOfYear" (Proxy :: Proxy QuarterOfYear)
+    , f "Quarter" (Proxy :: Proxy Quarter)
     , f "LocalTime" (Proxy :: Proxy LocalTime)
     , f "TimeZone" (Proxy :: Proxy TimeZone)
     , f "ZonedTime" (Proxy :: Proxy ZonedTime)
@@ -530,10 +587,33 @@
     , f "UniversalTime" (Proxy :: Proxy UniversalTime)
     ]
 
+allLeapSecondTypes ::
+    (forall t. (Eq t, Show t, Arbitrary t, FormatTime t, ParseTime t, HasFormatCodes t) => String -> t -> r) ->
+    [r]
+allLeapSecondTypes f =
+    let
+        day :: Day
+        day = fromGregorian 2000 01 01
+        lsTimeOfDay :: TimeOfDay
+        lsTimeOfDay = TimeOfDay 23 59 60.5
+        lsLocalTime :: LocalTime
+        lsLocalTime = LocalTime day lsTimeOfDay
+        lsZonedTime :: ZonedTime
+        lsZonedTime = ZonedTime lsLocalTime utc
+        lsUTCTime :: UTCTime
+        lsUTCTime = UTCTime day 86400.5
+    in
+        [ f "TimeOfDay" lsTimeOfDay
+        , f "LocalTime" lsLocalTime
+        , f "ZonedTime" lsZonedTime
+        , f "UTCTime" lsUTCTime
+        ]
+
 parseEmptyTest ::
-       forall t. ParseTime t
-    => Proxy t
-    -> Assertion
+    forall t.
+    ParseTime t =>
+    Proxy t ->
+    Assertion
 parseEmptyTest _ =
     case parse False "" "" :: Maybe t of
         Just _ -> return ()
@@ -542,10 +622,99 @@
 parseEmptyTests :: TestTree
 parseEmptyTests = nameTest "parse empty" $ allTypes $ \name p -> nameTest name $ parseEmptyTest p
 
+class (Eq a, Show a, ParseTime a) => TestParse a where
+    nonPosixValue :: a -> Bool
+    nonPosixValue _ = False
+
+instance TestParse UTCTime where
+    nonPosixValue (UTCTime _ dt) = dt >= 86400 || dt < 0
+
+instance TestParse ZonedTime where
+    nonPosixValue (ZonedTime t _) = nonPosixValue t
+
+instance TestParse TimeZone
+
+instance TestParse LocalTime where
+    nonPosixValue (LocalTime _ t) = nonPosixValue t
+
+instance TestParse Day
+
+instance TestParse Month
+
+instance TestParse DayOfWeek
+
+instance TestParse TimeOfDay where
+    nonPosixValue (TimeOfDay _ _ s) = s >= 60 || s < 0
+
+prop_parse_s :: forall a. TestParse a => (UTCTime -> a) -> UTCTime -> Result
+prop_parse_s f t =
+    if nonPosixValue t
+        then succeeded
+        else
+            let
+                str = format "%s%Q" t
+                found = parse False "%s%Q" str
+                expected = f t
+            in
+                compareResult (Just expected) found
+
+prop_parse_sz :: forall a. TestParse a => (ZonedTime -> a) -> ZonedTime -> Result
+prop_parse_sz f t =
+    if nonPosixValue t
+        then succeeded
+        else
+            let
+                str = format "%s%Q %z" t
+                found = parse False "%s%Q %z" str
+                expected = f t
+            in
+                compareResult (Just expected) found
+
+zeroTimeZone :: TimeZone
+zeroTimeZone = TimeZone 0 False ""
+
+parse_s_tests :: TestTree
+parse_s_tests =
+    nameTest
+        "parse_s"
+        [ nameTest "UTCTime" $ prop_parse_s @UTCTime id
+        , nameTest "ZonedTime" $ prop_parse_s @ZonedTime $ utcToZonedTime zeroTimeZone
+        , nameTest "TimeZone" $ prop_parse_s @TimeZone $ \_ -> zeroTimeZone
+        , nameTest "LocalTime" $ prop_parse_s @LocalTime $ utcToLocalTime zeroTimeZone
+        , nameTest "Day" $ prop_parse_s @Day utctDay
+        , nameTest "Month" $ prop_parse_s @Month $ (\(MonthDay m _) -> m) . utctDay
+        , nameTest "DayOfWeek" $ prop_parse_s @DayOfWeek $ dayOfWeek . utctDay
+        , nameTest "TimeOfDay" $ prop_parse_s @TimeOfDay $ localTimeOfDay . utcToLocalTime zeroTimeZone
+        ]
+
+parse_sz_tests :: TestTree
+parse_sz_tests =
+    nameTest
+        "parse_sz"
+        [ nameTest "UTCTime" $ prop_parse_sz @UTCTime zonedTimeToUTC
+        , nameTest "ZonedTime" $ prop_parse_sz @ZonedTime id
+        , nameTest "TimeZone" $ prop_parse_sz @TimeZone zonedTimeZone
+        , nameTest "LocalTime" $ prop_parse_sz @LocalTime zonedTimeToLocalTime
+        , nameTest "Day" $ prop_parse_sz @Day $ localDay . zonedTimeToLocalTime
+        , nameTest "Month" $ prop_parse_sz @Month $ (\(MonthDay m _) -> m) . localDay . zonedTimeToLocalTime
+        , nameTest "DayOfWeek" $ prop_parse_sz @DayOfWeek $ dayOfWeek . localDay . zonedTimeToLocalTime
+        , nameTest "TimeOfDay" $ prop_parse_sz @TimeOfDay $ localTimeOfDay . zonedTimeToLocalTime
+        ]
+
 formatParseFormatTests :: TestTree
 formatParseFormatTests =
-    localOption (QuickCheckTests 50000) $
-    nameTest "format_parse_format" $ allTypes $ \name p -> nameTest name $ prop_format_parse_format p
+    nameTest
+        "format_parse_format"
+        [ localOption (QuickCheckTests 50000) $
+            nameTest "general" $
+                allTypes $
+                    \name p -> nameTest name $ prop_format_parse_format p
+        , nameTest "#177" $
+            [ nameTest "start" $ \fc -> prop_format_parse_format Proxy fc (fst supportedDayRange)
+            , nameTest "end" $ \fc -> prop_format_parse_format Proxy fc (snd supportedDayRange)
+            ]
+        , nameTest "leapsecond" $ allLeapSecondTypes $ \name t -> nameTest name $ \fc -> prop_format_parse_format Proxy fc t
+        ]
 
 badInputTests :: TestTree
 badInputTests =
@@ -556,10 +725,10 @@
         , nameTest "LocalTime" $ tgroup (localTimeFormats ++ partialLocalTimeFormats) prop_no_crash_bad_input
         , nameTest "TimeZone" $ tgroup (timeZoneFormats) prop_no_crash_bad_input
         , nameTest "ZonedTime" $
-          tgroup (zonedTimeFormats ++ zonedTimeAlmostFormats ++ partialZonedTimeFormats) prop_no_crash_bad_input
+            tgroup (zonedTimeFormats ++ zonedTimeAlmostFormats ++ partialZonedTimeFormats) prop_no_crash_bad_input
         , nameTest "UTCTime" $ tgroup (utcTimeAlmostFormats ++ partialUTCTimeFormats) prop_no_crash_bad_input
         , nameTest "UniversalTime" $
-          tgroup (universalTimeFormats ++ partialUniversalTimeFormats) prop_no_crash_bad_input
+            tgroup (universalTimeFormats ++ partialUniversalTimeFormats) prop_no_crash_bad_input
         ]
 
 readShowTests :: TestTree
@@ -567,14 +736,22 @@
     nameTest
         "read_show"
         [ nameTest "Day" (prop_read_show :: Day -> Result)
+        , nameTest "Month" (prop_read_show :: Month -> Result)
+        , nameTest "QuarterOfYear" (prop_read_show :: QuarterOfYear -> Result)
+        , nameTest "Quarter" (prop_read_show :: Quarter -> Result)
         , nameTest "TimeOfDay" (prop_read_show :: TimeOfDay -> Result)
         , nameTest "LocalTime" (prop_read_show :: LocalTime -> Result)
         , nameTest "TimeZone" (prop_read_show :: TimeZone -> Result)
         , nameTest "ZonedTime" (prop_read_show :: ZonedTime -> Result)
         , nameTest "UTCTime" (prop_read_show :: UTCTime -> Result)
+        , nameTest "UTCTime (zoned)" prop_read_show_ZonedUTC
+        , nameTest "UTCTime (local)" prop_read_show_LocalUTC
+        , nameTest "UTCTime (no TZ)" prop_read_show_UTC_no_TZ
         , nameTest "UniversalTime" (prop_read_show :: UniversalTime -> Result)
-    --nameTest "CalendarDiffDays" (prop_read_show :: CalendarDiffDays -> Result),
-    --nameTest "CalendarDiffTime" (prop_read_show :: CalendarDiffTime -> Result)
+        , nameTest "NominalDiffTime" (prop_read_show :: NominalDiffTime -> Result)
+        , nameTest "DiffTime" (prop_read_show :: DiffTime -> Result)
+        , nameTest "CalendarDiffDays" (prop_read_show :: CalendarDiffDays -> Result)
+        , nameTest "CalendarDiffTime" (prop_read_show :: CalendarDiffTime -> Result)
         ]
 
 parseShowTests :: TestTree
@@ -589,24 +766,27 @@
 propertyTests :: TestTree
 propertyTests =
     localOption (QuickCheckTests 2000) $
-    nameTest
-        "properties"
-        [ readShowTests
-        , parseShowTests
-        , nameTest "fromMondayStartWeek" prop_fromMondayStartWeek
-        , nameTest "fromSundayStartWeek" prop_fromSundayStartWeek
-        , nameTest "parse_format" $ typedTests prop_parse_format
-        , nameTest "parse_format_lower" $ typedTests prop_parse_format_lower
-        , nameTest "parse_format_upper" $ typedTests prop_parse_format_upper
-        , parseEmptyTests
-        , formatParseFormatTests
-        , badInputTests
-        ]
+        nameTest
+            "properties"
+            [ readShowTests
+            , parseShowTests
+            , nameTest "fromMondayStartWeek" prop_fromMondayStartWeek
+            , nameTest "fromSundayStartWeek" prop_fromSundayStartWeek
+            , nameTest "parse_format" $ typedTests prop_parse_format
+            , nameTest "parse_format_lower" $ typedTests prop_parse_format_lower
+            , nameTest "parse_format_upper" $ typedTests prop_parse_format_upper
+            , parseEmptyTests
+            , parse_s_tests
+            , parse_sz_tests
+            , formatParseFormatTests
+            , badInputTests
+            ]
 
 dayFormats :: [FormatString Day]
 dayFormats =
-    map FormatString
-     -- numeric year, month, day
+    map
+        FormatString
+        -- numeric year, month, day
         [ "%Y-%m-%d"
         , "%Y%m%d"
         , "%C%y%m%d"
@@ -616,14 +796,18 @@
         , "%Y/%d/%m"
         , "%D %C"
         , "%F"
-     -- month names
-        , "%Y-%B-%d"
+        , -- month names
+          "%Y-%B-%d"
         , "%Y-%b-%d"
         , "%Y-%h-%d"
-     -- ordinal dates
-        , "%Y-%j"
-     -- ISO week dates
-        , "%G-%V-%u"
+        , "%C-%y-%B-%d"
+        , "%C-%y-%b-%d"
+        , "%C-%y-%h-%d"
+        , -- ordinal dates
+          "%Y-%j"
+        , "%C-%y-%j"
+        , -- ISO week dates
+          "%G-%V-%u"
         , "%G-%V-%a"
         , "%G-%V-%A"
         , "%G-%V-%w"
@@ -637,8 +821,8 @@
         , "%A week %V, %f%g"
         , "day %V, week %A, %f%g"
         , "%f%g-W%V-%u"
-     -- monday and sunday week dates
-        , "%Y-w%U-%A"
+        , -- monday and sunday week dates
+          "%Y-w%U-%A"
         , "%Y-w%W-%A"
         , "%Y-%A-w%U"
         , "%Y-%A-w%W"
@@ -646,10 +830,49 @@
         , "%A week %W, %Y"
         ]
 
+monthFormats :: [FormatString Month]
+monthFormats =
+    map
+        FormatString
+        -- numeric year, month
+        [ "%Y-%m"
+        , "%Y%m"
+        , "%C%y%m"
+        , "%Y %m"
+        , "%m/%Y"
+        , "%m/%Y"
+        , "%Y/%m"
+        , "%C %y %m"
+        , -- month names
+          "%Y-%B"
+        , "%Y-%b"
+        , "%Y-%h"
+        , "%C-%y-%B"
+        , "%C-%y-%b"
+        , "%C-%y-%h"
+        ]
+
+quarterFormats :: [FormatString Quarter]
+quarterFormats =
+    map
+        FormatString
+        -- numeric year, quarter
+        [ "%Y-%v"
+        , "%Y-Q%v"
+        , "%YQ%v"
+        , "%C%y%v"
+        , "%Y %v"
+        , "%v/%Y"
+        , "%v/%Y"
+        , "%Y/%vm"
+        , "%C %y %v"
+        ]
+
 timeOfDayFormats :: [FormatString TimeOfDay]
 timeOfDayFormats =
-    map FormatString
-     -- 24 h formats
+    map
+        FormatString
+        -- 24 h formats
         [ "%H:%M:%S.%q"
         , "%k:%M:%S.%q"
         , "%H%M%S.%q"
@@ -662,8 +885,8 @@
         , "%T%Q"
         , "%X%Q"
         , "%R:%S%Q"
-     -- 12 h formats
-        , "%I:%M:%S.%q %p"
+        , -- 12 h formats
+          "%I:%M:%S.%q %p"
         , "%I:%M:%S.%q %P"
         , "%l:%M:%S.%q %p"
         , "%r %q"
@@ -681,7 +904,8 @@
 
 zonedTimeFormats :: [FormatString ZonedTime]
 zonedTimeFormats =
-    map FormatString
+    map
+        FormatString
         [ "%a, %d %b %Y %H:%M:%S.%q %z"
         , "%a, %d %b %Y %H:%M:%S%Q %z"
         , "%a, %d %b %Y %H:%M:%S.%q %Z"
@@ -702,7 +926,8 @@
 
 calendarDiffTimeFormats :: [FormatString CalendarDiffTime]
 calendarDiffTimeFormats =
-    map FormatString
+    map
+        FormatString
         [ "%yy%Bm%ww%Dd%Hh%Mm%ESs"
         , "%bm%ww%Dd%Hh%Mm%ESs"
         , "%bm%dd%Hh%Mm%ESs"
@@ -722,7 +947,9 @@
     map FormatString ["%ww%Dd%Hh%Mm%ESs", "%dd%Hh%Mm%ESs", "%hh%Mm%ESs", "%mm%ESs", "%mm%0ESs", "%Ess", "%0Ess"]
 
 --
+
 -- * Formats that do not include all the information
+
 --
 partialDayFormats :: [FormatString Day]
 partialDayFormats = map FormatString []
@@ -735,21 +962,23 @@
 
 partialZonedTimeFormats :: [FormatString ZonedTime]
 partialZonedTimeFormats =
-    map FormatString
-     -- %s does not include second decimals
+    map
+        FormatString
+        -- %s does not include second decimals
         [ "%s %z"
-     -- %S does not include second decimals
-        , "%c"
+        , -- %S does not include second decimals
+          "%c"
         , "%a, %d %b %Y %H:%M:%S %Z"
         ]
 
 partialUTCTimeFormats :: [FormatString UTCTime]
 partialUTCTimeFormats =
-    map FormatString
-     -- %s does not include second decimals
+    map
+        FormatString
+        -- %s does not include second decimals
         [ "%s"
-     -- %c does not include second decimals
-        , "%c"
+        , -- %c does not include second decimals
+          "%c"
         ]
 
 partialUniversalTimeFormats :: [FormatString UniversalTime]
@@ -757,8 +986,9 @@
 
 failingPartialDayFormats :: [FormatString Day]
 failingPartialDayFormats =
-    map FormatString
-      -- ISO week dates with two digit year.
-      -- This can fail in the beginning or the end of a year where
-      -- the ISO week date year does not match the gregorian year.
+    map
+        FormatString
+        -- ISO week dates with two digit year.
+        -- This can fail in the beginning or the end of a year where
+        -- the ISO week date year does not match the gregorian year.
         ["%g-%V-%u", "%g-%V-%a", "%g-%V-%A", "%g-%V-%w", "%A week %V, %g", "day %V, week %A, %g", "%g-W%V-%u"]
diff --git a/test/main/Test/LocalTime/CalendarDiffTime.hs b/test/main/Test/LocalTime/CalendarDiffTime.hs
--- a/test/main/Test/LocalTime/CalendarDiffTime.hs
+++ b/test/main/Test/LocalTime/CalendarDiffTime.hs
@@ -1,17 +1,121 @@
-module Test.LocalTime.CalendarDiffTime
-    ( testCalendarDiffTime
-    ) where
+module Test.LocalTime.CalendarDiffTime (
+    testCalendarDiffTime,
+) where
 
---import Data.Time.LocalTime
+import Data.Fixed
+import Data.Time
+import Test.AddDiff
 import Test.Arbitrary ()
 import Test.Tasty
+import Test.Tasty.HUnit
+import Test.TestUtil
 
---import Test.Tasty.QuickCheck hiding (reason)
---testReadShow :: TestTree
---testReadShow = testProperty "read . show" $ \(t :: CalendarDiffTime) -> read (show t) == t
+utcClip :: AddDiff CalendarDiffTime UTCTime
+utcClip = MkAddDiff "utcClip" addUTCDurationClip diffUTCDurationClip
+
+utcRollOver :: AddDiff CalendarDiffTime UTCTime
+utcRollOver = MkAddDiff "utcRollOver" addUTCDurationRollOver diffUTCDurationRollOver
+
+localClip :: AddDiff CalendarDiffTime LocalTime
+localClip = MkAddDiff "localClip" addLocalDurationClip diffLocalDurationClip
+
+localRollOver :: AddDiff CalendarDiffTime LocalTime
+localRollOver = MkAddDiff "localRollOver" addLocalDurationRollOver diffLocalDurationRollOver
+
+testAddDiffs :: TestTree
+testAddDiffs =
+    testGroup
+        "add-diff"
+        [ testGroup "UTC" $ fmap testAddDiff [utcClip, utcRollOver]
+        , testGroup "LocalTime" $ fmap testAddDiff [localClip, localRollOver]
+        ]
+
+utcTime :: Integer -> Int -> Int -> DiffTime -> UTCTime
+utcTime y m d = UTCTime (YearMonthDay y m d)
+
+localTime :: Integer -> Int -> Int -> Int -> Int -> Pico -> LocalTime
+localTime y m d h minute s = LocalTime (YearMonthDay y m d) $ TimeOfDay h minute s
+
+testSpecifics :: TestTree
+testSpecifics =
+    testGroup
+        "specific"
+        [ testGroup
+            "add"
+            [ testCase "UTC clip" $
+                assertEqual
+                    "Jan 31 + 1 month clips to Feb 28"
+                    (utcTime 2001 2 28 0)
+                    (addUTCDurationClip (CalendarDiffTime 1 0) $ utcTime 2001 1 31 0)
+            , testCase "UTC rollover" $
+                assertEqual
+                    "Jan 31 + 1 month rolls over to Mar 3"
+                    (utcTime 2001 3 3 0)
+                    (addUTCDurationRollOver (CalendarDiffTime 1 0) $ utcTime 2001 1 31 0)
+            , testCase "LocalTime clip" $
+                assertEqual
+                    "Jan 31 + 1 month clips to Feb 28"
+                    (localTime 2001 2 28 0 0 0)
+                    (addLocalDurationClip (CalendarDiffTime 1 0) $ localTime 2001 1 31 0 0 0)
+            , testCase "LocalTime rollover" $
+                assertEqual
+                    "Jan 31 + 1 month rolls over to Mar 3"
+                    (localTime 2001 3 3 0 0 0)
+                    (addLocalDurationRollOver (CalendarDiffTime 1 0) $ localTime 2001 1 31 0 0 0)
+            , testCase "time part" $
+                assertEqual
+                    "the time part can carry into the next day"
+                    (localTime 2001 2 1 0 0 1)
+                    (addLocalDurationClip (CalendarDiffTime 0 2) $ localTime 2001 1 31 23 59 59)
+            ]
+        , testGroup
+            "diff"
+            [ testCase "UTC clip" $
+                assertEqual
+                    "Mar 1 - Jan 30 clips as 1 month and 1 day"
+                    (CalendarDiffTime 1 nominalDay)
+                    (diffUTCDurationClip (utcTime 2001 3 1 0) $ utcTime 2001 1 30 0)
+            , testCase "UTC rollover" $
+                assertEqual
+                    "Mar 1 - Jan 30 rolls over as 30 days"
+                    (CalendarDiffTime 0 $ 30 * nominalDay)
+                    (diffUTCDurationRollOver (utcTime 2001 3 1 0) $ utcTime 2001 1 30 0)
+            , testCase "LocalTime clip" $
+                assertEqual
+                    "Mar 1 - Jan 30 clips as 1 month and 1 day"
+                    (CalendarDiffTime 1 nominalDay)
+                    (diffLocalDurationClip (localTime 2001 3 1 0 0 0) $ localTime 2001 1 30 0 0 0)
+            , testCase "LocalTime rollover" $
+                assertEqual
+                    "Mar 1 - Jan 30 rolls over as 30 days"
+                    (CalendarDiffTime 0 $ 30 * nominalDay)
+                    (diffLocalDurationRollOver (localTime 2001 3 1 0 0 0) $ localTime 2001 1 30 0 0 0)
+            ]
+        ]
+
+testReadShowExact :: (Read a, Show a, Eq a) => String -> a -> TestTree
+testReadShowExact t v =
+    nameTest
+        t
+        [ nameTest "show" $ assertEqual "show" t $ show v
+        , nameTest "read" $ assertEqual "read" v $ read t
+        ]
+
 testCalendarDiffTime :: TestTree
 testCalendarDiffTime =
-    testGroup
+    nameTest
         "CalendarDiffTime"
-          --testReadShow
-        []
+        [ testReadShowExact "P0D" $ CalendarDiffTime 0 0
+        , testReadShowExact "P1DT1S" $ CalendarDiffTime 0 $ secondsToNominalDiffTime 86401
+        , testReadShowExact "P-1DT1S" $ CalendarDiffTime 0 $ secondsToNominalDiffTime $ negate 86399
+        , testReadShowExact "P-1D" $ CalendarDiffTime 0 $ secondsToNominalDiffTime $ negate 86400
+        , testReadShowExact "P-2DT23H59M59S" $ CalendarDiffTime 0 $ secondsToNominalDiffTime $ negate 86401
+        , testReadShowExact "P1M-1DT1S" $ CalendarDiffTime 1 $ secondsToNominalDiffTime $ negate 86399
+        , testReadShowExact "P1M-1D" $ CalendarDiffTime 1 $ secondsToNominalDiffTime $ negate 86400
+        , testReadShowExact "P1M-2DT23H59M59S" $ CalendarDiffTime 1 $ secondsToNominalDiffTime $ negate 86401
+        , testReadShowExact "P-1Y-1M-1DT1S" $ CalendarDiffTime (-13) $ secondsToNominalDiffTime $ negate 86399
+        , testReadShowExact "P-1Y-1M-1D" $ CalendarDiffTime (-13) $ secondsToNominalDiffTime $ negate 86400
+        , testReadShowExact "P-1Y-1M-2DT23H59M59S" $ CalendarDiffTime (-13) $ secondsToNominalDiffTime $ negate 86401
+        , testAddDiffs
+        , testSpecifics
+        ]
diff --git a/test/main/Test/LocalTime/Time.hs b/test/main/Test/LocalTime/Time.hs
--- a/test/main/Test/LocalTime/Time.hs
+++ b/test/main/Test/LocalTime/Time.hs
@@ -1,6 +1,6 @@
-module Test.LocalTime.Time
-    ( testTime
-    ) where
+module Test.LocalTime.Time (
+    testTime,
+) where
 
 import Data.Time
 import Data.Time.Calendar.OrdinalDate
@@ -10,44 +10,46 @@
 import Test.Tasty.HUnit
 
 showCal :: Integer -> String
-showCal mjd = let
-    date = ModifiedJulianDay mjd
-    (y, m, d) = toGregorian date
-    date' = fromGregorian y m d
-    in concat
-           [ show mjd ++ "=" ++ showGregorian date ++ "=" ++ showOrdinalDate date ++ "=" ++ showWeekDate date ++ "\n"
-           , if date == date'
-                 then ""
-                 else "=" ++ (show $ toModifiedJulianDay date') ++ "!"
-           ]
+showCal mjd =
+    let
+        date = ModifiedJulianDay mjd
+        (y, m, d) = toGregorian date
+        date' = fromGregorian y m d
+    in
+        concat
+            [ show mjd ++ "=" ++ showGregorian date ++ "=" ++ showOrdinalDate date ++ "=" ++ showWeekDate date ++ "\n"
+            , if date == date'
+                then ""
+                else "=" ++ (show $ toModifiedJulianDay date') ++ "!"
+            ]
 
 testCal :: String
 testCal =
     concat
         -- days around 1 BCE/1 CE
         [ concatMap showCal [-678950 .. -678930]
-        -- days around 1000 CE
-        , concatMap showCal [-313710 .. -313690]
-        -- days around MJD zero
-        , concatMap showCal [-30 .. 30]
+        , -- days around 1000 CE
+          concatMap showCal [-313710 .. -313690]
+        , -- days around MJD zero
+          concatMap showCal [-30 .. 30]
         , showCal 40000
         , showCal 50000
-        -- 1900 not a leap year
-        , showCal 15078
+        , -- 1900 not a leap year
+          showCal 15078
         , showCal 15079
-        -- 1980 is a leap year
-        , showCal 44297
+        , -- 1980 is a leap year
+          showCal 44297
         , showCal 44298
         , showCal 44299
-        -- 1990 not a leap year
-        , showCal 47950
+        , -- 1990 not a leap year
+          showCal 47950
         , showCal 47951
-        -- 2000 is a leap year
-        , showCal 51602
+        , -- 2000 is a leap year
+          showCal 51602
         , showCal 51603
         , showCal 51604
-        -- years 2000 and 2001, plus some slop
-        , concatMap showCal [51540 .. 52280]
+        , -- years 2000 and 2001, plus some slop
+          concatMap showCal [51540 .. 52280]
         ]
 
 showUTCTime :: UTCTime -> String
@@ -63,10 +65,12 @@
 leapSec1998 = localTimeToUTC utc leapSec1998Cal
 
 testUTC :: String
-testUTC = let
-    lsMineCal = utcToLocalTime myzone leapSec1998
-    lsMine = localTimeToUTC myzone lsMineCal
-    in unlines [showCal 51178, show leapSec1998Cal, showUTCTime leapSec1998, show lsMineCal, showUTCTime lsMine]
+testUTC =
+    let
+        lsMineCal = utcToLocalTime myzone leapSec1998
+        lsMine = localTimeToUTC myzone lsMineCal
+    in
+        unlines [showCal 51178, show leapSec1998Cal, showUTCTime leapSec1998, show lsMineCal, showUTCTime lsMine]
 
 neglong :: Rational
 neglong = -120
@@ -86,17 +90,20 @@
         ]
 
 testTimeOfDayToDayFraction :: String
-testTimeOfDayToDayFraction = let
-    f = dayFractionToTimeOfDay . timeOfDayToDayFraction
-    in unlines
-           [ show $ f $ TimeOfDay 12 34 56.789
-           , show $ f $ TimeOfDay 12 34 56.789123
-           , show $ f $ TimeOfDay 12 34 56.789123456
-           , show $ f $ TimeOfDay 12 34 56.789123456789
-           , show $ f $ TimeOfDay minBound 0 0
-           ]
+testTimeOfDayToDayFraction =
+    let
+        f = dayFractionToTimeOfDay . timeOfDayToDayFraction
+    in
+        unlines
+            [ show $ f $ TimeOfDay 12 34 56.789
+            , show $ f $ TimeOfDay 12 34 56.789123
+            , show $ f $ TimeOfDay 12 34 56.789123456
+            , show $ f $ TimeOfDay 12 34 56.789123456789
+            , show $ f $ TimeOfDay minBound 0 0
+            ]
 
 testTime :: TestTree
 testTime =
     testCase "testTime" $
-    assertEqual "times" testTimeRef $ unlines [testCal, testUTC, testUT1, testTimeOfDayToDayFraction]
+        assertEqual "times" testTimeRef $
+            unlines [testCal, testUTC, testUT1, testTimeOfDayToDayFraction]
diff --git a/test/main/Test/LocalTime/TimeOfDay.hs b/test/main/Test/LocalTime/TimeOfDay.hs
--- a/test/main/Test/LocalTime/TimeOfDay.hs
+++ b/test/main/Test/LocalTime/TimeOfDay.hs
@@ -1,6 +1,6 @@
-module Test.LocalTime.TimeOfDay
-    ( testTimeOfDay
-    ) where
+module Test.LocalTime.TimeOfDay (
+    testTimeOfDay,
+) where
 
 import Data.Time.LocalTime
 import Test.Arbitrary ()
@@ -11,12 +11,16 @@
 testTimeOfDay =
     testGroup
         "TimeOfDay"
-        [ testProperty "daysAndTimeOfDayToTime . timeToDaysAndTimeOfDay" $ \ndt -> let
-              (d, tod) = timeToDaysAndTimeOfDay ndt
-              ndt' = daysAndTimeOfDayToTime d tod
-              in ndt' == ndt
-        , testProperty "timeOfDayToTime . timeToTimeOfDay" $ \dt -> let
-              tod = timeToTimeOfDay dt
-              dt' = timeOfDayToTime tod
-              in dt' == dt
+        [ testProperty "daysAndTimeOfDayToTime . timeToDaysAndTimeOfDay" $ \ndt ->
+            let
+                (d, tod) = timeToDaysAndTimeOfDay ndt
+                ndt' = daysAndTimeOfDayToTime d tod
+            in
+                ndt' == ndt
+        , testProperty "timeOfDayToTime . timeToTimeOfDay" $ \dt ->
+            let
+                tod = timeToTimeOfDay dt
+                dt' = timeOfDayToTime tod
+            in
+                dt' == dt
         ]
diff --git a/test/main/Test/LocalTime/TimeRef.hs b/test/main/Test/LocalTime/TimeRef.hs
--- a/test/main/Test/LocalTime/TimeRef.hs
+++ b/test/main/Test/LocalTime/TimeRef.hs
@@ -6,9 +6,10 @@
 is64Bit =
     if toInteger (maxBound :: Int) == toInteger (maxBound :: Int32)
         then False
-        else if toInteger (maxBound :: Int) == toInteger (maxBound :: Int64)
-                 then True
-                 else error "unrecognised Int size"
+        else
+            if toInteger (maxBound :: Int) == toInteger (maxBound :: Int64)
+                then True
+                else error "unrecognised Int size"
 
 testTimeRef :: String
 testTimeRef =
@@ -889,7 +890,7 @@
         , "12:34:56.789123456"
         , "12:34:56.789123456789"
         , if is64Bit
-              then "-9223372036854775808:00:00"
-              else "-2147483648:00:00"
+            then "-9223372036854775808:00:00"
+            else "-2147483648:00:00"
         , ""
         ]
diff --git a/test/main/Test/TestUtil.hs b/test/main/Test/TestUtil.hs
--- a/test/main/Test/TestUtil.hs
+++ b/test/main/Test/TestUtil.hs
@@ -32,5 +32,8 @@
 instance (Arbitrary a, Show a, Testable b) => NameTest (a -> b) where
     nameTest name = nameTest name . property
 
+instance Testable a => NameTest (Gen a) where
+    nameTest name = nameTest name . property
+
 tgroup :: (Show a, NameTest t) => [a] -> (a -> t) -> [TestTree]
 tgroup aa f = fmap (\a -> nameTest (show a) $ f a) aa
diff --git a/test/main/Test/Types.hs b/test/main/Test/Types.hs
--- a/test/main/Test/Types.hs
+++ b/test/main/Test/Types.hs
@@ -1,26 +1,52 @@
-module Test.Types(CheckInstances) where
+module Test.Types () where
 
+import Control.DeepSeq
 import Data.Data
+import Data.Ix
 import Data.Time
+import Data.Time.Calendar.Month
+import Data.Time.Calendar.Quarter
 import Data.Time.Clock.System
 import Data.Time.Clock.TAI
 
-class (Typeable t, Data t) => CheckDataInstances t
-class (Typeable t, Data t, Eq t) => CheckInstances t
+class (Typeable t, Data t, NFData t) => CheckDataInstances t
 
-instance CheckInstances UTCTime
-instance CheckInstances NominalDiffTime
+class (Typeable t, Data t, NFData t, Eq t) => CheckEqInstances t
 
-instance CheckInstances Day
-instance CheckInstances DayOfWeek
-instance CheckInstances TimeOfDay
-instance CheckInstances LocalTime
-instance CheckInstances TimeZone
+class (Typeable t, Data t, NFData t, Eq t, Ord t) => CheckOrdInstances t
+
+class (Typeable t, Data t, NFData t, Eq t, Ord t, Ix t, Enum t) => CheckEnumInstances t
+
+class (Typeable t, Data t, NFData t, Eq t, Ord t, Ix t, Enum t, Bounded t) => CheckBoundedInstances t
+
+instance CheckOrdInstances UTCTime
+
+instance CheckOrdInstances NominalDiffTime
+
+instance CheckEnumInstances Day
+
+instance CheckEnumInstances DayOfWeek
+
+instance CheckOrdInstances TimeOfDay
+
+instance CheckOrdInstances LocalTime
+
+instance CheckOrdInstances TimeZone
+
 instance CheckDataInstances ZonedTime
-instance CheckInstances CalendarDiffDays
-instance CheckInstances CalendarDiffTime
 
-instance CheckInstances SystemTime
+instance CheckEqInstances CalendarDiffDays
 
-instance CheckInstances AbsoluteTime
-instance CheckInstances UniversalTime
+instance CheckEqInstances CalendarDiffTime
+
+instance CheckEnumInstances Month
+
+instance CheckEnumInstances Quarter
+
+instance CheckBoundedInstances QuarterOfYear
+
+instance CheckOrdInstances SystemTime
+
+instance CheckOrdInstances AbsoluteTime
+
+instance CheckOrdInstances UniversalTime
diff --git a/test/template/Main.hs b/test/template/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/template/Main.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE CPP #-}
+
+module Main (main) where
+
+import Data.Time.Clock
+#if __GLASGOW_HASKELL__ >= 914
+import qualified Language.Haskell.TH.Lift as TH
+#else
+import qualified Language.Haskell.TH.Syntax as TH
+#endif
+import Test.Tasty
+import Test.Tasty.HUnit
+import Test.TastyWrapper
+
+testLift :: TestTree
+testLift =
+    testGroup
+        "Lift instances"
+        [ testCase "DiffTime" $ $$(TH.liftTyped (secondsToDiffTime 100)) @?= secondsToDiffTime 100
+        , testCase "NominalDiffTime" $ $$(TH.liftTyped (secondsToNominalDiffTime 100)) @?= secondsToNominalDiffTime 100
+        ]
+
+tests :: TestTree
+tests =
+    testGroup
+        "time-template"
+        [ testLift
+        ]
+
+main :: IO ()
+main = tastyWrapper $ defaultMain tests
diff --git a/test/template/Test/TastyWrapper.hs b/test/template/Test/TastyWrapper.hs
new file mode 100644
--- /dev/null
+++ b/test/template/Test/TastyWrapper.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE CPP #-}
+
+module Test.TastyWrapper where
+
+#if defined(javascript_HOST_ARCH)
+import GHC.IO.Handle (hDuplicateTo)
+import System.IO (IOMode (ReadMode), stdin, withFile)
+#endif
+
+tastyWrapper :: IO a -> IO a
+#if defined(javascript_HOST_ARCH)
+-- Tasty's console reporter queries terminal width through ansi-terminal, which
+-- trips h$fdReady in the JS RTS when this test runs attached to a TTY.
+tastyWrapper action =
+    withFile "/dev/null" ReadMode $ \devNull -> do
+        hDuplicateTo devNull stdin
+        action
+#else
+tastyWrapper = id
+#endif
diff --git a/test/unix/Main.hs b/test/unix/Main.hs
--- a/test/unix/Main.hs
+++ b/test/unix/Main.hs
@@ -5,7 +5,7 @@
 import Test.Tasty
 
 tests :: TestTree
-tests = testGroup "Time" [testGroup "Format" [testFormat], testGroup "LocalTime" [testTimeZone]]
+tests = testGroup "Time" [testGroup "Format" testFormat, testGroup "LocalTime" [testTimeZone]]
 
 main :: IO ()
 main = defaultMain tests
diff --git a/test/unix/Test/Format/Format.hs b/test/unix/Test/Format/Format.hs
--- a/test/unix/Test/Format/Format.hs
+++ b/test/unix/Test/Format/Format.hs
@@ -1,8 +1,8 @@
 {-# OPTIONS -fno-warn-orphans #-}
 
-module Test.Format.Format
-    ( testFormat
-    ) where
+module Test.Format.Format (
+    testFormat,
+) where
 
 import Data.Char
 import Data.Fixed as F
@@ -25,51 +25,67 @@
     const char *format,
     int isdst,int gmtoff,time_t t);
 -}
-foreign import ccall unsafe "FormatStuff.h format_time" format_time
-    :: CString ->
-  CSize -> CString -> CInt -> CInt -> CString -> CTime -> IO CSize
+foreign import ccall unsafe "FormatStuff.h format_time"
+    format_time ::
+        CString ->
+        CSize ->
+        CString ->
+        CInt ->
+        CInt ->
+        CString ->
+        CTime ->
+        IO CSize
 
 withBuffer :: Int -> (CString -> IO CSize) -> IO String
 withBuffer n f =
     withArray
         (replicate n 0)
-        (\buffer -> do
-             len <- f buffer
-             peekCStringLen (buffer, fromIntegral len))
+        ( \buffer -> do
+            len <- f buffer
+            peekCStringLen (buffer, fromIntegral len)
+        )
 
 unixFormatTime :: String -> TimeZone -> UTCTime -> String
 unixFormatTime fmt zone time =
     unsafePerformIO $
-    withCString
-        fmt
-        (\pfmt ->
-             withCString
-                 (timeZoneName zone)
-                 (\pzonename ->
-                      withBuffer
-                          100
-                          (\buffer ->
-                               format_time
-                                   buffer
-                                   100
-                                   pfmt
-                                   (if timeZoneSummerOnly zone
+        withCString
+            fmt
+            ( \pfmt ->
+                withCString
+                    (timeZoneName zone)
+                    ( \pzonename ->
+                        withBuffer
+                            100
+                            ( \buffer ->
+                                format_time
+                                    buffer
+                                    100
+                                    pfmt
+                                    ( if timeZoneSummerOnly zone
                                         then 1
-                                        else 0)
-                                   (fromIntegral (timeZoneMinutes zone * 60))
-                                   pzonename
-                                   (fromInteger (floor (utcTimeToPOSIXSeconds time))))))
+                                        else 0
+                                    )
+                                    (fromIntegral (timeZoneMinutes zone * 60))
+                                    pzonename
+                                    (fromInteger (floor (utcTimeToPOSIXSeconds time)))
+                            )
+                    )
+            )
 
 locale :: TimeLocale
-locale = defaultTimeLocale {dateTimeFmt = "%a %b %e %H:%M:%S %Y"}
+locale = defaultTimeLocale{dateTimeFmt = "%a %b %e %H:%M:%S %Y"}
 
 instance Random (F.Fixed res) where
-    randomR (MkFixed lo, MkFixed hi) oldgen = let
-        (v, newgen) = randomR (lo, hi) oldgen
-        in (MkFixed v, newgen)
-    random oldgen = let
-        (v, newgen) = random oldgen
-        in (MkFixed v, newgen)
+    randomR (MkFixed lo, MkFixed hi) oldgen =
+        let
+            (v, newgen) = randomR (lo, hi) oldgen
+        in
+            (MkFixed v, newgen)
+    random oldgen =
+        let
+            (v, newgen) = random oldgen
+        in
+            (MkFixed v, newgen)
 
 instance Arbitrary TimeZone where
     arbitrary = do
@@ -92,10 +108,12 @@
 
 -- | The size of 'CTime' is platform-dependent.
 secondsFitInCTime :: Integer -> Bool
-secondsFitInCTime sec = let
-    CTime ct = fromInteger sec
-    sec' = toInteger ct
-    in sec == sec'
+secondsFitInCTime sec =
+    let
+        CTime ct = fromInteger sec
+        sec' = toInteger ct
+    in
+        sec == sec'
 
 instance Arbitrary UTCTime where
     arbitrary = do
@@ -132,15 +150,22 @@
     isPadChar _ = False
 unixWorkarounds _ s = s
 
+lastM :: [a] -> Maybe a
+lastM [] = Nothing
+lastM [a] = Just a
+lastM (_ : aa) = lastM aa
+
 compareFormat :: (String -> String) -> String -> TimeZone -> UTCTime -> Result
 compareFormat _modUnix fmt zone _time
-    | last fmt == 'Z' && timeZoneName zone == "" = rejected
-compareFormat modUnix fmt zone time = let
-    ctime = utcToZonedTime zone time
-    haskellText = formatTime locale fmt ctime
-    unixText = unixFormatTime fmt zone time
-    expectedText = unixWorkarounds fmt (modUnix unixText)
-    in assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText
+    | lastM fmt == Just 'Z' && timeZoneName zone == "" = rejected
+compareFormat modUnix fmt zone time =
+    let
+        ctime = utcToZonedTime zone time
+        haskellText = formatTime locale fmt ctime
+        unixText = unixFormatTime fmt zone time
+        expectedText = unixWorkarounds fmt (modUnix unixText)
+    in
+        assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText
 
 -- as found in http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
 -- plus FgGklz
@@ -159,12 +184,13 @@
 
 formats :: [String]
 formats =
-    ["%G-W%V-%u", "%U-%w", "%W-%u"] ++
-    (do
-         char <- chars
-         width <- widths
-         modifier <- modifiers
-         return $ "%" ++ modifier ++ width ++ [char])
+    ["%G-W%V-%u", "%U-%w", "%W-%u"]
+        ++ ( do
+                char <- chars
+                width <- widths
+                modifier <- modifiers
+                return $ "%" ++ modifier ++ width ++ [char]
+           )
 
 hashformats :: [String]
 hashformats = do
@@ -187,10 +213,12 @@
 
 formatUnitTest :: String -> Pico -> String -> TestTree
 formatUnitTest fmt sec expected =
-    nameTest (show fmt) $ let
-        tod = TimeOfDay 0 0 (1 + sec)
-        found = formatTime locale fmt tod
-        in assertEqual "" expected found
+    nameTest (show fmt) $
+        let
+            tod = TimeOfDay 0 0 (1 + sec)
+            found = formatTime locale fmt tod
+        in
+            assertEqual "" expected found
 
 testQs :: [TestTree]
 testQs =
@@ -244,6 +272,11 @@
     , formatUnitTest "%-5Q" 0.37 ".37   "
     ]
 
-testFormat :: TestTree
+strftimeHasGNUExts :: Bool
+strftimeHasGNUExts = unixFormatTime "%_6Y" utc (UTCTime (fromGregorian 1980 1 1) 0) == "  1980"
+
+testFormat :: [TestTree]
 testFormat =
-    localOption (QuickCheckTests 10000) $ testGroup "testFormat" $ testCompareFormat ++ testCompareHashFormat ++ testQs
+    if strftimeHasGNUExts
+        then pure $ localOption (QuickCheckTests 10000) $ testGroup "testFormat" $ testCompareFormat ++ testCompareHashFormat ++ testQs
+        else []
diff --git a/test/unix/Test/LocalTime/TimeZone.hs b/test/unix/Test/LocalTime/TimeZone.hs
--- a/test/unix/Test/LocalTime/TimeZone.hs
+++ b/test/unix/Test/LocalTime/TimeZone.hs
@@ -1,18 +1,19 @@
-module Test.LocalTime.TimeZone
-    ( testTimeZone
-    ) where
+module Test.LocalTime.TimeZone (
+    testTimeZone,
+) where
 
 import Data.Time
-import System.Posix.Env (putEnv)
+import System.Environment (setEnv)
 import Test.Tasty
 import Test.Tasty.HUnit
 
 testTimeZone :: TestTree
 testTimeZone =
     testCase "getTimeZone respects TZ env var" $ do
-        let epoch = UTCTime (ModifiedJulianDay 57000) 0
-        putEnv "TZ=UTC+0"
+        let
+            epoch = UTCTime (ModifiedJulianDay 57000) 0
+        setEnv "TZ" "UTC+0"
         zone1 <- getTimeZone epoch
-        putEnv "TZ=EST+5"
+        setEnv "TZ" "EST+5"
         zone2 <- getTimeZone epoch
         assertBool "zone not changed" $ zone1 /= zone2
diff --git a/test/unix/Test/TestUtil.hs b/test/unix/Test/TestUtil.hs
--- a/test/unix/Test/TestUtil.hs
+++ b/test/unix/Test/TestUtil.hs
@@ -32,7 +32,7 @@
 instance (Arbitrary a, Show a, Testable b) => NameTest (a -> b) where
     nameTest name = nameTest name . property
 
-instance (Testable a) => NameTest (Gen a) where
+instance Testable a => NameTest (Gen a) where
     nameTest name = nameTest name . property
 
 tgroup :: (Show a, NameTest t) => [a] -> (a -> t) -> [TestTree]
@@ -41,5 +41,5 @@
 assertEqualQC :: (Show a, Eq a) => String -> a -> a -> Result
 assertEqualQC _name expected found
     | expected == found = succeeded
-assertEqualQC "" expected found = failed {reason = "expected " ++ show expected ++ ", found " ++ show found}
-assertEqualQC name expected found = failed {reason = name ++ ": expected " ++ show expected ++ ", found " ++ show found}
+assertEqualQC "" expected found = failed{reason = "expected " ++ show expected ++ ", found " ++ show found}
+assertEqualQC name expected found = failed{reason = name ++ ": expected " ++ show expected ++ ", found " ++ show found}
diff --git a/time.cabal b/time.cabal
--- a/time.cabal
+++ b/time.cabal
@@ -1,7 +1,8 @@
+cabal-version:  3.0
 name:           time
-version:        1.10
+version:        1.16
 stability:      stable
-license:        BSD3
+license:        BSD-2-Clause
 license-file:   LICENSE
 author:         Ashley Yakeley
 maintainer:     <ashley@semantic.org>
@@ -11,12 +12,14 @@
 description:    Time, clocks and calendars
 category:       Time
 build-type:     Configure
-cabal-version:  >=1.10
-tested-with:    GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5
+tested-with:
+    GHC == 9.8.4,
+    GHC == 9.10.3,
+    GHC == 9.12.4,
+    GHC == 9.14.1
 x-follows-version-policy:
 
 extra-source-files:
-    changelog.md
     aclocal.m4
     configure.ac
     configure
@@ -29,6 +32,8 @@
     config.status
     autom4te.cache
     lib/include/HsTimeConfig.h
+extra-doc-files:
+    changelog.md
 
 source-repository head
     type:     git
@@ -36,17 +41,27 @@
 
 library
     hs-source-dirs: lib
-    default-language: Haskell2010
+    default-language: GHC2021
     default-extensions:
-        Rank2Types
-        DeriveDataTypeable
-        StandaloneDeriving
-        CPP
-    ghc-options: -Wall -fwarn-tabs
+        NoGeneralizedNewtypeDeriving
+        LambdaCase
+        PatternSynonyms
+        ViewPatterns
+    ghc-options:
+        -Wall
+        -fwarn-tabs
+        -Wno-deriving-typeable
     c-sources: lib/cbits/HsTime.c
     build-depends:
-        base >= 4.9 && < 5,
-        deepseq >= 1.1
+        base >= 4.19 && < 5,
+        deepseq >= 1.1,
+    -- template-haskell-lift was added as a boot library in GHC-9.14
+    -- once we no longer wish to backport releases to older major releases,
+    -- this conditional can be dropped
+    if impl(ghc < 9.14)
+        build-depends: template-haskell
+    elif impl(ghc)
+        build-depends: template-haskell-lift >= 0.1 && <0.2
     if os(windows)
         build-depends: Win32
     exposed-modules:
@@ -56,23 +71,26 @@
         Data.Time.Calendar.WeekDate,
         Data.Time.Calendar.Julian,
         Data.Time.Calendar.Easter,
+        Data.Time.Calendar.Month,
+        Data.Time.Calendar.Quarter,
         Data.Time.Clock,
         Data.Time.Clock.System,
         Data.Time.Clock.POSIX,
         Data.Time.Clock.TAI,
         Data.Time.LocalTime,
         Data.Time.Format,
-        Data.Time.Format.Internal,
         Data.Time.Format.ISO8601,
         Data.Time
     other-modules:
-        Data.Format
-        Data.Time.Calendar.Private,
+        Data.Format,
+        Data.Time.Calendar.CalendarDiffDays,
         Data.Time.Calendar.Days,
         Data.Time.Calendar.Gregorian,
-        Data.Time.Calendar.CalendarDiffDays,
-        Data.Time.Calendar.Week,
         Data.Time.Calendar.JulianYearDay,
+        Data.Time.Calendar.Private,
+        Data.Time.Calendar.Types,
+        Data.Time.Calendar.Week,
+        Data.Time.Format.Internal,
         Data.Time.Clock.Internal.DiffTime,
         Data.Time.Clock.Internal.AbsoluteTime,
         Data.Time.Clock.Internal.NominalDiffTime,
@@ -81,11 +99,11 @@
         Data.Time.Clock.Internal.SystemTime,
         Data.Time.Clock.Internal.UTCTime,
         Data.Time.Clock.Internal.CTimeval,
-        Data.Time.Clock.Internal.CTimespec,
         Data.Time.Clock.Internal.UTCDiff,
+        Data.Time.LocalTime.Internal.Foreign,
         Data.Time.LocalTime.Internal.TimeZone,
         Data.Time.LocalTime.Internal.TimeOfDay,
-        Data.Time.LocalTime.Internal.CalendarDiffTime
+        Data.Time.LocalTime.Internal.CalendarDiffTime,
         Data.Time.LocalTime.Internal.LocalTime,
         Data.Time.LocalTime.Internal.ZonedTime,
         Data.Time.Format.Parse,
@@ -94,11 +112,16 @@
         Data.Time.Format.Format.Instances,
         Data.Time.Format.Parse.Class,
         Data.Time.Format.Parse.Instances
+    if !impl(mhs)
+        other-modules:
+            Data.Time.Clock.Internal.CTimespec
     include-dirs: lib/include
     if os(windows)
         install-includes:
             HsTime.h
     else
+        autogen-includes:
+            HsTimeConfig.h
         install-includes:
             HsTime.h
             HsTimeConfig.h
@@ -106,44 +129,71 @@
 test-suite ShowDefaultTZAbbreviations
     type: exitcode-stdio-1.0
     hs-source-dirs: test
-    default-language: Haskell2010
+    default-language: GHC2021
     ghc-options: -Wall -fwarn-tabs
     build-depends:
         base,
         time
     main-is: ShowDefaultTZAbbreviations.hs
 
+test-suite ShowTime
+    type: exitcode-stdio-1.0
+    hs-source-dirs: test
+    default-language: GHC2021
+    ghc-options: -Wall -fwarn-tabs
+    build-depends:
+        base,
+        time
+    main-is: ShowTime.hs
+
+test-suite ForeignCalls
+    type: exitcode-stdio-1.0
+    hs-source-dirs: test
+    default-language: GHC2021
+    ghc-options: -Wall -fwarn-tabs
+    build-depends:
+        base,
+        time
+    main-is: ForeignCalls.hs
+
 test-suite test-main
+    if arch (javascript)
+        -- blocked by splitmix
+        -- https://github.com/haskellari/splitmix/issues/93
+        buildable: False
     type: exitcode-stdio-1.0
     hs-source-dirs: test/main
-    default-language: Haskell2010
+    default-language: GHC2021
     default-extensions:
-        Rank2Types
-        CPP
-        DeriveDataTypeable
-        StandaloneDeriving
-        ExistentialQuantification
-        MultiParamTypeClasses
-        FlexibleInstances
+        DefaultSignatures
+        DerivingStrategies
+        RecordWildCards
         UndecidableInstances
-        ScopedTypeVariables
-        TupleSections
     ghc-options: -Wall -fwarn-tabs
+    if !arch (wasm32)
+        ghc-options: -threaded -rtsopts -with-rtsopts=-N
     build-depends:
         base,
         deepseq,
         time,
+        random,
         QuickCheck,
         tasty,
         tasty-hunit,
-        tasty-quickcheck
+        tasty-quickcheck,
+    if impl(ghc < 9.14)
+        build-depends: template-haskell
+    elif impl(ghc)
+        build-depends: template-haskell-lift >= 0.1 && <0.2
     main-is: Main.hs
     other-modules:
+        Test.AddDiff
         Test.Types
         Test.TestUtil
         Test.Arbitrary
         Test.Calendar.AddDays
         Test.Calendar.AddDaysRef
+        Test.Calendar.CalendarProps
         Test.Calendar.Calendars
         Test.Calendar.CalendarsRef
         Test.Calendar.ClipDates
@@ -152,13 +202,17 @@
         Test.Calendar.Duration
         Test.Calendar.Easter
         Test.Calendar.EasterRef
+        Test.Calendar.DayPeriod
         Test.Calendar.LongWeekYears
         Test.Calendar.LongWeekYearsRef
         Test.Calendar.MonthDay
         Test.Calendar.MonthDayRef
+        Test.Calendar.MonthOfYear
         Test.Calendar.Valid
         Test.Calendar.Week
+        Test.Calendar.Year
         Test.Clock.Conversion
+        Test.Clock.Pattern
         Test.Clock.Resolution
         Test.Clock.TAI
         Test.Format.Compile
@@ -170,23 +224,46 @@
         Test.LocalTime.TimeOfDay
         Test.LocalTime.TimeRef
 
+test-suite test-template
+    if arch (wasm32)
+        buildable: False
+    type: exitcode-stdio-1.0
+    hs-source-dirs: test/template
+    default-language: GHC2021
+    default-extensions:
+        DerivingStrategies
+        UndecidableInstances
+        RecordWildCards
+        TemplateHaskell
+    ghc-options: -Wall -fwarn-tabs
+    build-depends:
+        base,
+        deepseq,
+        time,
+        random,
+        QuickCheck,
+        tasty,
+        tasty-hunit,
+        tasty-quickcheck,
+    if impl(ghc < 9.14)
+        build-depends: template-haskell
+    elif impl(ghc)
+        build-depends: template-haskell-lift >= 0.1 && <0.2
+    main-is: Main.hs
+    other-modules:
+        Test.TastyWrapper
+
 test-suite test-unix
-    if os(windows)
+    if os(windows) || arch (javascript) || arch (wasm32)
         buildable: False
     type: exitcode-stdio-1.0
     hs-source-dirs: test/unix
-    default-language: Haskell2010
+    default-language: GHC2021
     default-extensions:
-        Rank2Types
-        CPP
-        DeriveDataTypeable
-        StandaloneDeriving
-        ExistentialQuantification
-        MultiParamTypeClasses
-        FlexibleInstances
         UndecidableInstances
-        ScopedTypeVariables
     ghc-options: -Wall -fwarn-tabs
+    if !arch (wasm32)
+        ghc-options: -threaded -rtsopts -with-rtsopts=-N
     c-sources: test/unix/Test/Format/FormatStuff.c
     build-depends:
         base,
@@ -197,10 +274,24 @@
         tasty,
         tasty-hunit,
         tasty-quickcheck
-    if !os(windows)
-        build-depends: unix
     main-is: Main.hs
     other-modules:
         Test.TestUtil
         Test.Format.Format
         Test.LocalTime.TimeZone
+
+benchmark time-bench
+    type: exitcode-stdio-1.0
+    hs-source-dirs: benchmark
+    default-language: GHC2021
+    ghc-options: -Wall -fwarn-tabs
+    build-depends:
+        base,
+        deepseq,
+        time,
+        criterion
+    if impl(ghc < 9.14)
+        build-depends: template-haskell
+    elif impl(ghc)
+        build-depends: template-haskell-lift >= 0.1 && <0.2
+    main-is: Main.hs
