fork download
  1. (define-condition time-string-parse-error (parse-error)
  2. ())
  3.  
  4. (define-condition invalid-time-string-error (time-string-parse-error)
  5. ((string :initarg :string))
  6. (:report (lambda (condition stream)
  7. (format stream "Invalid time string: ~S"
  8. (slot-value condition 'string)))))
  9.  
  10. (defun parse-time-string (string)
  11. (unless (stringp string)
  12. (error 'type-error :datum string :expected-type 'string))
  13. (unless (every (lambda (c)
  14. (find c (concatenate 'string "012345679: " #(#\Tab))))
  15. string)
  16. (error (make-condition 'invalid-time-string-error :string string)))
  17. (unless (= (count #\: string) 2)
  18. (error (make-condition 'invalid-time-string-error :string string)))
  19. (let* ((c1 (position #\: string))
  20. (c2 (position #\: string :start (1+ c1)))
  21. (parts (list (subseq string 0 c1)
  22. (subseq string (1+ c1) c2)
  23. (subseq string (1+ c2))))
  24. (parts (mapcar (lambda (x)
  25. (handler-case (parse-integer x :radix 10)
  26. (parse-error (e) e)))
  27. parts)))
  28. (unless (and (= (length parts) 3)
  29. (every #'integerp parts))
  30. (error (make-condition 'invalid-time-string-error :string string)))
  31. (destructuring-bind (h m s) parts
  32. (unless (and (<= 0 h 23)
  33. (<= 0 m 59)
  34. (<= 0 s 59))
  35. (error (make-condition 'invalid-time-string-error :string string))))
  36. parts))
  37.  
  38.  
  39. (defun +sec (time-string sec)
  40. (destructuring-bind (h m s)
  41. (parse-time-string time-string)
  42. (let ((time (+ (* h 60 60)
  43. (* m 60)
  44. (* s 1)
  45. sec)))
  46. (multiple-value-setq (time s) (floor time 60))
  47. (multiple-value-setq (time m) (floor time 60))
  48. (multiple-value-setq (time h) (floor time 24))
  49. (format nil "~2,'0D:~2,'0D:~2,'0D" h m s))))
  50.  
  51.  
  52. (loop for s = (read-line nil nil)
  53. while s
  54. for a = (handler-case (+sec s 1)
  55. (invalid-time-string-error (e)
  56. (princ-to-string e)))
  57. do (write-line a))
  58.  
Success #stdin #stdout 0.02s 30708KB
stdin
00:00:00
23:59:59
0:0:0
 1 : 23 : 045
0
0:0:0:0
23:59:60
15:29:07
stdout
00:00:01
00:00:00
00:00:01
01:23:46
Invalid time string: "0"
Invalid time string: "0:0:0:0"
Invalid time string: "23:59:60"
Invalid time string: "15:29:07"