diff --git a/CMakeLists.txt b/CMakeLists.txt index fb3b06992a..44da21939f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ Platform logic is largely separated into the cmake/platform_*.cmake files. Plat cmake_minimum_required (VERSION 3.21...4.0) # Mac/apple setup -- must appear before the first "project()" line" -set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0") +set(CMAKE_OSX_DEPLOYMENT_TARGET "13.4") if(NOT DEFINED CMAKE_OSX_SYSROOT) # Tells Mac builds to use the current SDK's headers & libs, not what's in the OS. set(CMAKE_OSX_SYSROOT macosx) diff --git a/Crypto/Certificate.cc b/Crypto/Certificate.cc index 41f454626c..90741762ea 100644 --- a/Crypto/Certificate.cc +++ b/Crypto/Certificate.cc @@ -37,7 +37,6 @@ #include #include #include -#include "date/date.h" namespace litecore::crypto { using namespace std; @@ -262,8 +261,8 @@ namespace litecore::crypto { auto now = floor(system_clock::now()) - 60s; auto exp = now + seconds(issuerParams.validity_secs); stringstream notBefore, notAfter; - notBefore << date::format("%Y%m%d%H%M%S", now); - notAfter << date::format("%Y%m%d%H%M%S", exp); + notBefore << std::format("{:%Y%m%d%H%M%S}", now); + notAfter << std::format("{:%Y%m%d%H%M%S}", exp); // Set certificate attributes: mbedtls_x509write_crt_set_subject_key(&crt, subjectKey->context()); @@ -345,8 +344,8 @@ namespace litecore::crypto { } static time_t x509_to_time_t(const mbedtls_x509_time& xtime) { - date::sys_days date = date::year{xtime.year} / xtime.mon / xtime.day; - date::sys_seconds datetime = date + (hours(xtime.hour) + minutes(xtime.min) + seconds(xtime.sec)); + sys_days date = year{xtime.year} / xtime.mon / xtime.day; + sys_seconds datetime = date + (hours(xtime.hour) + minutes(xtime.min) + seconds(xtime.sec)); // The limit of 32-bit time_t is approaching... auto result = datetime.time_since_epoch().count(); diff --git a/Jenkinsfile b/Jenkinsfile index 2d15aa8d59..2ae547691a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -16,7 +16,7 @@ pipeline { } } stage("iOS") { - agent { label 'sonoma' } + agent { label 'sequoia' } environment { BRANCH = "${BRANCH_NAME}" KEYCHAIN_PWD = credentials("keychain-password") @@ -40,7 +40,7 @@ pipeline { } } stage("macOS") { - agent { label 'sonoma' } + agent { label 'sequoia' } environment { BRANCH = "${BRANCH_NAME}" GH_PAT = credentials("cbl-bot-github-pat") diff --git a/LiteCore/Logging/LogDecoder.cc b/LiteCore/Logging/LogDecoder.cc index e89e7ae317..44bd6b2f7e 100644 --- a/LiteCore/Logging/LogDecoder.cc +++ b/LiteCore/Logging/LogDecoder.cc @@ -18,7 +18,6 @@ #include #include #include -#include "date/date.h" #include "ParseDate.hh" #include "NumConversion.hh" @@ -51,27 +50,29 @@ namespace litecore { } void LogIterator::writeTimestamp(Timestamp t, ostream& out, bool inUtcTime) { - date::local_time tp{seconds(t.secs) + microseconds(t.microsecs)}; - const char* fmt = "%FT%TZ "; - if ( !inUtcTime ) { - struct tm tmpTime = FromTimestamp(duration_cast(tp.time_since_epoch())); + if ( inUtcTime ) { + writeISO8601DateTime(t, out); + out << " "; + } else { + local_time tp{seconds(t.secs) + microseconds(t.microsecs)}; + struct tm tmpTime = FromTimestamp(duration_cast(tp.time_since_epoch())); + // Updates tp to the local time. tp += GetLocalTZOffset(&tmpTime, true); - fmt = "%FT%T "; + out << std::format("{:%FT%T }", tp); } - out << date::format(fmt, tp); } void LogIterator::writeISO8601DateTime(Timestamp t, std::ostream& out) { - date::sys_time tp(seconds(t.secs) + microseconds(t.microsecs)); - out << date::format("%FT%TZ", tp); + sys_time tp(seconds(t.secs) + microseconds(t.microsecs)); + out << std::format("{:%FT%TZ}", tp); } string LogIterator::formatDate(Timestamp t) { - date::local_time tp(seconds(t.secs) + microseconds(t.microsecs)); - struct tm tmpTime = FromTimestamp(duration_cast(tp.time_since_epoch())); + local_time tp(seconds(t.secs) + microseconds(t.microsecs)); + struct tm tmpTime = FromTimestamp(duration_cast(tp.time_since_epoch())); tp += GetLocalTZOffset(&tmpTime, true); stringstream out; - out << date::format("%c", tp); + out << std::format("%c", tp); return out.str(); } @@ -148,8 +149,8 @@ namespace litecore { std::optional startingAt) { if ( !startingAt || *startingAt < Timestamp{_startTime, 0} ) { writeTimestamp({_startTime, 0}, out, true); - date::local_time tp{seconds(_startTime)}; - out << "---- Logging begins on " << date::format("%A %FT%TZ", tp) << " ----" << endl; + local_time tp{seconds(_startTime)}; + out << "---- Logging begins on " << std::format("{:%A %FT%TZ}", tp) << " ----" << endl; } LogIterator::decodeTo(out, levelNames, startingAt); diff --git a/LiteCore/Query/DateFormat.cc b/LiteCore/Query/DateFormat.cc index 911bd8e52e..836930e651 100644 --- a/LiteCore/Query/DateFormat.cc +++ b/LiteCore/Query/DateFormat.cc @@ -1,6 +1,5 @@ #include "DateFormat.hh" #include "ParseDate.hh" -#include "date/date.h" #include "fleece/slice.hh" #include #include @@ -19,8 +18,7 @@ namespace fleece { const DateFormat DateFormat::kISO8601 = DateFormat{YMD::kISO8601, Separator::T, HMS::kISO8601, {Timezone::NoColon}}; - /** This parses a subset of the formatting tokens from "date.h", found - * here: https://howardhinnant.github.io/date/date.html#to_stream_formatting. + /** This parses a subset of the formatting tokens of std::format * The valid tokens are: * %Y: Year (YYYY), %m: Month (MM), %d: Day (DD). * %F == %Y-%m-%d @@ -326,31 +324,31 @@ namespace fleece { std::ostringstream stream; const milliseconds millis{milliseconds{timestamp} + duration_cast(tzoffset)}; - const auto tm = date::local_time{millis}; - - const seconds offset_seconds{tzoffset}; + const auto tm = local_time{millis}; const DateFormat f = fmt.has_value() ? fmt.value() : kISO8601; - if ( f.ymd.has_value() ) { stream << date::format("%F", tm); } + if ( f.ymd.has_value() ) { stream << std::format("{:%F}", tm); } if ( f.hms.has_value() ) { if ( f.ymd.has_value() ) { stream << (char)f.separator.value(); } if ( f.hms.value().millis && timestamp % 1000 ) { - stream << date::format("%T", tm); + stream << std::format("{:%T}", tm); } else { const auto secs = duration_cast(millis); - stream << date::format("%T", date::local_seconds(secs)); + stream << std::format("{:%T}", local_seconds(secs)); } if ( f.tz.has_value() ) { - if ( offset_seconds.count() == 0 ) { + if ( tzoffset.count() == 0 ) { stream << 'Z'; } else { - if ( f.tz.value() == Timezone::Colon ) to_stream(stream, "%Ez", tm, nullptr, &offset_seconds); - else - to_stream(stream, "%z", tm, nullptr, &offset_seconds); + char sign = tzoffset.count() < 0 ? '-' : '+'; + hh_mm_ss hms{sign == '-' ? -tzoffset : tzoffset}; + stream << std::format("{}{:02}", sign, hms.hours().count()); + if ( f.tz.value() == Timezone::Colon ) stream << ":"; + stream << std::format("{:02}", hms.minutes().count()); } } } diff --git a/LiteCore/Query/SQLiteDateTimeHelpers.hh b/LiteCore/Query/SQLiteDateTimeHelpers.hh index 18198297e9..5631014e50 100644 --- a/LiteCore/Query/SQLiteDateTimeHelpers.hh +++ b/LiteCore/Query/SQLiteDateTimeHelpers.hh @@ -1,7 +1,6 @@ #pragma once #include "ParseDate.hh" -#include "date/date.h" #include #include #include @@ -9,25 +8,27 @@ #include "SQLiteFleeceUtil.hh" #include "DateFormat.hh" -namespace date { +using namespace std::chrono; - using namespace std::chrono; +using quarters = duration, months::period>>; +using decades = duration, years::period>>; +using centuries = duration, years::period>>; +using millenniums = duration, years::period>>; - using quarters = duration, months::period>>; - using decades = duration, years::period>>; - using centuries = duration, years::period>>; - using millenniums = duration, years::period>>; +typedef struct { + int64_t year; + int64_t doy; + int64_t hour; + int64_t minute; + int64_t second; + int64_t millisecond; +} DateDiff; - typedef struct { - int64_t year; - int64_t doy; - int64_t hour; - int64_t minute; - int64_t second; - int64_t millisecond; - } DateDiff; +constexpr year_month_day& operator+=(year_month_day& ymd, decades d) noexcept { return ymd += years(d); } -} // namespace date +constexpr year_month_day& operator+=(year_month_day& ymd, centuries c) noexcept { return ymd += years(c); } + +constexpr year_month_day& operator+=(year_month_day& ymd, millenniums m) noexcept { return ymd += years(m); } namespace litecore { using namespace fleece; @@ -64,10 +65,10 @@ namespace litecore { // The Day Of Year for the given time_point. This is the number of days since the start of the year. inline int64_t doy(const date_time_point& t) { - const auto daypoint = floor(t); - const auto ymd = date::year_month_day{daypoint}; + const auto daypoint = floor(t); + const auto ymd = year_month_day{daypoint}; const auto year = ymd.year(); - const auto year_day = daypoint - date::sys_days{year / date::January / 0}; + const auto year_day = daypoint - sys_days{year / std::chrono::January / 0}; return year_day.count(); } @@ -110,8 +111,7 @@ namespace litecore { setResultTextFromSlice(ctx, DateFormat::format(buf, millis, asUTC, format)); } - inline int64_t diffPart(const DateTime& t1, const DateTime& t2, const date::DateDiff& diff, - const DateComponent part) { + inline int64_t diffPart(const DateTime& t1, const DateTime& t2, const DateDiff& diff, const DateComponent part) { switch ( part ) { case kDateComponentMillisecond: { @@ -184,12 +184,12 @@ namespace litecore { sign = -1; } - const date::DateDiff diff{left.Y - right.Y, - doy(tp_left) - doy(tp_right), - left.h - right.h, - left.m - right.m, - static_cast(left.s) - static_cast(right.s), - static_cast((frac(left.s) - frac(right.s)) * 1000)}; + const DateDiff diff{left.Y - right.Y, + doy(tp_left) - doy(tp_right), + left.h - right.h, + left.m - right.m, + static_cast(left.s) - static_cast(right.s), + static_cast((frac(left.s) - frac(right.s)) * 1000)}; auto result = diffPart(left, right, diff, date_component); result *= sign; @@ -201,7 +201,7 @@ namespace litecore { DateComponent date_component; if ( !part || (date_component = ParseDateComponent(part)) == kDateComponentInvalid ) { return -1; } - date::year_month_day ymd = date::year(start.Y) / start.M / start.D; + year_month_day ymd = year(start.Y) / start.M / start.D; std::chrono::milliseconds tod = std::chrono::hours(start.h) + std::chrono::minutes(start.m - start.tz) + std::chrono::milliseconds(static_cast(start.s * 1000)); @@ -219,34 +219,34 @@ namespace litecore { tod += std::chrono::hours(amount); break; case kDateComponentDay: - tod += date::days(amount); + tod += days(amount); break; case kDateComponentWeek: - tod += date::weeks(amount); + tod += weeks(amount); break; case kDateComponentMonth: - ymd += date::months(amount); + ymd += months(amount); break; case kDateComponentQuarter: - ymd += date::quarters(amount); + ymd += quarters(amount); break; case kDateComponentYear: - ymd += date::years(amount); + ymd += years(amount); break; case kDateComponentDecade: - ymd += date::decades(amount); + ymd += decades(amount); break; case kDateComponentCentury: - ymd += date::centuries(amount); + ymd += centuries(amount); break; case kDateComponentMillennium: - ymd += date::millenniums(amount); + ymd += millenniums(amount); break; case kDateComponentInvalid: return -1; } - return (date::sys_days(ymd) + tod).time_since_epoch().count(); + return (sys_days(ymd) + tod).time_since_epoch().count(); } } // namespace litecore diff --git a/LiteCore/tests/QueryTest.cc b/LiteCore/tests/QueryTest.cc index f69b2c26d9..c8788f60e2 100644 --- a/LiteCore/tests/QueryTest.cc +++ b/LiteCore/tests/QueryTest.cc @@ -21,7 +21,6 @@ #include #include #include -#include "date/date.h" #include "ParseDate.hh" #include "SecureDigest.hh" #include @@ -1818,40 +1817,42 @@ N_WAY_TEST_CASE_METHOD(QueryTest, "Query Distance Metrics", "[Query]") { N_WAY_TEST_CASE_METHOD(QueryTest, "Query Date Functions", "[Query][CBL-59]") { - constexpr date::local_seconds localtime = date::local_days{date::year(2018) / 10 / 23}; - tm tmpTime = FromTimestamp(localtime.time_since_epoch()); - const seconds offset_seconds = GetLocalTZOffset(&tmpTime, false); - date::local_seconds utc_time = localtime - offset_seconds; + constexpr local_seconds localtime = local_days{year(2018) / 10 / 23}; + tm tmpTime = FromTimestamp(localtime.time_since_epoch()); + const seconds offset_seconds = GetLocalTZOffset(&tmpTime, false); + local_seconds utc_time = localtime - offset_seconds; // MILLIS_TO_STR() result should be in localtime. - stringstream mil_to_str; - constexpr date::local_seconds mil_to_str_time = localtime + 18h + 33min + 1s; - mil_to_str << date::format("%FT%T", mil_to_str_time + offset_seconds); + stringstream mil_to_str; + constexpr local_seconds mil_to_str_time = localtime + 18h + 33min + 1s; + mil_to_str << std::format("{:%FT%T}", mil_to_str_time + offset_seconds); if ( offset_seconds.count() == 0 ) { mil_to_str << "Z"; } else { - to_stream(mil_to_str, "%z", mil_to_str_time, nullptr, &offset_seconds); + char sign = offset_seconds.count() < 0 ? '-' : '+'; + hh_mm_ss hms{sign == '-' ? -offset_seconds : offset_seconds}; + mil_to_str << std::format("{}{:02}{:02}", sign, hms.hours().count(), hms.minutes().count()); } const auto mil_to_str_expected = mil_to_str.str(); // These are all for STR_TO_UTC stringstream s1, s2, s3, s5; stringstream s1iso, s2iso, s3iso; - s1 << date::format("%F", utc_time); - s1iso << date::format("%FT%TZ", utc_time); + s1 << std::format("{:%F}", utc_time); + s1iso << std::format("{:%FT%TZ}", utc_time); utc_time += 18h + 33min; - s2 << date::format("%FT%TZ", utc_time); - s2iso << date::format("%FT%TZ", utc_time); + s2 << std::format("{:%FT%TZ}", utc_time); + s2iso << std::format("{:%FT%TZ}", utc_time); utc_time += 1s; - s3 << date::format("%FT%T", utc_time); - s3iso << date::format("%FT%TZ", utc_time); - s5 << date::format("%FT%TZ", utc_time); + s3 << std::format("{:%FT%T}", utc_time); + s3iso << std::format("{:%FT%TZ}", utc_time); + s5 << std::format("{:%FT%TZ}", utc_time); - constexpr date::local_seconds localtime2 = date::local_days{date::year(1944) / 6 / 6} + 6h + 30min; - tmpTime = FromTimestamp(localtime2.time_since_epoch()); - utc_time = localtime2 - GetLocalTZOffset(&tmpTime, false); + constexpr local_seconds localtime2 = local_days{year(1944) / 6 / 6} + 6h + 30min; + tmpTime = FromTimestamp(localtime2.time_since_epoch()); + utc_time = localtime2 - GetLocalTZOffset(&tmpTime, false); stringstream s4; - s4 << date::format("%FT%TZ", utc_time); + s4 << std::format("{:%FT%TZ}", utc_time); auto expected1 = s1.str(); auto expected2 = s2.str(); diff --git a/Xcode/xcconfigs/Project.xcconfig b/Xcode/xcconfigs/Project.xcconfig index 50ed12de8b..7d8eb15beb 100644 --- a/Xcode/xcconfigs/Project.xcconfig +++ b/Xcode/xcconfigs/Project.xcconfig @@ -24,8 +24,8 @@ CLANG_STATIC_ANALYZER_MODE = shallow LITECORE_VERSION_STRING = 0.0.0 LITECORE_BUILD_NUMBER = 0 -IPHONEOS_DEPLOYMENT_TARGET = 15.0 -MACOSX_DEPLOYMENT_TARGET = 13.0 +IPHONEOS_DEPLOYMENT_TARGET = 16.5 +MACOSX_DEPLOYMENT_TARGET = 13.3 TVOS_DEPLOYMENT_TARGET = 12.0 ONLY_ACTIVE_ARCH = YES SKIP_INSTALL = YES diff --git a/vendor/fleece b/vendor/fleece index 37ce2cc6f5..af7c4b47fd 160000 --- a/vendor/fleece +++ b/vendor/fleece @@ -1 +1 @@ -Subproject commit 37ce2cc6f57bdfcca9f7e42b13a556a8150347cd +Subproject commit af7c4b47fdda257dfb9dc16a034ad18ca3e7f08a