5#include "../SqlColumnTypeDefinitions.hpp"
34 return SqlDateTime { std::chrono::system_clock::now() };
37#if !defined(LIGHTWEIGHT_CXX26_REFLECTION)
47 return SqlDateTime { std::chrono::system_clock::now() };
64 constexpr std::weak_ordering operator<=>(
SqlDateTime const& other) const noexcept
71 return (*this <=> other) == std::weak_ordering::equivalent;
77 return !(*
this == other);
81 LIGHTWEIGHT_FORCE_INLINE
constexpr SqlDateTime(std::chrono::year_month_day ymd,
82 std::chrono::hh_mm_ss<duration_type> time)
noexcept:
84 .year = (SQLSMALLINT) (
int) ymd.year(),
85 .month = (SQLUSMALLINT) (
unsigned) ymd.month(),
86 .day = (SQLUSMALLINT) (
unsigned) ymd.day(),
87 .hour = (SQLUSMALLINT) time.hours().count(),
88 .minute = (SQLUSMALLINT) time.minutes().count(),
89 .second = (SQLUSMALLINT) time.seconds().count(),
91 (SQLUINTEGER) (std::chrono::duration_cast<std::chrono::nanoseconds>(time.to_duration()).count() / 100) * 100,
98 std::chrono::year
year,
99 std::chrono::month
month,
100 std::chrono::day
day,
101 std::chrono::hours
hour,
102 std::chrono::minutes
minute,
103 std::chrono::seconds
second,
104 std::chrono::nanoseconds
nanosecond = std::chrono::nanoseconds(0)) noexcept:
106 .year = (SQLSMALLINT) (
int)
year,
107 .month = (SQLUSMALLINT) (
unsigned)
month,
108 .day = (SQLUSMALLINT) (
unsigned)
day,
109 .hour = (SQLUSMALLINT)
hour.count(),
110 .minute = (SQLUSMALLINT)
minute.count(),
111 .second = (SQLUSMALLINT)
second.count(),
112 .fraction = (SQLUINTEGER) (
nanosecond.count() / 100) * 100,
118 LIGHTWEIGHT_FORCE_INLINE
constexpr SqlDateTime(std::chrono::system_clock::time_point
value)
noexcept:
126 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::year
year() const noexcept
128 return std::chrono::year(
static_cast<int>(
sqlValue.year));
132 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::month
month() const noexcept
134 return std::chrono::month(
static_cast<unsigned>(
sqlValue.month));
138 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::day
day() const noexcept
140 return std::chrono::day(
static_cast<unsigned>(
sqlValue.day));
144 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::hours
hour() const noexcept
146 return std::chrono::hours(
static_cast<unsigned>(
sqlValue.hour));
150 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::minutes
minute() const noexcept
152 return std::chrono::minutes(
static_cast<unsigned>(
sqlValue.minute));
156 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::seconds
second() const noexcept
158 return std::chrono::seconds(
static_cast<unsigned>(
sqlValue.second));
162 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::nanoseconds
nanosecond() const noexcept
164 return std::chrono::nanoseconds(
static_cast<unsigned>(
sqlValue.fraction));
170 LIGHTWEIGHT_FORCE_INLINE
constexpr operator native_type() const noexcept
176 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE
SqlDate Date() const noexcept
182 [[nodiscard]]
constexpr LIGHTWEIGHT_FORCE_INLINE
SqlTime Time() const noexcept
185 std::chrono::minutes {
minute() },
186 std::chrono::seconds {
second() },
187 std::chrono::microseconds { std::chrono::duration_cast<std::chrono::microseconds>(
nanosecond()) } };
193 using namespace std::chrono;
194 auto const totalDays = floor<days>(
value);
195 auto const ymd = year_month_day { totalDays };
197 hh_mm_ss<duration_type> { std::chrono::duration_cast<duration_type>(floor<nanoseconds>(
value - totalDays)) };
203 std::chrono::year_month_day ymd, std::chrono::hh_mm_ss<duration_type> hms)
noexcept
207 return SQL_TIMESTAMP_STRUCT {
208 .year = (SQLSMALLINT) (
int) ymd.year(),
209 .month = (SQLUSMALLINT) (
unsigned) ymd.month(),
210 .day = (SQLUSMALLINT) (
unsigned) ymd.day(),
211 .hour = (SQLUSMALLINT) hms.hours().count(),
212 .minute = (SQLUSMALLINT) hms.minutes().count(),
213 .second = (SQLUSMALLINT) hms.seconds().count(),
214 .fraction = (SQLUINTEGER) (((
static_cast<unsigned long long>(std::chrono::duration_cast<std::chrono::nanoseconds>(hms.to_duration()).count()) % 1'000'000'000LLU) / 100) * 100)
223 using namespace std::chrono;
224 auto const ymd = year_month_day { std::chrono::year { time.year } / std::chrono::month { time.month } / std::chrono::day { time.day } };
225 auto const hms = hh_mm_ss<duration_type> {
226 duration_cast<duration_type>(
228 + minutes { time.minute }
229 + seconds { time.second }
230 + nanoseconds { time.fraction }
233 return sys_days { ymd } + hms.to_duration();
264 return SqlDateTime { dateTime.value() - duration };
274struct std::formatter<Lightweight::SqlDateTime>: std::formatter<std::string>
277 -> std::format_context::iterator
283 auto const milliseconds = value.sqlValue.fraction / 1'000'000;
284 return std::formatter<std::string>::format(std::format(
"{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}",
286 value.sqlValue.month,
289 value.sqlValue.minute,
290 value.sqlValue.second,
297struct std::formatter<std::optional<Lightweight::SqlDateTime>>: std::formatter<std::string>
299 LIGHTWEIGHT_FORCE_INLINE
auto format(std::optional<Lightweight::SqlDateTime>
const& value,
300 std::format_context& ctx)
const -> std::format_context::iterator
302 if (!value.has_value())
303 return std::formatter<std::string>::format(
"nullopt", ctx);
304 return std::formatter<std::string>::format(std::format(
"{}", value.value()), ctx);
312struct SqlDataBinder<SqlDateTime::native_type>
314 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(SQLHSTMT stmt,
318 SqlDataBinderCallback
const& )
noexcept
320 SQL_TIMESTAMP_STRUCT sqlValue {};
321 auto const rc = SQLGetData(stmt, column, SQL_C_TYPE_TIMESTAMP, &sqlValue,
sizeof(sqlValue), indicator);
322 if (SQL_SUCCEEDED(rc))
329struct LIGHTWEIGHT_API SqlDataBinder<SqlDateTime>
331 static constexpr auto ColumnType = SqlColumnTypeDefinitions::DateTime {};
333 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
335 SqlDateTime
const& value,
336 [[maybe_unused]] SqlDataBinderCallback
const& cb)
noexcept
338#if defined(_WIN32) || defined(_WIN64)
341 using namespace std::string_view_literals;
342 if (cb.ServerType() == SqlServerType::MICROSOFT_SQL && cb.DriverName() ==
"SQLSRV32.DLL"sv)
346 SQLSMALLINT sqlType { SQL_TYPE_TIMESTAMP };
347 SQLULEN paramSize { 23 };
348 SQLSMALLINT decimalDigits { 3 };
349 SQLSMALLINT nullable {};
351 auto const sqlDescribeParamResult =
352 SQLDescribeParam(stmt, column, &hints.sqlType, &hints.paramSize, &hints.decimalDigits, &hints.nullable);
353 if (SQL_SUCCEEDED(sqlDescribeParamResult))
355 return SQLBindParameter(stmt,
362 (SQLPOINTER) &value.sqlValue,
369 return SQLBindParameter(stmt,
376 (SQLPOINTER) &value.sqlValue,
384 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN BatchInputParameter(SQLHSTMT stmt,
386 SqlDateTime
const* values,
388 [[maybe_unused]] SqlDataBinderCallback& cb,
389 SQLLEN* indicators =
nullptr) noexcept
391#if defined(_WIN32) || defined(_WIN64)
392 using namespace std::string_view_literals;
393 if (cb.ServerType() == SqlServerType::MICROSOFT_SQL && cb.DriverName() ==
"SQLSRV32.DLL"sv)
397 SQLSMALLINT sqlType { SQL_TYPE_TIMESTAMP };
398 SQLULEN paramSize { 23 };
399 SQLSMALLINT decimalDigits { 3 };
400 SQLSMALLINT nullable {};
402 auto const sqlDescribeParamResult =
403 SQLDescribeParam(stmt, column, &hints.sqlType, &hints.paramSize, &hints.decimalDigits, &hints.nullable);
404 if (SQL_SUCCEEDED(sqlDescribeParamResult))
406 return SQLBindParameter(stmt,
413 (SQLPOINTER) &values->sqlValue,
420 return SQLBindParameter(stmt,
427 (SQLPOINTER) &values->sqlValue,
432 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
433 SQLHSTMT stmt, SQLUSMALLINT column, SqlDateTime* result, SQLLEN* indicator, SqlDataBinderCallback& )
noexcept
436 *indicator =
sizeof(result->sqlValue);
437 return SQLBindCol(stmt, column, SQL_C_TYPE_TIMESTAMP, &result->sqlValue, 0, indicator);
440 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(SQLHSTMT stmt,
444 SqlDataBinderCallback
const& )
noexcept
446 return SQLGetData(stmt, column, SQL_C_TYPE_TIMESTAMP, &result->sqlValue,
sizeof(result->sqlValue), indicator);
449 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(SqlDateTime
const& value)
noexcept
451 return std::format(
"{}", value);
456inline constexpr bool SqlIsNativeRowBindableValue<SqlDateTime> =
true;
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::year year() const noexcept
Returns the year of this date-time object.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::day day() const noexcept
Returns the day of this date-time object.
static LIGHTWEIGHT_FORCE_INLINE SQL_TIMESTAMP_STRUCT constexpr ConvertToSqlValue(std::chrono::year_month_day ymd, std::chrono::hh_mm_ss< duration_type > hms) noexcept
Converts year_month_day and hh_mm_ss components to the underlying SQL timestamp structure.
static LIGHTWEIGHT_FORCE_INLINE SqlDateTime Now() noexcept
Returns the current date and time.
constexpr bool operator==(SqlDateTime const &other) const noexcept
Equality comparison operator.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDateTime(std::chrono::system_clock::time_point value) noexcept
Constructs a date and time from a time point.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlDate Date() const noexcept
Constructs only a date from a SQL date-time structure.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDateTime(std::chrono::year year, std::chrono::month month, std::chrono::day day, std::chrono::hours hour, std::chrono::minutes minute, std::chrono::seconds second, std::chrono::nanoseconds nanosecond=std::chrono::nanoseconds(0)) noexcept
Constructs a date and time from individual components.
std::chrono::system_clock::time_point native_type
The native C++ type representing a date-time value.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::month month() const noexcept
Returns the month of this date-time object.
SQL_TIMESTAMP_STRUCT sqlValue
Holds the underlying SQL timestamp structure.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::seconds second() const noexcept
Returns the second of this date-time object.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::hours hour() const noexcept
Returns the hour of this date-time object.
std::chrono::system_clock::duration duration_type
The duration type used for arithmetic operations.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::minutes minute() const noexcept
Returns the minute of this date-time object.
LIGHTWEIGHT_FORCE_INLINE SqlDateTime & operator-=(duration_type duration) noexcept
Subtracts a duration from this date-time.
constexpr LIGHTWEIGHT_FORCE_INLINE std::chrono::nanoseconds nanosecond() const noexcept
Returns the nanosecond of this date-time object.
constexpr SqlDateTime() noexcept=default
Default constructor.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDateTime(std::chrono::year_month_day ymd, std::chrono::hh_mm_ss< duration_type > time) noexcept
Constructs a date and time from individual components.
static LIGHTWEIGHT_FORCE_INLINE SqlDateTime NowUTC() noexcept
Return the current date and time in UTC.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlTime Time() const noexcept
Constructs only a time from a SQL date-time structure.
static LIGHTWEIGHT_FORCE_INLINE SQL_TIMESTAMP_STRUCT constexpr ConvertToSqlValue(native_type value) noexcept
Converts a native time_point to the underlying SQL timestamp structure.
LIGHTWEIGHT_FORCE_INLINE SqlDateTime & operator+=(duration_type duration) noexcept
Adds a duration to this date-time.
constexpr LIGHTWEIGHT_FORCE_INLINE native_type value() const noexcept
Returns the current date and time.
constexpr bool operator!=(SqlDateTime const &other) const noexcept
Inequality comparison operator.
static LIGHTWEIGHT_FORCE_INLINE native_type constexpr ConvertToNative(SQL_TIMESTAMP_STRUCT const &time) noexcept
Converts a SQL timestamp structure to the native time_point representation.