tzParser :: A.Parser Tz
tzParser = do
  hh <- A.signed A.decimal
  mm <-
    A.peekChar >>= \case
      Just ':' -> A.char ':' *> A.decimal
      Just _ -> A.decimal
      Nothing -> pure 0
  guard $ isTzValid (abs hh) mm
  pure (hh, sign hh * mm)
  where
    sign n
      | n >= 0 = 1
      | otherwise = -1
    isTzValid 18 0  = True
    isTzValid hh mm = hh >= 0 && hh < 18 && mm >= 0 && mm < 60
tzParser :: A.Parser Tz
tzParser = do
  hh <- A.signed A.decimal
  mm <-
    A.peekChar >>= \case
      Just ':' -> A.char ':' *> A.decimal
      Just _ -> A.decimal
      Nothing -> pure 0
  guard $ isTzValid (abs hh) mm
  pure (hh, sign hh * mm)
  where
    sign n
      | n >= 0 = 1
      | otherwise = -1
    isTzValid 18 0  = True
    isTzValid hh mm = hh >= 0 && hh < 18 && mm >= 0 && mm < 60
tzParser = do
  hh <- A.signed A.decimal
  mm <-
    A.peekChar >>= \case
      Just ':' -> A.char ':' *> A.decimal
      Just _ -> A.decimal
      Nothing -> pure 0
  guard $ isTzValid (abs hh) mm
  pure (hh, sign hh * mm)
  where
    sign n
      | n >= 0 = 1
      | otherwise = -1
    isTzValid 18 0  = True
    isTzValid hh mm = hh >= 0 && hh < 18 && mm >= 0 && mm < 60