mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 02:03:04 +01:00
Fixed DATEDIFF.
This commit is contained in:
parent
141f62611b
commit
3b5aa40b43
@ -292,6 +292,20 @@ ISC_TIMESTAMP TimeZoneUtil::timeStampTzToTimeStamp(const ISC_TIMESTAMP_TZ& timeS
|
||||
return TimeStamp::encode_timestamp(×, fractions);
|
||||
}
|
||||
|
||||
// Converts a time from local to UTC.
|
||||
void TimeZoneUtil::localTimeToUtc(ISC_TIME& time, Callbacks* cb)
|
||||
{
|
||||
//// TODO:
|
||||
ISC_TIMESTAMP_TZ tempTimeStampTz;
|
||||
tempTimeStampTz.timestamp_date = TimeStamp::getCurrentTimeStamp().value().timestamp_date;
|
||||
tempTimeStampTz.timestamp_time = time;
|
||||
tempTimeStampTz.timestamp_zone = cb->getSessionTimeZone();
|
||||
|
||||
localTimeStampToUtc(tempTimeStampTz);
|
||||
|
||||
time = tempTimeStampTz.timestamp_time;
|
||||
}
|
||||
|
||||
// Converts a time from local to UTC.
|
||||
void TimeZoneUtil::localTimeToUtc(ISC_TIME_TZ& timeTz)
|
||||
{
|
||||
@ -306,6 +320,20 @@ void TimeZoneUtil::localTimeToUtc(ISC_TIME_TZ& timeTz)
|
||||
timeTz.time_time = tempTimeStampTz.timestamp_time;
|
||||
}
|
||||
|
||||
// Converts a timestamp from its local datetime fields to UTC.
|
||||
void TimeZoneUtil::localTimeStampToUtc(ISC_TIMESTAMP& timeStamp, Callbacks* cb)
|
||||
{
|
||||
ISC_TIMESTAMP_TZ tempTimeStampTz;
|
||||
tempTimeStampTz.timestamp_date = timeStamp.timestamp_date;
|
||||
tempTimeStampTz.timestamp_time = timeStamp.timestamp_time;
|
||||
tempTimeStampTz.timestamp_zone = cb->getSessionTimeZone();
|
||||
|
||||
localTimeStampToUtc(tempTimeStampTz);
|
||||
|
||||
timeStamp.timestamp_date = tempTimeStampTz.timestamp_date;
|
||||
timeStamp.timestamp_time = tempTimeStampTz.timestamp_time;
|
||||
}
|
||||
|
||||
// Converts a timestamp from its local datetime fields to UTC.
|
||||
void TimeZoneUtil::localTimeStampToUtc(ISC_TIMESTAMP_TZ& timeStampTz)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define COMMON_TIME_ZONE_UTIL_H
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/cvt.h"
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
@ -53,7 +54,10 @@ public:
|
||||
static ISC_TIME timeTzToTime(const ISC_TIME_TZ& timeTz, USHORT toTimeZone);
|
||||
static ISC_TIMESTAMP timeStampTzToTimeStamp(const ISC_TIMESTAMP_TZ& timeStampTz, USHORT toTimeZone);
|
||||
|
||||
static void localTimeToUtc(ISC_TIME& time, Callbacks* cb);
|
||||
static void localTimeToUtc(ISC_TIME_TZ& timeTz);
|
||||
|
||||
static void localTimeStampToUtc(ISC_TIMESTAMP& timeStamp, Callbacks* cb);
|
||||
static void localTimeStampToUtc(ISC_TIMESTAMP_TZ& timeStampTz);
|
||||
|
||||
static void decodeTime(const ISC_TIME_TZ& timeTz, struct tm* times, int* fractions = NULL);
|
||||
|
@ -538,8 +538,8 @@ void setParamsDateDiff(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc
|
||||
{
|
||||
if (args[1]->isUnknown() && args[2]->isUnknown())
|
||||
{
|
||||
args[1]->makeTimestamp();
|
||||
args[2]->makeTimestamp();
|
||||
args[1]->makeTimestamp(); //// TODO:
|
||||
args[2]->makeTimestamp(); //// TODO:
|
||||
}
|
||||
else if (args[1]->isUnknown())
|
||||
*args[1] = *args[2];
|
||||
@ -2128,7 +2128,6 @@ dsc* evlDateAdd(thread_db* tdbb, const SysFunction* function, const NestValueArr
|
||||
}
|
||||
|
||||
|
||||
//// FIXME:
|
||||
dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueArray& args,
|
||||
impure_value* impure)
|
||||
{
|
||||
@ -2153,17 +2152,25 @@ dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueAr
|
||||
switch (value1Dsc->dsc_dtype)
|
||||
{
|
||||
case dtype_sql_time:
|
||||
timestamp1.value().timestamp_time = *(GDS_TIME *) value1Dsc->dsc_address;
|
||||
case dtype_sql_time_tz:
|
||||
timestamp1.value().timestamp_time = *(GDS_TIME*) value1Dsc->dsc_address;
|
||||
timestamp1.value().timestamp_date = 0;
|
||||
|
||||
if (value1Dsc->dsc_dtype == dtype_sql_time && value2Dsc->isDateTimeTz())
|
||||
TimeZoneUtil::localTimeToUtc(timestamp1.value().timestamp_time, &EngineCallbacks::instance);
|
||||
break;
|
||||
|
||||
case dtype_sql_date:
|
||||
timestamp1.value().timestamp_date = *(GDS_DATE *) value1Dsc->dsc_address;
|
||||
timestamp1.value().timestamp_date = *(GDS_DATE*) value1Dsc->dsc_address;
|
||||
timestamp1.value().timestamp_time = 0;
|
||||
break;
|
||||
|
||||
case dtype_timestamp:
|
||||
timestamp1.value() = *(GDS_TIMESTAMP *) value1Dsc->dsc_address;
|
||||
case dtype_timestamp_tz:
|
||||
timestamp1.value() = *(GDS_TIMESTAMP*) value1Dsc->dsc_address;
|
||||
|
||||
if (value1Dsc->dsc_dtype == dtype_timestamp && value2Dsc->isDateTimeTz())
|
||||
TimeZoneUtil::localTimeStampToUtc(timestamp1.value(), &EngineCallbacks::instance);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2178,17 +2185,25 @@ dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueAr
|
||||
switch (value2Dsc->dsc_dtype)
|
||||
{
|
||||
case dtype_sql_time:
|
||||
timestamp2.value().timestamp_time = *(GDS_TIME *) value2Dsc->dsc_address;
|
||||
case dtype_sql_time_tz:
|
||||
timestamp2.value().timestamp_time = *(GDS_TIME*) value2Dsc->dsc_address;
|
||||
timestamp2.value().timestamp_date = 0;
|
||||
|
||||
if (value2Dsc->dsc_dtype == dtype_sql_time && value1Dsc->isDateTimeTz())
|
||||
TimeZoneUtil::localTimeToUtc(timestamp2.value().timestamp_time, &EngineCallbacks::instance);
|
||||
break;
|
||||
|
||||
case dtype_sql_date:
|
||||
timestamp2.value().timestamp_date = *(GDS_DATE *) value2Dsc->dsc_address;
|
||||
timestamp2.value().timestamp_date = *(GDS_DATE*) value2Dsc->dsc_address;
|
||||
timestamp2.value().timestamp_time = 0;
|
||||
break;
|
||||
|
||||
case dtype_timestamp:
|
||||
timestamp2.value() = *(GDS_TIMESTAMP *) value2Dsc->dsc_address;
|
||||
case dtype_timestamp_tz:
|
||||
timestamp2.value() = *(GDS_TIMESTAMP*) value2Dsc->dsc_address;
|
||||
|
||||
if (value2Dsc->dsc_dtype == dtype_timestamp && value1Dsc->isDateTimeTz())
|
||||
TimeZoneUtil::localTimeStampToUtc(timestamp2.value(), &EngineCallbacks::instance);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2229,7 +2244,7 @@ dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueAr
|
||||
case blr_extract_month:
|
||||
case blr_extract_day:
|
||||
case blr_extract_week:
|
||||
if (value1Dsc->dsc_dtype == dtype_sql_time || value2Dsc->dsc_dtype == dtype_sql_time)
|
||||
if (value1Dsc->isTime() || value2Dsc->isTime())
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_sysf_invalid_timediff) <<
|
||||
@ -2242,22 +2257,17 @@ dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueAr
|
||||
case blr_extract_second:
|
||||
case blr_extract_millisecond:
|
||||
{
|
||||
//if (value1Dsc->dsc_dtype == dtype_sql_date || value2Dsc->dsc_dtype == dtype_sql_date)
|
||||
// status_exception::raise(Arg::Gds(isc_expression_eval_err));
|
||||
|
||||
// ASF: also throw error if one value is TIMESTAMP and the other is TIME
|
||||
// CVC: Or if one value is DATE and the other is TIME.
|
||||
const int type1 = value1Dsc->dsc_dtype;
|
||||
const int type2 = value2Dsc->dsc_dtype;
|
||||
if ((type1 == dtype_timestamp && type2 == dtype_sql_time) ||
|
||||
(type1 == dtype_sql_time && type2 == dtype_timestamp))
|
||||
if ((value1Dsc->isTimeStamp() && value2Dsc->isTime()) ||
|
||||
(value1Dsc->isTime() && value2Dsc->isTimeStamp()))
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_sysf_invalid_tstamptimediff) <<
|
||||
Arg::Str(function->name));
|
||||
}
|
||||
if ((type1 == dtype_sql_date && type2 == dtype_sql_time) ||
|
||||
(type1 == dtype_sql_time && type2 == dtype_sql_date))
|
||||
if ((value1Dsc->dsc_dtype == dtype_sql_date && value2Dsc->isTime()) ||
|
||||
(value1Dsc->isTime() && value2Dsc->dsc_dtype == dtype_sql_date))
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_sysf_invalid_datetimediff) <<
|
||||
|
Loading…
Reference in New Issue
Block a user