diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-TimeLib is Copyright (c) Ashley Yakeley and contributors, 2004-2022. All rights reserved.
+TimeLib is Copyright (c) Ashley Yakeley and contributors, 2004-2021. 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/aclocal.m4 b/aclocal.m4
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,17 +1,19 @@
-# FP_DECL_ALTZONE
-# ---------------
-# Defines HAVE_DECL_ALTZONE to 1 if declared, 0 otherwise.
-#
-# Used by base package.
-AC_DEFUN([FP_DECL_ALTZONE],
-[
-  AC_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
+# 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
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,14 +1,8 @@
 # Change Log
 
-## [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
+## [1.13] - 2021-10-18
 - add DayPeriod class for periods of days
-- add QuarterDay pattern and DayOfQuarter type synonym
+- add QuarterDay pattern
 - add CommonEra and BeforeCommonEra patterns
 
 ## [1.12] - 2021-06-12
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Haskell time package 1.12.2.
+# Generated by GNU Autoconf 2.69 for Haskell time package 1.13.
 #
 # Report bugs to <ashley@semantic.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='Haskell time package'
 PACKAGE_TARNAME='time'
-PACKAGE_VERSION='1.12.2'
-PACKAGE_STRING='Haskell time package 1.12.2'
+PACKAGE_VERSION='1.13'
+PACKAGE_STRING='Haskell time package 1.13'
 PACKAGE_BUGREPORT='ashley@semantic.org'
 PACKAGE_URL=''
 
@@ -622,7 +622,6 @@
 # include <unistd.h>
 #endif"
 
-ac_header_list=
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 EGREP
@@ -1239,7 +1238,7 @@
   # 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.12.2 to adapt to many kinds of systems.
+\`configure' configures Haskell time package 1.13 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1301,7 +1300,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Haskell time package 1.12.2:";;
+     short | recursive ) echo "Configuration of Haskell time package 1.13:";;
    esac
   cat <<\_ACEOF
 
@@ -1387,7 +1386,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Haskell time package configure 1.12.2
+Haskell time package configure 1.13
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1859,7 +1858,7 @@
 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.12.2, which was
+It was created by Haskell time package $as_me 1.13, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2139,7 +2138,6 @@
   >$cache_file
 fi
 
-as_fn_append ac_header_list " sys/time.h"
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
@@ -3619,29 +3617,42 @@
 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>
 
-  for ac_header in $ac_header_list
-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
+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
-
-done
-
-
-
+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
+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 :
@@ -3653,12 +3664,16 @@
 
 done
 
-  ac_fn_c_check_decl "$LINENO" "altzone" "ac_cv_have_decl_altzone" "
-  #if HAVE_SYS_TIME_H
-  #include <sys/time.h>
-  #endif
-  #include <time.h>
-
+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
@@ -4178,7 +4193,7 @@
 # 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.12.2, which was
+This file was extended by Haskell time package $as_me 1.13, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4231,7 +4246,7 @@
 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.12.2
+Haskell time package config.status 1.13
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([Haskell time package],[1.12.2],[ashley@semantic.org],[time])
+AC_INIT([Haskell time package], [1.13], [ashley@semantic.org], [time])
 
 # Safety check: Ensure that we are in the correct source directory.
 AC_CONFIG_SRCDIR([lib/include/HsTime.h])
diff --git a/lib/Data/Format.hs b/lib/Data/Format.hs
--- a/lib/Data/Format.hs
+++ b/lib/Data/Format.hs
@@ -61,10 +61,10 @@
 
 -- | A text format for a type
 data Format t = MkFormat
-    { formatShowM :: t -> Maybe String
-    -- ^ Show a value in the format, if representable
-    , formatReadP :: ReadP t
-    -- ^ Read a value in the format
+    { -- | Show a value in the format, if representable
+      formatShowM :: t -> Maybe String
+    , -- | Read a value in the format
+      formatReadP :: ReadP t
     }
 
 -- | Show a value in the format, or error if unrepresentable
@@ -110,8 +110,7 @@
 instance Productish Format where
     pUnit = MkFormat{formatShowM = \_ -> Just "", formatReadP = return ()}
     (<**>) (MkFormat sa ra) (MkFormat sb rb) =
-        let
-            sab (a, b) = do
+        let sab (a, b) = do
                 astr <- sa a
                 bstr <- sb b
                 return $ astr ++ bstr
@@ -119,20 +118,18 @@
                 a <- ra
                 b <- rb
                 return (a, b)
-            in MkFormat sab rab
+         in MkFormat sab rab
     (MkFormat sa ra) **> (MkFormat sb rb) =
-        let
-            s b = do
+        let s b = do
                 astr <- sa ()
                 bstr <- sb b
                 return $ astr ++ bstr
             r = do
                 ra
                 rb
-            in MkFormat s r
+         in MkFormat s r
     (MkFormat sa ra) <** (MkFormat sb rb) =
-        let
-            s a = do
+        let s a = do
                 astr <- sa a
                 bstr <- sb ()
                 return $ astr ++ bstr
@@ -140,47 +137,43 @@
                 a <- ra
                 rb
                 return a
-            in MkFormat s r
+         in MkFormat s r
 
 instance Summish Format where
     pVoid = MkFormat absurd pfail
     (MkFormat sa ra) <++> (MkFormat sb rb) =
-        let
-            sab (Left a) = sa a
+        let sab (Left a) = sa a
             sab (Right b) = sb b
             rab = (fmap Left ra) +++ (fmap Right rb)
-            in MkFormat sab rab
+         in MkFormat sab rab
 
 literalFormat :: String -> Format ()
 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
+    let s' t
             | t == val = Just str
         s' t = s t
-        in MkFormat s' r
+     in MkFormat s' r
 
 specialCaseFormat :: Eq a => (a, String) -> Format a -> Format a
 specialCaseFormat (val, str) (MkFormat s r) =
-    let
-        s' t
+    let s' t
             | t == val = Just str
         s' t = s t
         r' = (string str >> return val) +++ r
-        in MkFormat s' r'
+     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
+    let s t = lookup t pairs
         r [] = pfail
         r ((v, str) : pp) = (string str >> return v) <++ r pp
-        in MkFormat s $ r pairs
+     in MkFormat s $ r pairs
 
 optionalSignFormat :: (Eq t, Num t) => Format t
 optionalSignFormat = casesFormat [(1, ""), (1, "+"), (0, ""), (-1, "-")]
@@ -228,12 +221,10 @@
 
 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
+    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
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
@@ -53,7 +53,7 @@
 
 -- | The class of types which can be represented as a period of days.
 --
--- @since 1.12.1
+-- @since 1.13
 class Ord p => DayPeriod p where
     -- | Returns the first 'Day' in a period of days.
     periodFirstDay :: p -> Day
@@ -66,13 +66,13 @@
 
 -- | A list of all the days in this period.
 --
--- @since 1.12.1
+-- @since 1.13
 periodAllDays :: DayPeriod p => p -> [Day]
 periodAllDays p = [periodFirstDay p .. periodLastDay p]
 
 -- | The number of days in this period.
 --
--- @since 1.12.1
+-- @since 1.13
 periodLength :: DayPeriod p => p -> Int
 periodLength p = succ $ fromInteger $ diffDays (periodLastDay p) (periodFirstDay p)
 
@@ -80,26 +80,26 @@
 --
 -- @periodFromDay (periodFirstDay p) = (p,1)@
 --
--- @since 1.12.1
+-- @since 1.13
 periodFromDay :: DayPeriod p => Day -> (p, Int)
-periodFromDay d = let
-    p = dayPeriod d
-    dt = succ $ fromInteger $ diffDays d $ periodFirstDay p
-    in (p, dt)
+periodFromDay d =
+    let p = dayPeriod d
+        dt = succ $ fromInteger $ diffDays d $ periodFirstDay p
+     in (p, dt)
 
 -- | Inverse of 'periodFromDay'.
 --
--- @since 1.12.1
+-- @since 1.13
 periodToDay :: DayPeriod p => p -> Int -> Day
 periodToDay p i = addDays (toInteger $ pred i) $ periodFirstDay p
 
 -- | Validating inverse of 'periodFromDay'.
 --
--- @since 1.12.1
+-- @since 1.13
 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
+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
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
@@ -18,7 +18,7 @@
 
 -- | Given a year, find the Paschal full moon according to Orthodox Christian tradition
 orthodoxPaschalMoon :: Year -> Day
-orthodoxPaschalMoon year = addDays (-shiftedEpact) (fromJulian jyear 4 19)
+orthodoxPaschalMoon year = addDays (- shiftedEpact) (fromJulian jyear 4 19)
   where
     shiftedEpact = mod (14 + 11 * (mod year 19)) 30
     jyear =
@@ -32,7 +32,7 @@
 
 -- | Given a year, find the Paschal full moon according to the Gregorian method
 gregorianPaschalMoon :: Year -> Day
-gregorianPaschalMoon year = addDays (-adjustedEpact) (fromGregorian year 4 19)
+gregorianPaschalMoon year = addDays (- adjustedEpact) (fromGregorian year 4 19)
   where
     century = (div year 100) + 1
     shiftedEpact = mod (14 + 11 * (mod year 19) - (div (3 * century) 4) + (div (5 + 8 * century) 25)) 30
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
@@ -133,46 +133,46 @@
 
 -- | Calendrical difference, with as many whole months as possible
 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.
 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 =
-        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
+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 =
+            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
 
 -- orphan instance
 instance Show Day where
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
@@ -125,43 +125,43 @@
 
 -- | 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 =
-        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
+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 =
+            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
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
@@ -53,8 +53,7 @@
                 else 365
             )
             day
-    let
-        y = year - 1
+    let y = year - 1
         mjd = (fromIntegral day') + (365 * y) + (div y 4) - 678578
     return (ModifiedJulianDay mjd)
 
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
@@ -47,8 +47,7 @@
 monthAndDayToDayOfYearValid isLeap month day = do
     month' <- clipValid 1 12 month
     day' <- clipValid 1 (monthLength' isLeap month') day
-    let
-        day'' = fromIntegral day'
+    let day'' = fromIntegral day'
         month'' = fromIntegral month'
         k =
             if month' <= 2
@@ -105,4 +104,4 @@
     , 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
@@ -67,8 +67,7 @@
                 else 365
             )
             day
-    let
-        y = year - 1
+    let y = year - 1
         mjd = (fromIntegral day') + (365 * y) + (div y 4) - (div y 100) + (div y 400) - 678576
     return (ModifiedJulianDay mjd)
 
@@ -115,18 +114,18 @@
     -- 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
+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 ::
     -- | Year.
@@ -139,8 +138,7 @@
     Maybe Day
 fromMondayStartWeekValid year w d = do
     d' <- clipValid 1 7 d
-    let
-        -- first day of the year
+    let -- first day of the year
         firstDay = fromOrdinalDate year 1
         -- 0-based week of year
         zbFirstMonday = (5 - toModifiedJulianDay firstDay) `mod` 7
@@ -173,18 +171,18 @@
     -- 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
+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 ::
     -- | Year.
@@ -197,8 +195,7 @@
     Maybe Day
 fromSundayStartWeekValid year w d = do
     d' <- clipValid 0 6 d
-    let
-        -- first day of the year
+    let -- first day of the year
         firstDay = fromOrdinalDate year 1
         -- 0-based week of year
         zbFirstSunday = (4 - toModifiedJulianDay firstDay) `mod` 7
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
@@ -74,6 +74,6 @@
     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
--- a/lib/Data/Time/Calendar/Quarter.hs
+++ b/lib/Data/Time/Calendar/Quarter.hs
@@ -10,7 +10,6 @@
     monthOfYearQuarter,
     monthQuarter,
     dayQuarter,
-    DayOfQuarter,
     pattern QuarterDay,
 ) where
 
@@ -117,25 +116,22 @@
 
 {-# 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
+-- @since 1.13
 pattern QuarterDay :: Quarter -> DayOfQuarter -> Day
 pattern QuarterDay q dq <-
     (periodFromDay -> (q, dq))
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
@@ -6,9 +6,6 @@
     dayOfWeek,
     dayOfWeekDiff,
     firstDayOfWeekOnAfter,
-    weekAllDays,
-    weekFirstDay,
-    weekLastDay,
 ) where
 
 import Control.DeepSeq
@@ -39,14 +36,15 @@
 -- | \"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
@@ -72,55 +70,3 @@
 -- | 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
@@ -32,11 +32,11 @@
     deriving (Eq)
 
 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
+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.
@@ -47,18 +47,18 @@
     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)
+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.
@@ -71,15 +71,15 @@
     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
+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.
@@ -92,17 +92,17 @@
     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
+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 -> (Year, WeekOfYear, Int)
-toWeekDate d = let
-    (y, wy, dw) = toWeekCalendar FirstMostWeek Monday d
-    in (y, wy, fromEnum dw)
+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.
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,5 +1,3 @@
-{-# LANGUAGE CApiFFI #-}
-
 module Data.Time.Clock.Internal.CTimespec where
 
 #include "HsTimeConfig.h"
@@ -51,7 +49,8 @@
     peek ptspec
     )
 
-foreign import capi unsafe "time.h value CLOCK_REALTIME" clock_REALTIME :: ClockID
+clock_REALTIME :: ClockID
+clock_REALTIME = #{const CLOCK_REALTIME}
 
 clock_TAI :: Maybe ClockID
 clock_TAI =
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
@@ -64,9 +64,9 @@
     fromRational r = MkDiffTime (fromRational r)
 
 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
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
@@ -57,7 +57,7 @@
 getTAISystemTime :: Maybe (DiffTime, IO SystemTime)
 
 #ifdef mingw32_HOST_OS
--- On Windows, the equivalent of POSIX time is "file time", defined as
+-- On Windows, the equlvalent of POSIX time is "file time", defined as
 -- the number of 100-nanosecond intervals that have elapsed since
 -- 12:00 A.M. January 1, 1601 (UTC).  We can convert this into a POSIX
 -- time by adjusting the offset to be relative to the POSIX epoch.
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
@@ -23,10 +23,10 @@
 -- 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)
+    { -- | the day
+      utctDay :: Day
+    , -- | the time from midnight, 0 <= t < 86401s (because of leap-seconds)
+      utctDayTime :: DiffTime
     }
     deriving (Data, Typeable)
 
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
@@ -34,9 +34,9 @@
 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
@@ -27,48 +27,48 @@
 
 -- | 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
@@ -49,17 +49,16 @@
     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/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
@@ -39,28 +39,33 @@
 
 -- 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
-        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
-        Nothing -> idef
-    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
+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
+                Nothing -> idef
+        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
 
 formatGeneral ::
     Bool -> Bool -> Int -> Char -> (TimeLocale -> PadOption -> t -> String) -> (FormatOptions -> t -> String)
@@ -79,25 +84,25 @@
 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'.
 --
@@ -353,9 +358,9 @@
 
 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
+formatTime2 locale recase mpad cs t =
+    let (mwidth, rest) = pullNumber Nothing cs
+     in formatTime3 locale recase mpad mwidth rest t
 
 formatTime3 ::
     (FormatTime t) =>
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
@@ -39,11 +39,11 @@
             <|> 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
@@ -87,15 +87,15 @@
     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
@@ -166,11 +166,12 @@
     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
@@ -187,11 +188,12 @@
     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
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
@@ -231,26 +231,27 @@
 
 -- | 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
-            (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
+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)
 hourFormat :: Format TimeOfDay
-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
+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
 
 -- | ISO 8601:2004(E) sec. 4.2.2.5
 withTimeDesignator :: Format t -> Format t
@@ -262,19 +263,14 @@
 
 -- | ISO 8601:2004(E) sec. 4.2.5.1
 timeOffsetFormat :: FormatExtension -> Format TimeZone
-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 isoMap toTimeZone fromTimeZone $
-        mandatorySignFormat <**> (digits2 <++> extColonFormat fe digits2 digits2)
+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))
 
 -- | ISO 8601:2004(E) sec. 4.2.5.2
 timeOfDayAndOffsetFormat :: FormatExtension -> Format (TimeOfDay, TimeZone)
@@ -311,10 +307,10 @@
 decDesignator c = optionalFormat 0 $ decimalFormat NoSign 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
 durationDaysFormat :: Format CalendarDiffDays
@@ -322,44 +318,44 @@
 
 -- | 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
 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
 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
 intervalFormat :: Format a -> Format b -> Format (a, b)
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
@@ -4,10 +4,9 @@
 --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,
+    FormatTime (..),
+    ParseTime (..),
 ) where
 
 import Data.Format
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
@@ -26,7 +26,7 @@
 
 -- | Locale representing American usage.
 --
--- 'knownTimeZones' contains only the ten time-zones mentioned in RFC 822 sec. 5:
+-- 'knownTimeZones' contains only the ten time-zones mentioned in RFC 802 sec. 5:
 -- \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\".
 -- Note that the parsing functions will regardless parse \"UTC\", single-letter military time-zones, and +HHMM format.
 defaultTimeLocale :: TimeLocale
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
@@ -224,15 +224,13 @@
 
 -- | 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\",
--- per RFC 822 section 5.
+-- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\".
 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\",
--- per RFC 822 section 5.
+-- and these time-zones: \"UTC\", \"UT\", \"GMT\", \"EST\", \"EDT\", \"CST\", \"CDT\", \"MST\", \"MDT\", \"PST\", \"PDT\".
 instance Read ZonedTime where
     readsPrec n = readParen False $ \s -> [(ZonedTime t z, r2) | (t, r1) <- readsPrec n s, (z, r2) <- readsPrec n r1]
 
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
@@ -55,8 +55,7 @@
 -- | Case-insensitive version of 'Text.ParserCombinators.ReadP.string'.
 stringCI :: String -> ReadP String
 stringCI this = do
-    let
-        scan [] _ = return this
+    let scan [] _ = return this
         scan (x : xs) (y : ys)
             | toUpper x == toUpper y = do
                 _ <- get
@@ -66,38 +65,41 @@
     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
-        _ <- satisfy isSpace
-        case cs of
-            (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
+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 ()
+                    _ -> 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
 
 data PaddingSide
     = PrePadding
@@ -136,78 +138,76 @@
     return $ sign ++ digits ++ decimaldigits
 
 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)
-    allowNegative :: ReadP String -> ReadP String
-    allowNegative p = (char '-' >> fmap ('-' :) p) <++ p
-    in case c of
-        -- century
-        'C' -> allowNegative $ digits SpacePadding 2
-        'f' -> allowNegative $ digits SpacePadding 2
-        -- year
-        'Y' -> allowNegative $ digits SpacePadding 4
-        'G' -> allowNegative $ 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
-                    (am, pm) = amPm l
-                    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
+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)
+        allowNegative :: ReadP String -> ReadP String
+        allowNegative p = (char '-' >> fmap ('-' :) p) <++ p
+     in case c of
+            -- century
+            'C' -> allowNegative $ digits SpacePadding 2
+            'f' -> allowNegative $ digits SpacePadding 2
+            -- year
+            'Y' -> allowNegative $ digits SpacePadding 4
+            'G' -> allowNegative $ 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 (am, pm) = amPm l
+                       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
 
 timeSubstituteTimeSpecifier :: TimeLocale -> Char -> Maybe String
 timeSubstituteTimeSpecifier l 'c' = Just $ dateTimeFmt l
@@ -222,19 +222,19 @@
 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 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
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
@@ -49,118 +49,115 @@
     | MondayWeek
 
 makeDayComponent :: TimeLocale -> Char -> String -> Maybe [DayComponent]
-makeDayComponent 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 [DCCentury a]
-        -- %f century (all but the last two digits of the year), 00 - 99
-        'f' -> do
-            a <- ra
-            return [DCCentury a]
-        -- %Y: year
-        'Y' -> do
-            a <- ra
-            return [DCCentury (a `div` 100), DCCenturyYear (a `mod` 100)]
-        -- %G: year for Week Date format
-        'G' -> do
-            a <- ra
-            return [DCCentury (a `div` 100), DCCenturyYear (a `mod` 100)]
-        -- %y: last two digits of year, 00 - 99
-        'y' -> do
-            a <- ra
-            return [DCCenturyYear a]
-        -- %g: last two digits of year for Week Date format, 00 - 99
-        'g' -> do
-            a <- ra
-            return [DCCenturyYear a]
-        -- %B: month name, long form (fst from months locale), January - December
-        'B' -> do
-            a <- oneBasedListIndex $ fmap fst $ months l
-            return [DCYearMonth a]
-        -- %b: month name, short form (snd from months locale), Jan - Dec
-        'b' -> do
-            a <- oneBasedListIndex $ fmap snd $ months l
-            return [DCYearMonth a]
-        -- %m: month of year, leading 0 as needed, 01 - 12
-        'm' -> do
-            raw <- ra
-            a <- clipValid 1 12 raw
-            return [DCYearMonth a]
-        -- %d: day of month, leading 0 as needed, 01 - 31
-        'd' -> do
-            raw <- ra
-            a <- clipValid 1 31 raw
-            return [DCMonthDay a]
-        -- %e: day of month, leading space as needed, 1 - 31
-        'e' -> do
-            raw <- ra
-            a <- clipValid 1 31 raw
-            return [DCMonthDay a]
-        -- %V: week for Week Date format, 01 - 53
-        'V' -> do
-            raw <- ra
-            a <- clipValid 1 53 raw
-            return [DCYearWeek 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 [DCYearWeek 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 [DCYearWeek MondayWeek a]
-        -- %u: day for Week Date format, 1 - 7
-        'u' -> do
-            raw <- ra
-            a <- clipValid 1 7 raw
-            return [DCWeekDay 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 [DCWeekDay 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 [DCWeekDay 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 [DCWeekDay a]
-        -- %j: day of year for Ordinal Date format, 001 - 366
-        'j' -> do
-            raw <- ra
-            a <- clipValid 1 366 raw
-            return [DCYearDay a]
-        -- unrecognised, pass on to other parsers
-        _ -> return []
+makeDayComponent 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 [DCCentury a]
+            -- %f century (all but the last two digits of the year), 00 - 99
+            'f' -> do
+                a <- ra
+                return [DCCentury a]
+            -- %Y: year
+            'Y' -> do
+                a <- ra
+                return [DCCentury (a `div` 100), DCCenturyYear (a `mod` 100)]
+            -- %G: year for Week Date format
+            'G' -> do
+                a <- ra
+                return [DCCentury (a `div` 100), DCCenturyYear (a `mod` 100)]
+            -- %y: last two digits of year, 00 - 99
+            'y' -> do
+                a <- ra
+                return [DCCenturyYear a]
+            -- %g: last two digits of year for Week Date format, 00 - 99
+            'g' -> do
+                a <- ra
+                return [DCCenturyYear a]
+            -- %B: month name, long form (fst from months locale), January - December
+            'B' -> do
+                a <- oneBasedListIndex $ fmap fst $ months l
+                return [DCYearMonth a]
+            -- %b: month name, short form (snd from months locale), Jan - Dec
+            'b' -> do
+                a <- oneBasedListIndex $ fmap snd $ months l
+                return [DCYearMonth a]
+            -- %m: month of year, leading 0 as needed, 01 - 12
+            'm' -> do
+                raw <- ra
+                a <- clipValid 1 12 raw
+                return [DCYearMonth a]
+            -- %d: day of month, leading 0 as needed, 01 - 31
+            'd' -> do
+                raw <- ra
+                a <- clipValid 1 31 raw
+                return [DCMonthDay a]
+            -- %e: day of month, leading space as needed, 1 - 31
+            'e' -> do
+                raw <- ra
+                a <- clipValid 1 31 raw
+                return [DCMonthDay a]
+            -- %V: week for Week Date format, 01 - 53
+            'V' -> do
+                raw <- ra
+                a <- clipValid 1 53 raw
+                return [DCYearWeek 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 [DCYearWeek 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 [DCYearWeek MondayWeek a]
+            -- %u: day for Week Date format, 1 - 7
+            'u' -> do
+                raw <- ra
+                a <- clipValid 1 7 raw
+                return [DCWeekDay 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 [DCWeekDay 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 [DCWeekDay 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 [DCWeekDay a]
+            -- %j: day of year for Ordinal Date format, 001 - 366
+            'j' -> do
+                raw <- ra
+                a <- clipValid 1 366 raw
+                return [DCYearDay a]
+            -- unrecognised, pass on to other parsers
+            _ -> return []
 
 makeDayComponents :: TimeLocale -> [(Char, String)] -> Maybe [DayComponent]
 makeDayComponents l pairs = do
@@ -177,27 +174,26 @@
         cs <- makeDayComponents l pairs
         -- 'Nothing' indicates a parse failure,
         -- while 'Just []' means no information
-        let
-            y = let
-                d = safeLast 70 [x | DCCenturyYear x <- cs]
-                c =
-                    safeLast
-                        ( if d >= 69
-                            then 19
-                            else 20
-                        )
-                        [x | DCCentury x <- cs]
-                in 100 * c + d
-            rest (DCYearMonth m : _) = let
-                d = safeLast 1 [x | DCMonthDay x <- cs]
-                in fromGregorianValid y m d
+        let y =
+                let d = safeLast 70 [x | DCCenturyYear x <- cs]
+                    c =
+                        safeLast
+                            ( if d >= 69
+                                then 19
+                                else 20
+                            )
+                            [x | DCCentury x <- cs]
+                 in 100 * c + d
+            rest (DCYearMonth m : _) =
+                let d = safeLast 1 [x | DCMonthDay x <- cs]
+                 in fromGregorianValid y m d
             rest (DCYearDay d : _) = fromOrdinalDateValid y d
-            rest (DCYearWeek wt w : _) = let
-                d = safeLast 4 [x | DCWeekDay x <- cs]
-                in case wt of
-                    ISOWeek -> fromWeekDateValid y w d
-                    SundayWeek -> fromSundayStartWeekValid y w (d `mod` 7)
-                    MondayWeek -> fromMondayStartWeekValid y w d
+            rest (DCYearWeek wt w : _) =
+                let d = safeLast 4 [x | DCWeekDay 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 [DCYearMonth 1]
         rest cs
@@ -209,91 +205,90 @@
         cs <- makeDayComponents l pairs
         -- 'Nothing' indicates a parse failure,
         -- while 'Just []' means no information
-        let
-            y = let
-                d = safeLast 70 [x | DCCenturyYear x <- cs]
-                c =
-                    safeLast
-                        ( if d >= 69
-                            then 19
-                            else 20
-                        )
-                        [x | DCCentury x <- cs]
-                in 100 * c + d
+        let y =
+                let d = safeLast 70 [x | DCCenturyYear x <- cs]
+                    c =
+                        safeLast
+                            ( if d >= 69
+                                then 19
+                                else 20
+                            )
+                            [x | DCCentury x <- cs]
+                 in 100 * c + d
             rest (DCYearMonth m : _) = fromYearMonthValid y m
             rest (_ : xs) = rest xs
             rest [] = fromYearMonthValid y 1
         rest cs
 
 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
+mfoldl f =
+    let mf ma b = do
+            a <- ma
+            f a b
+     in foldl mf
 
 instance ParseTime TimeOfDay 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
-                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
+    buildTime l =
+        let f t@(TimeOfDay h m s) (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)
-                _ -> Just t
-        in mfoldl f (Just midnight)
+                        '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)
 
 rpad :: Int -> a -> [a] -> [a]
 rpad n c xs = xs ++ replicate (n - length xs) c
@@ -323,11 +318,11 @@
 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)
@@ -335,50 +330,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)
+                | 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)
 
 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
@@ -414,19 +408,20 @@
 
 buildTimeSeconds :: [(Char, String)] -> Maybe Pico
 buildTimeSeconds xs = do
-    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
+    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
     return $ sum tt
 
 instance ParseTime NominalDiffTime where
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
@@ -31,13 +31,13 @@
 -- @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.
-    -- Any local minute may have a leap second, since leap seconds happen in all zones simultaneously
+    { -- | range 0 - 23
+      todHour :: Int
+    , -- | range 0 - 59
+      todMin :: Int
+    , -- | Note that 0 <= 'todSec' < 61, accomodating leap seconds.
+      -- Any local minute may have a leap second, since leap seconds happen in all zones simultaneously
+      todSec :: Pico
     }
     deriving (Eq, Ord, Data, Typeable)
 
@@ -65,12 +65,12 @@
 -- | 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
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
@@ -26,12 +26,12 @@
 
 -- | A TimeZone is a whole number of minutes offset from UTC, together with a name and a \"just for summer\" flag.
 data TimeZone = TimeZone
-    { timeZoneMinutes :: Int
-    -- ^ The number of minutes offset from UTC. Positive means local time will be later in the day than UTC.
-    , timeZoneSummerOnly :: Bool
-    -- ^ Is this time zone just persisting for the summer?
-    , timeZoneName :: String
-    -- ^ The name of the zone, typically a three- or four-letter acronym.
+    { -- | The number of minutes offset from UTC. Positive means local time will be later in the day than UTC.
+      timeZoneMinutes :: Int
+    , -- | Is this time zone just persisting for the summer?
+      timeZoneSummerOnly :: Bool
+    , -- | The name of the zone, typically a three- or four-letter acronym.
+      timeZoneName :: String
     }
     deriving (Eq, Ord, Data, Typeable)
 
@@ -48,11 +48,12 @@
 
 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
-        NoPad -> NoPad
-        Pad i c -> Pad (max 0 $ i - 3) c
-    in showPaddedNum opt' (div t 60) ++ ":" ++ show2 (mod t 60)
+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)
 
 timeZoneOffsetString'' :: Bool -> PadOption -> TimeZone -> String
 timeZoneOffsetString'' colon opt (TimeZone t _ _)
@@ -103,52 +104,25 @@
 
 -- 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"
+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).
+-- | 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 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
+-- | 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 configured time-zone for the current time.
+-- | 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
@@ -37,7 +37,6 @@
 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
 
@@ -51,6 +50,7 @@
     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,7 +5,7 @@
 {
 #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)
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
@@ -82,6 +82,9 @@
 /* Define to 1 if you have the ANSI C header files. */
 #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
 
diff --git a/test/ShowTime.hs b/test/ShowTime.hs
deleted file mode 100644
--- a/test/ShowTime.hs
+++ /dev/null
@@ -1,8 +0,0 @@
-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
@@ -39,7 +39,7 @@
             , clipDates
             , convertBack
             , longWeekYears
-            , testDayPeriod
+            , testHasDays
             , testMonthDay
             , testMonthOfYear
             , testEaster
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
@@ -39,24 +39,24 @@
 
 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 []
-        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
+    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 []
+            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
 
 instance CoArbitrary Day where
     coarbitrary (ModifiedJulianDay d) = coarbitrary d
@@ -97,28 +97,29 @@
 
 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
-            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]
+    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]
 
 instance CoArbitrary TimeOfDay where
     coarbitrary t = coarbitrary (timeOfDayToTime t)
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
@@ -23,9 +23,9 @@
 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
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
@@ -10,19 +10,19 @@
 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 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
--- a/test/main/Test/Calendar/DayPeriod.hs
+++ b/test/main/Test/Calendar/DayPeriod.hs
@@ -1,11 +1,10 @@
 module Test.Calendar.DayPeriod (
-    testDayPeriod,
+    testHasDays,
 ) 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
@@ -47,30 +46,14 @@
 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 =
+testHasDays :: TestTree
+testHasDays =
     testGroup
         "DayPeriod"
         [ testGroup "Day" testDay
         , testGroup "Month" testMonth
         , testGroup "Quarter" testQuarter
         , testGroup "Year" testYear
-        , testGroup "Week" testWeek
         ]
 
 testDay :: [TestTree]
@@ -79,12 +62,6 @@
         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]
@@ -98,19 +75,6 @@
         , 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]
@@ -137,12 +101,6 @@
         , 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]
@@ -151,25 +109,4 @@
         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
@@ -24,12 +24,12 @@
         ]
 
 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
+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
 
 testDiffs :: TestTree
 testDiffs =
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
@@ -18,20 +18,20 @@
 
 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/MonthDay.hs b/test/main/Test/Calendar/MonthDay.hs
--- a/test/main/Test/Calendar/MonthDay.hs
+++ b/test/main/Test/Calendar/MonthDay.hs
@@ -24,10 +24,9 @@
     yearDays isLeap =
         map
             ( \yd ->
-                let
-                    (m, d) = dayOfYearToMonthAndDay isLeap yd
+                let (m, d) = dayOfYearToMonthAndDay isLeap yd
                     yd' = monthAndDayToDayOfYear isLeap m d
                     mdtext = show m ++ "-" ++ show d
-                    in showCompare yd mdtext yd'
+                 in showCompare yd mdtext yd'
             )
             [-2 .. 369]
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
@@ -11,36 +11,36 @@
 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) =>
@@ -58,16 +58,16 @@
         ]
 
 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 WYear
     = MkWYear Year
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
@@ -99,27 +99,27 @@
 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_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_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_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
+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 =
@@ -135,105 +135,5 @@
         , 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 =
-    nameTest
-        "Week"
-        [ testDay
-        , testSucc
-        , testPred
-        , testSequences
-        , testReadShow
-        , testDiff
-        , testWeekDays
-        ]
+testWeek = nameTest "Week" [testDay, testSucc, testPred, testSequences, testReadShow, testDiff]
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
@@ -9,17 +9,17 @@
 
 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
-                ]
-        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)
-           ]
+    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)
+            ]
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
@@ -51,8 +51,7 @@
                 do
                     threadDelay 1000 -- 1ms
                     getTime
-        let
-            times = fmap (\t -> timeDiff t t0) $ times0 ++ times1 ++ times2 ++ times3 ++ times4
+        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
 
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
@@ -19,28 +19,28 @@
 
 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
+    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
+            , testCase "day length" $ do
                 assertEqual "dayA" (Just 86401) $ utcDayLength sampleLeapSecondMap dayA
                 assertEqual "dayB" (Just 86400) $ utcDayLength sampleLeapSecondMap dayB
-           , testCase "differences" $ do
+            , 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
+            , testGroup
                 "round-trip"
                 [ testCase "1" $ do
                     absTime <- assertJust mAbsTime1
@@ -55,4 +55,4 @@
                     utcTime <- assertJust $ taiToUTCTime sampleLeapSecondMap absTime
                     assertEqual "round-trip" utcTime3 utcTime
                 ]
-           ]
+            ]
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
@@ -39,8 +39,7 @@
 compareExpected :: (Eq t, Show t, ParseTime t) => String -> String -> String -> Proxy t -> TestTree
 compareExpected testname fmt str proxy =
     testCase testname $ do
-        let
-            found :: ParseTime t => Proxy t -> Maybe t
+        let found :: ParseTime t => Proxy t -> Maybe t
             found _ = parseTimeM False defaultTimeLocale fmt str
         assertEqual "" Nothing $ found proxy
 
@@ -63,10 +62,10 @@
 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 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 =
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
@@ -23,10 +23,9 @@
     case formatShowM fmt val of
         Nothing -> property Discard
         Just str ->
-            let
-                found = formatParseM fmt str
+            let found = formatParseM fmt str
                 expected = Just val
-                in property $
+             in property $
                     if expected == found
                         then succeeded
                         else failed{reason = show str ++ ": expected " ++ (show expected) ++ ", found " ++ (show found)}
@@ -69,13 +68,13 @@
         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 (MkFormat sa ra) = MkFormat (\b -> sa $ unDurational b) (fmap MkDurational ra)
@@ -127,67 +126,59 @@
                 recurringIntervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
         ]
 
-testShowReadFormat :: (Show t, Eq t) => String -> Format t -> String -> t -> TestTree
-testShowReadFormat name fmt str val =
-    nameTest
-        (name ++ ": " ++ str)
-        [ nameTest "show" $ assertEqual "" (Just str) $ formatShowM fmt val
-        , nameTest "read" $ assertEqual "" (Just val) $ formatParseM fmt str
-        ]
-
-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
+testShowFormat :: String -> Format t -> String -> t -> TestTree
+testShowFormat name fmt str t = nameTest (name ++ ": " ++ str) $ assertEqual "" (Just str) $ formatShowM fmt t
 
 testShowFormats :: TestTree
 testShowFormats =
     nameTest
         "show format"
-        [ 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" $
+        [ 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
-        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P7Y10M5DT2H1M18.77634S" $
+        , testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10M5DT2H1M18.77634S" $
             CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634
-        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P7Y10MT2H1M18.77634S" $
+        , testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10MT2H1M18.77634S" $
             CalendarDiffTime 94 $ 7278.77634
-        , testShowReadFormat "durationTimeFormat" durationTimeFormat "P8YT2H1M18.77634S" $ CalendarDiffTime 96 $ 7278.77634
-        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0001-00-00" $
+        , testShowFormat "durationTimeFormat" durationTimeFormat "P8YT2H1M18.77634S" $ CalendarDiffTime 96 $ 7278.77634
+        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0001-00-00" $
             CalendarDiffDays 12 0
-        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0002-03-29" $
+        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0002-03-29" $
             CalendarDiffDays 27 29
-        , testShowReadFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0561-08-29" $
+        , testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0561-08-29" $
             CalendarDiffDays (561 * 12 + 8) 29
-        , testShowReadFormat
+        , testShowFormat
             "alternativeDurationTimeFormat"
             (alternativeDurationTimeFormat ExtendedFormat)
             "P0000-00-01T00:00:00"
             $ CalendarDiffTime 0 86400
-        , testShowReadFormat
+        , testShowFormat
             "alternativeDurationTimeFormat"
             (alternativeDurationTimeFormat ExtendedFormat)
             "P0007-10-05T02:01:18.77634"
             $ CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634
-        , testShowReadFormat
+        , testShowFormat
             "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
+        , testShowFormat "centuryFormat" centuryFormat "02" 2
+        , testShowFormat "centuryFormat" centuryFormat "21" 21
+        , testShowFormat
             "intervalFormat etc."
             ( intervalFormat
                 (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
@@ -197,7 +188,7 @@
             ( LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
             , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34
             )
-        , testShowReadFormat
+        , testShowFormat
             "recurringIntervalFormat etc."
             ( recurringIntervalFormat
                 (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat))
@@ -208,105 +199,75 @@
             , LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56)
             , CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34
             )
-        , testShowReadFormat
+        , testShowFormat
             "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
+        , 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)
-        , testShowReadFormat "timeOffsetFormat" (timeOffsetFormat BasicFormat) "+1015" (minutesToTimeZone $ 615)
-        , testShowReadFormat
+        , 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)))
-        , 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
+        , testShowFormat
             "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
+        , testShowFormat
             "utcTimeFormat"
             iso8601Format
             "2024-07-06T08:45:56.553Z"
             (UTCTime (fromGregorian 2024 07 06) (timeOfDayToTime $ TimeOfDay 8 45 56.553))
-        , testShowReadFormat
+        , testShowFormat
             "utcTimeFormat"
             iso8601Format
             "2028-12-31T23:59:60.9Z"
             (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
+        , 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)
-        , 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
+        , 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)
-        , 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)
+        , 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)
         ]
 
 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
@@ -40,15 +40,15 @@
     }
 
 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
@@ -65,19 +65,22 @@
 minCodeWidth _ = 0
 
 fcShrink :: FormatCode pf t -> [FormatCode pf t]
-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
-        False -> []
-        True -> [fc{fcAlt = False}]
-    fc3 = case fcModifier fc of
-        "" -> []
-        _ -> [fc{fcModifier = ""}]
-    in fc1 ++ fc2 ++ fc3
+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
+                False -> []
+                True -> [fc{fcAlt = False}]
+        fc3 =
+            case fcModifier fc of
+                "" -> []
+                _ -> [fc{fcModifier = ""}]
+     in fc1 ++ fc2 ++ fc3
 
 instance HasFormatCodes t => Arbitrary (FormatCode FormatOnly t) where
     arbitrary = do
@@ -153,11 +156,11 @@
         )
 
 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
+readTest expected target =
+    let found = reads target
+        result = assertEqual "" expected found
+        name = show target
+     in Test.Tasty.HUnit.testCase name result
 
 readTestsParensSpaces ::
     forall a.
@@ -189,9 +192,9 @@
     testGroup
         "read times"
         [ readTestsParensSpaces testDay "1912-07-08"
-        , -- readTestsParensSpaces testDay "1912-7-8",
+        , --readTestsParensSpaces testDay "1912-7-8",
           readTestsParensSpaces testTimeOfDay "08:04:02"
-          -- ,readTestsParensSpaces testTimeOfDay "8:4:2"
+          --,readTestsParensSpaces testTimeOfDay "8:4:2"
         ]
   where
     testDay = fromGregorian 1912 7 8
@@ -227,11 +230,11 @@
         ]
   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
+    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 =
@@ -265,20 +268,24 @@
 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
@@ -298,18 +305,18 @@
     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 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
@@ -321,8 +328,10 @@
 
 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
@@ -364,9 +373,9 @@
 
 --
 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)
 
 --
 
@@ -382,9 +391,6 @@
 prop_read_show_LocalUTC :: LocalTime -> Result
 prop_read_show_LocalUTC t = compareResult (Just $ localTimeToUTC utc t) (readMaybe (show t))
 
-prop_read_show_UTC_no_TZ :: UTCTime -> Result
-prop_read_show_UTC_no_TZ t = compareResult (Just t) $ readMaybe $ show $ utcToLocalTime utc t
-
 --
 
 -- * special show functions
@@ -405,16 +411,16 @@
 
 --
 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
@@ -444,13 +450,13 @@
     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
+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"]
@@ -550,22 +556,22 @@
 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
-       ]
+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.
@@ -623,12 +629,11 @@
         , 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 "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)
+        --nameTest "CalendarDiffDays" (prop_read_show :: CalendarDiffDays -> Result),
+        --nameTest "CalendarDiffTime" (prop_read_show :: CalendarDiffTime -> Result)
         ]
 
 parseShowTests :: TestTree
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
@@ -2,16 +2,16 @@
     testCalendarDiffTime,
 ) where
 
--- import Data.Time.LocalTime
+--import Data.Time.LocalTime
 import Test.Arbitrary ()
 import Test.Tasty
 
--- import Test.Tasty.QuickCheck hiding (reason)
--- testReadShow :: TestTree
--- testReadShow = testProperty "read . show" $ \(t :: CalendarDiffTime) -> read (show t) == t
+--import Test.Tasty.QuickCheck hiding (reason)
+--testReadShow :: TestTree
+--testReadShow = testProperty "read . show" $ \(t :: CalendarDiffTime) -> read (show t) == t
 testCalendarDiffTime :: TestTree
 testCalendarDiffTime =
     testGroup
         "CalendarDiffTime"
-        -- testReadShow
+        --testReadShow
         []
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
@@ -10,16 +10,16 @@
 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 =
@@ -63,10 +63,10 @@
 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,15 +86,15 @@
         ]
 
 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 =
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
@@ -11,12 +11,12 @@
 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/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
@@ -76,20 +76,19 @@
 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
         mins <- choose (-2000, 2000)
         dst <- arbitrary
         hasName <- arbitrary
-        let
-            name =
+        let name =
                 if hasName
                     then "ZONE"
                     else ""
@@ -104,17 +103,16 @@
 
 -- | 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
         day <- choose (-25000, 75000)
         time <- arbitrary
-        let
-            -- verify that the created time can fit in the local CTime
+        let -- verify that the created time can fit in the local CTime
             localT = LocalTime (ModifiedJulianDay day) time
             utcT = localTimeToUTC utc localT
             secondsInteger = floor (utcTimeToPOSIXSeconds utcT)
@@ -147,12 +145,12 @@
 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
+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
@@ -200,10 +198,10 @@
 
 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 =
diff --git a/time.cabal b/time.cabal
--- a/time.cabal
+++ b/time.cabal
@@ -1,6 +1,6 @@
 cabal-version:  3.0
 name:           time
-version:        1.12.2
+version:        1.13
 stability:      stable
 license:        BSD-2-Clause
 license-file:   LICENSE
@@ -13,9 +13,9 @@
 category:       Time
 build-type:     Configure
 tested-with:
+    GHC == 8.8.4,
     GHC == 8.10.7,
-    GHC == 9.0.2,
-    GHC == 9.2.2
+    GHC == 9.0.1
 x-follows-version-policy:
 
 extra-source-files:
@@ -49,7 +49,7 @@
     ghc-options: -Wall -fwarn-tabs
     c-sources: lib/cbits/HsTime.c
     build-depends:
-        base >= 4.14 && < 5,
+        base >= 4.13 && < 5,
         deepseq >= 1.1
     if os(windows)
         build-depends: Win32
@@ -121,16 +121,6 @@
         base,
         time
     main-is: ShowDefaultTZAbbreviations.hs
-
-test-suite ShowTime
-    type: exitcode-stdio-1.0
-    hs-source-dirs: test
-    default-language: Haskell2010
-    ghc-options: -Wall -fwarn-tabs
-    build-depends:
-        base,
-        time
-    main-is: ShowTime.hs
 
 test-suite test-main
     type: exitcode-stdio-1.0
