1#include "catch.hpp"
2#include "duckdb/common/types/date.hpp"
3#include "duckdb/common/types/time.hpp"
4
5#include <vector>
6
7using namespace duckdb;
8using namespace std;
9
10TEST_CASE("Date parsing works", "[date]") {
11 REQUIRE(Date::ToString(Date::FromString("1992-01-01")) == "1992-01-01");
12 REQUIRE(Date::ToString(Date::FromString(Date::Format(1992, 1, 1))) == Date::Format(1992, 1, 1));
13 REQUIRE(Date::ToString(Date::FromString(Date::Format(1992, 10, 10))) == Date::Format(1992, 10, 10));
14 REQUIRE(Date::ToString(Date::FromString(Date::Format(1992, 9, 20))) == Date::Format(1992, 9, 20));
15 REQUIRE(Date::ToString(Date::FromString(Date::Format(1992, 12, 31))) == Date::Format(1992, 12, 31));
16
17 REQUIRE(Date::FromString("1992-09-20") == Date::FromDate(1992, 9, 20));
18 REQUIRE(Date::ToString(Date::FromString("1992-09-20")) == "1992-09-20");
19 REQUIRE(Date::Format(1992, 9, 20) == "1992-09-20");
20
21 REQUIRE(Date::IsLeapYear(1992));
22 REQUIRE(Date::IsLeapYear(1996));
23 REQUIRE(Date::IsLeapYear(2000));
24 REQUIRE(!Date::IsLeapYear(3));
25 REQUIRE(!Date::IsLeapYear(2100));
26 REQUIRE(!Date::IsLeapYear(1993));
27
28 REQUIRE(Date::Format(30, 1, 1) == "0030-01-01");
29 REQUIRE(Date::Format(30000, 1, 1) == "30000-01-01");
30 REQUIRE(Date::Format(-1000, 1, 1) == "1000-01-01 (BC)");
31
32 REQUIRE(!Date::IsValidDay(1, 2, 29));
33
34 for (int year = 50; year < 4000; year += 50) {
35 for (int month = 1; month <= 12; month++) {
36 for (int day = 1; day <= 31; day++) {
37 if (Date::IsValidDay(year, month, day)) {
38 REQUIRE(Date::ToString(Date::FromString(Date::Format(year, month, day))) ==
39 Date::Format(year, month, day));
40 }
41 }
42 }
43 }
44 // we accept a few different separators
45 REQUIRE(Date::FromString("1992/09/20") == Date::FromDate(1992, 9, 20));
46 REQUIRE(Date::FromString("1992 09 20") == Date::FromDate(1992, 9, 20));
47 REQUIRE(Date::FromString("1992\\09\\20") == Date::FromDate(1992, 9, 20));
48
49 // invalid formats
50 REQUIRE_THROWS(Date::FromString("100000"));
51 REQUIRE_THROWS(Date::FromString("1992-10/10"));
52 REQUIRE_THROWS(Date::FromString("1992a10a10"));
53 REQUIRE_THROWS(Date::FromString("1992/10-10"));
54 REQUIRE_THROWS(Date::FromString("hello"));
55 REQUIRE_THROWS(Date::FromString("aa-10-10"));
56 REQUIRE_THROWS(Date::FromString("1992-aa-10"));
57 REQUIRE_THROWS(Date::FromString("1992-10-aa"));
58 REQUIRE_THROWS(Date::FromString(""));
59 REQUIRE_THROWS(Date::FromString("-"));
60 REQUIRE_THROWS(Date::FromString("-/10/10"));
61 REQUIRE_THROWS(Date::FromString("-a"));
62 REQUIRE_THROWS(Date::FromString("1992-"));
63 REQUIRE_THROWS(Date::FromString("1992-10"));
64 REQUIRE_THROWS(Date::FromString("1992-10-"));
65 // date out of range
66 REQUIRE_THROWS(Date::FromString("10000000000-01-01"));
67 REQUIRE_THROWS(Date::FromString("-10000000000-01-01"));
68 REQUIRE_THROWS(Date::FromString("1992-30-30"));
69 REQUIRE_THROWS(Date::FromString("1992-10-50"));
70 REQUIRE_THROWS(Date::FromString("1992-10-100"));
71}
72
73TEST_CASE("Time parsing works", "[date]") {
74 REQUIRE(Time::ToString(Time::FromString("14:42:04")) == "14:42:04");
75
76 for (int hour = 0; hour < 24; hour++) {
77 for (int minute = 0; minute < 60; minute++) {
78 for (int second = 0; second < 60; second++) {
79 if (Time::IsValidTime(hour, minute, second)) {
80 REQUIRE(Time::ToString(Time::FromString(Time::Format(hour, minute, second))) ==
81 Time::Format(hour, minute, second));
82 }
83 }
84 }
85 }
86
87 int hour = 14;
88 int min = 42;
89 int sec = 11;
90
91 for (int ms = 0; ms < 1000; ms++) {
92 REQUIRE(Time::ToString(Time::FromString(Time::Format(hour, min, sec, ms))) == Time::Format(hour, min, sec, ms));
93 }
94
95 // some corner cases without trailing 0
96 REQUIRE(Time::ToString(Time::FromString("14:42:04.0")) == "14:42:04");
97 REQUIRE(Time::ToString(Time::FromString("14:42:04.00")) == "14:42:04");
98 REQUIRE(Time::ToString(Time::FromString("14:42:04.0000")) == "14:42:04"); // questionable
99
100 REQUIRE(Time::ToString(Time::FromString("14:42:04.200")) == "14:42:04.200");
101 REQUIRE(Time::ToString(Time::FromString("14:42:04.030")) == "14:42:04.030");
102}
103