@@ -35,7 +35,7 @@ import Data.Generic.Rep (class Generic)
3535import Data.Generic.Rep.Show (genericShow )
3636import Data.Int as Int
3737import Data.List as List
38- import Data.Maybe (Maybe (..), maybe , fromMaybe )
38+ import Data.Maybe (Maybe (..), fromMaybe , isJust , maybe )
3939import Data.Newtype (unwrap )
4040import Data.Ord (abs )
4141import Data.String as Str
@@ -189,23 +189,24 @@ formatCommand dt@(DT.DateTime d t) = case _ of
189189 MillisecondsTwoDigits → padSingleDigit $ (_ / 10 ) $ fromEnum $ T .millisecond t
190190 Placeholder s → s
191191
192- -- TODO we need leftpad here
193-
194192padSingleDigit ∷ Int → String
195193padSingleDigit i
196- | i < 10 = " 0" <> (show i)
194+ | i < 0 = " -" <> padSingleDigit (-i)
195+ | i < 10 = " 0" <> (show i)
197196 | otherwise = show i
198197
199198padDoubleDigit ∷ Int → String
200199padDoubleDigit i
200+ | i < 0 = " -" <> padDoubleDigit (-i)
201201 | i < 10 = " 00" <> (show i)
202202 | i < 100 = " 0" <> (show i)
203203 | otherwise = show i
204204
205205padQuadrupleDigit ∷ Int → String
206206padQuadrupleDigit i
207- | i < 10 = " 000" <> (show i)
208- | i < 100 = " 00" <> (show i)
207+ | i < 0 = " -" <> padQuadrupleDigit (-i)
208+ | i < 10 = " 000" <> (show i)
209+ | i < 100 = " 00" <> (show i)
209210 | i < 1000 = " 0" <> (show i)
210211 | otherwise = show i
211212
@@ -223,7 +224,6 @@ data Meridiem = AM | PM
223224
224225derive instance eqMeridiem ∷ Eq Meridiem
225226
226- -- TODO: consider using Map Int
227227type UnformatAccum =
228228 { year ∷ Maybe Int
229229 , month ∷ Maybe Int
@@ -284,8 +284,6 @@ adjustMeridiem (Just AM) n = n
284284adjustMeridiem Nothing 24 = 0
285285adjustMeridiem Nothing n = n
286286
287-
288-
289287exactLength ∷ ∀ e . ReaderT { maxLength ∷ Int , length ∷ Int | e } (Either String ) Unit
290288exactLength = ask >>= \({maxLength, length}) → lift if maxLength /= length
291289 then Left $ " Expected " <> (show maxLength) <> " digits but got " <> (show length)
@@ -314,6 +312,15 @@ takeMany :: ∀ f a. Alternative f ⇒ Z.Lazy (f (List.List a)) ⇒ Int → f a
314312takeMany 0 _ = pure List.Nil
315313takeMany n v = takeSome n v <|> pure List.Nil
316314
315+ parseSignedInt ∷ ∀ m
316+ . Monad m
317+ ⇒ Int
318+ → ReaderT { length ∷ Int , num ∷ Int , maxLength ∷ Int } (Either String ) Unit
319+ → String
320+ → P.ParserT String m Int
321+ parseSignedInt maxLength validators errMsg = do
322+ isNegative ← isJust <$> PC .optionMaybe (PS .char ' -' )
323+ (if isNegative then negate else identity) <$> parseInt maxLength validators errMsg
317324
318325parseInt ∷ ∀ m
319326 . Monad m
@@ -333,9 +340,9 @@ parseInt maxLength validators errMsg = do
333340unformatCommandParser ∷ FormatterCommand → P.ParserT String (State UnformatAccum ) Unit
334341unformatCommandParser = case _ of
335342 YearFull → _{year = _} `modifyWithParser`
336- (parseInt 4 exactLength " Incorrect full year" )
343+ (parseSignedInt 4 exactLength " Incorrect full year" )
337344 YearTwoDigits → _{year = _} `modifyWithParser`
338- (parseInt 2 exactLength " Incorrect 2-digit year" )
345+ (parseSignedInt 2 exactLength " Incorrect 2-digit year" )
339346 YearAbsolute → _{year = _} `modifyWithParser`
340347 (lift2 (*)
341348 (PC .option 1 $ PC .try $ PS .string " -" <#> (const (-1 )))
@@ -405,8 +412,6 @@ unformatParser f = do
405412 unState s = case runState s initialAccum of
406413 Tuple (Tuple e state) res → pure (Tuple (e $> res) state)
407414
408-
409-
410415unformatDateTime ∷ String → String → Either String DT.DateTime
411416unformatDateTime pattern str =
412417 parseFormatString pattern >>= (_ `unformat` str)
@@ -419,7 +424,6 @@ parseMeridiem = (PC.try <<< PS.string) `oneOfAs`
419424 , Tuple " PM" PM
420425 ]
421426
422-
423427parseDayOfWeekName ∷ ∀ m . Monad m ⇒ P.ParserT String m D.Weekday
424428parseDayOfWeekName = (PC .try <<< PS .string) `oneOfAs`
425429 [ Tuple " Monday" D.Monday
0 commit comments