Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 4 additions & 5 deletions Crypto/Certificate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include <algorithm>
#include <cstdlib>
#include <chrono>
#include "date/date.h"

namespace litecore::crypto {
using namespace std;
Expand Down Expand Up @@ -262,8 +261,8 @@ namespace litecore::crypto {
auto now = floor<seconds>(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());
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pipeline {
}
}
stage("iOS") {
agent { label 'sonoma' }
agent { label 'sequoia' }
environment {
BRANCH = "${BRANCH_NAME}"
KEYCHAIN_PWD = credentials("keychain-password")
Expand All @@ -40,7 +40,7 @@ pipeline {
}
}
stage("macOS") {
agent { label 'sonoma' }
agent { label 'sequoia' }
environment {
BRANCH = "${BRANCH_NAME}"
GH_PAT = credentials("cbl-bot-github-pat")
Expand Down
29 changes: 15 additions & 14 deletions LiteCore/Logging/LogDecoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <cstring>
#include <chrono>
#include <algorithm>
#include "date/date.h"
#include "ParseDate.hh"
#include "NumConversion.hh"

Expand Down Expand Up @@ -51,27 +50,29 @@ namespace litecore {
}

void LogIterator::writeTimestamp(Timestamp t, ostream& out, bool inUtcTime) {
date::local_time<microseconds> tp{seconds(t.secs) + microseconds(t.microsecs)};
const char* fmt = "%FT%TZ ";
if ( !inUtcTime ) {
struct tm tmpTime = FromTimestamp(duration_cast<seconds>(tp.time_since_epoch()));
if ( inUtcTime ) {
writeISO8601DateTime(t, out);
out << " ";
} else {
local_time<microseconds> tp{seconds(t.secs) + microseconds(t.microsecs)};
struct tm tmpTime = FromTimestamp(duration_cast<seconds>(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<microseconds> tp(seconds(t.secs) + microseconds(t.microsecs));
out << date::format("%FT%TZ", tp);
sys_time<microseconds> tp(seconds(t.secs) + microseconds(t.microsecs));
out << std::format("{:%FT%TZ}", tp);
}

string LogIterator::formatDate(Timestamp t) {
date::local_time<microseconds> tp(seconds(t.secs) + microseconds(t.microsecs));
struct tm tmpTime = FromTimestamp(duration_cast<seconds>(tp.time_since_epoch()));
local_time<microseconds> tp(seconds(t.secs) + microseconds(t.microsecs));
struct tm tmpTime = FromTimestamp(duration_cast<seconds>(tp.time_since_epoch()));
tp += GetLocalTZOffset(&tmpTime, true);
stringstream out;
out << date::format("%c", tp);
out << std::format("%c", tp);
return out.str();
}

Expand Down Expand Up @@ -148,8 +149,8 @@ namespace litecore {
std::optional<Timestamp> startingAt) {
if ( !startingAt || *startingAt < Timestamp{_startTime, 0} ) {
writeTimestamp({_startTime, 0}, out, true);
date::local_time<seconds> tp{seconds(_startTime)};
out << "---- Logging begins on " << date::format("%A %FT%TZ", tp) << " ----" << endl;
local_time<seconds> tp{seconds(_startTime)};
out << "---- Logging begins on " << std::format("{:%A %FT%TZ}", tp) << " ----" << endl;
}

LogIterator::decodeTo(out, levelNames, startingAt);
Expand Down
24 changes: 11 additions & 13 deletions LiteCore/Query/DateFormat.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "DateFormat.hh"
#include "ParseDate.hh"
#include "date/date.h"
#include "fleece/slice.hh"
#include <optional>
#include <slice_stream.hh>
Expand All @@ -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
Expand Down Expand Up @@ -326,31 +324,31 @@ namespace fleece {
std::ostringstream stream;

const milliseconds millis{milliseconds{timestamp} + duration_cast<milliseconds>(tzoffset)};
const auto tm = date::local_time<milliseconds>{millis};

const seconds offset_seconds{tzoffset};
const auto tm = local_time<milliseconds>{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<seconds>(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());
}
}
}
Expand Down
74 changes: 37 additions & 37 deletions LiteCore/Query/SQLiteDateTimeHelpers.hh
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
#pragma once

#include "ParseDate.hh"
#include "date/date.h"
#include <chrono>
#include <cmath>
#include <ratio>
#include <cstdint>
#include "SQLiteFleeceUtil.hh"
#include "DateFormat.hh"

namespace date {
using namespace std::chrono;

using namespace std::chrono;
using quarters = duration<int, std::ratio_multiply<std::ratio<3>, months::period>>;
using decades = duration<int, std::ratio_multiply<std::ratio<10>, years::period>>;
using centuries = duration<int, std::ratio_multiply<std::ratio<100>, years::period>>;
using millenniums = duration<int, std::ratio_multiply<std::ratio<1000>, years::period>>;

using quarters = duration<int, detail::ratio_multiply<std::ratio<3>, months::period>>;
using decades = duration<int, detail::ratio_multiply<std::ratio<10>, years::period>>;
using centuries = duration<int, detail::ratio_multiply<std::ratio<100>, years::period>>;
using millenniums = duration<int, detail::ratio_multiply<std::ratio<1000>, 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;
Expand Down Expand Up @@ -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<date::days>(t);
const auto ymd = date::year_month_day{daypoint};
const auto daypoint = floor<days>(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();
}

Expand Down Expand Up @@ -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:
{
Expand Down Expand Up @@ -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<int64_t>(left.s) - static_cast<int64_t>(right.s),
static_cast<int64_t>((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<int64_t>(left.s) - static_cast<int64_t>(right.s),
static_cast<int64_t>((frac(left.s) - frac(right.s)) * 1000)};

auto result = diffPart(left, right, diff, date_component);
result *= sign;
Expand All @@ -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<int64_t>(start.s * 1000));

Expand All @@ -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
41 changes: 21 additions & 20 deletions LiteCore/tests/QueryTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include <chrono>
#include <limits>
#include <numeric>
#include "date/date.h"
#include "ParseDate.hh"
#include "SecureDigest.hh"
#include <functional>
Expand Down Expand Up @@ -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();
Expand Down
Loading
Loading