1(in-package #:local-time.test)
2
3(defsuite* (parsing :in test))
4
5(deftest test/parsing/parse-format-consistency/range (&key (start-day -100000) (end-day 100000))
6  (declare (optimize debug))
7  (without-test-progress-printing
8    (loop
9      :with time = (make-timestamp)
10      :for day :from start-day :upto end-day
11      :for index :upfrom 0 :do
12        (setf (day-of time) day)
13        (when (zerop (mod index 10000))
14          (print time))
15        (let ((parsed (parse-timestring (format-timestring nil time))))
16          (is (timestamp= parsed time))))))
17
18(deftest test/parsing/parse-format-consistency ()
19  (flet ((compare (nsec sec min hour day mon year str
20                        &key start end offset
21                        (allow-missing-elements t))
22           (let* ((timestamp-a (encode-timestamp nsec sec min hour
23                                                 day mon year :offset offset))
24                  (used-offset (or offset
25                                   (local-time::%guess-offset (sec-of timestamp-a)
26                                                              (day-of timestamp-a))))
27                  (timestamp-b (parse-timestring str
28                                                 :start start
29                                                 :end end
30                                                 :allow-missing-elements
31                                                 allow-missing-elements
32                                                 :offset used-offset)))
33             (is (timestamp= timestamp-a timestamp-b)))))
34    (let ((timestamp (now)))
35      (is (timestamp= timestamp
36                      (parse-timestring
37                       (format-timestring nil timestamp)))))
38
39    (let* ((*default-timezone* (find-timezone-by-location-name "Europe/Budapest")))
40      (compare 0 0 0 0 1 1 1 "0001-01-01T00:00:00,0"))
41
42    (compare 0 0 0 0 1 1 1 "0001-01-01T00:00:00Z" :offset 0)
43
44    (compare 0 0 0 0 1 1 2006 "2006-01-01T00:00:00,0")
45    (compare 0 0 0 0 1 1 2006 "xxxx 2006-01-01T00:00:00,0 xxxx"
46             :start 5
47             :end 15)
48
49    (is (eql (day-of (parse-timestring "2006-06-06TZ")) 2288))
50
51    (compare 20000000 3 4 5 6 7 2008 "2008-07-06T05:04:03,02")
52    (compare 0 2 0 0 23 3 2000 "--23T::02" :allow-missing-elements t)
53    (compare 80000000 7 6 5 1 3 2000 "T05:06:07,08" :allow-missing-elements t)
54    (compare 940703000 28 56 16 20 2 2008 "2008-02-20T16:56:28.940703Z"
55             :offset 0)))
56
57(deftest test/parsing/split ()
58  (is (equal (local-time::%split-timestring "2006-01-02T03:04:05,6-05")
59             '(2006 1 2 3 4 5 600000000 -5 0)))
60  (is (equal (local-time::%split-timestring "2006-01-02T03:04:05,6-0515")
61             '(2006 1 2 3 4 5 600000000 -5 -15)))
62  (is (equal (local-time::%split-timestring "2006-01-02T03:04:05,6-05:15")
63             '(2006 1 2 3 4 5 600000000 -5 -15))))
64
65
66(deftest test/parsing/reader ()
67  (let ((now (now)))
68    (setf (nsec-of now) 123456000)
69    (is (timestamp= now
70                     (with-input-from-string (ins (format-timestring nil now))
71                       (local-time::%read-timestring ins #\@))))))
72
73(deftest test/parsing/read-universal-time ()
74  (let ((now (now)))
75    (setf (nsec-of now) 0)
76    (is (timestamp= now
77                     (with-input-from-string (ins (princ-to-string (timestamp-to-universal now)))
78                       (local-time::%read-universal-time ins #\@ nil))))))
79
80(deftest test/parsing/error ()
81  (signals invalid-timestring (parse-timestring "2019-w2-20")))
82
83(deftest test/parsing/parse-rfc3339 ()
84  (let ((local-time:*default-timezone* local-time:+utc-zone+))
85    (is (equal (multiple-value-list (decode-timestamp (local-time::parse-rfc3339-timestring "2006-01-02T03:04:05.6-05")))
86               '(600000000 5 4 8 2 1 2006 1 NIL 0 "UTC")))
87    ;; rfc3339 only supports . for fractional seconds
88    (signals local-time::invalid-timestring (local-time::parse-rfc3339-timestring "2006-01-02T03:04:05,6-05"))))
89