diff --git a/builds/win32/msvc7/common.vcproj b/builds/win32/msvc7/common.vcproj index 82385260d7..c5e0dcaa6d 100644 --- a/builds/win32/msvc7/common.vcproj +++ b/builds/win32/msvc7/common.vcproj @@ -177,6 +177,9 @@ + + @@ -211,6 +214,9 @@ + + diff --git a/builds/win32/msvc7/common_classic.vcproj b/builds/win32/msvc7/common_classic.vcproj index 8b8e504245..8a6bbcc106 100644 --- a/builds/win32/msvc7/common_classic.vcproj +++ b/builds/win32/msvc7/common_classic.vcproj @@ -177,6 +177,9 @@ + + @@ -208,6 +211,9 @@ + + diff --git a/builds/win32/msvc7/common_static.vcproj b/builds/win32/msvc7/common_static.vcproj index 4c0ded8328..4151cc98ea 100644 --- a/builds/win32/msvc7/common_static.vcproj +++ b/builds/win32/msvc7/common_static.vcproj @@ -173,6 +173,9 @@ + + @@ -207,6 +210,9 @@ + + diff --git a/configure.in b/configure.in index 87a0de3a27..860aa1ce17 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.208 2004-10-25 09:45:03 aafemt Exp $ +dnl $Id: configure.in,v 1.209 2004-11-04 19:14:08 skidder Exp $ dnl ############################# INITIALISATION ############################### @@ -457,6 +457,7 @@ AC_CHECK_FUNCS(tcgetattr strdup) AC_CHECK_FUNCS(mkstemp) AC_CHECK_FUNCS(pthread_keycreate pthread_key_create) AC_CHECK_FUNCS(llrint) +AC_CHECK_FUNCS(localtime_r) # Checks for typedefs, structures, and compiler characteristics. diff --git a/src/common/classes/timestamp.cpp b/src/common/classes/timestamp.cpp index eadcc5be72..3fd36a633d 100644 --- a/src/common/classes/timestamp.cpp +++ b/src/common/classes/timestamp.cpp @@ -3,25 +3,25 @@ * MODULE: timestamp.cpp * DESCRIPTION: Date/time handling class * - * The contents of this file are subject to the Initial - * Developer's Public License Version 1.0 (the "License"); - * you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html * - * Software distributed under the License is distributed AS IS, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the License for the specific language governing rights - * and limitations under the License. + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. * - * The Original Code was created by Dmitry Yemanov - * for the Firebird Open Source RDBMS project. + * The Original Code was created by Inprise Corporation + * and its predecessors. Portions created by Inprise Corporation are + * Copyright (C) Inprise Corporation. * - * Copyright (c) 2004 Dmitry Yemanov - * and all contributors signed below. + * All Rights Reserved. + * Contributor(s): ______________________________________. * - * All Rights Reserved. - * Contributor(s): ______________________________________. + * NS: The code now contains much of the logic from original gds.c + * this is why we need to use IPL license for it */ #include "firebird.h" @@ -29,17 +29,6 @@ #include "../jrd/dsc.h" #include "../jrd/gdsassert.h" -#if defined(TIME_WITH_SYS_TIME) -#include -#include -#else -#if defined(HAVE_SYS_TIME_H) -#include -#else -#include -#endif -#endif - #ifdef HAVE_SYS_TIMES_H #include #endif @@ -51,95 +40,205 @@ namespace Firebird { -TimeStamp::TimeStamp(bool empty) +int TimeStamp::yday(const struct tm* times) { - if (empty) - { - invalidate(); - } +/************************************** + * + * y d a y + * + ************************************** + * + * Functional description + * Convert a calendar date to the day-of-year. + * + * The unix time structure considers + * january 1 to be Year day 0, although it + * is day 1 of the month. (Note that QLI, + * when printing Year days takes the other + * view.) + * + **************************************/ + SSHORT day = times->tm_mday; + const SSHORT month = times->tm_mon; + const SSHORT year = times->tm_year + 1900; + + --day; + + day += (214 * month + 3) / 7; + + if (month < 2) + return day; + + if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) + --day; else - { - generate(); - } + day -= 2; + + return day; } -void TimeStamp::invalidate() -{ - seconds = fractions = 0; -} -void TimeStamp::validate() +void TimeStamp::decode_date(ISC_DATE nday, struct tm* times) { - if (!seconds) - { - generate(); - } -} +/************************************** + * + * d e c o d e _ d a t e + * + ************************************** + * + * Functional description + * Convert a numeric day to [day, month, year]. + * + * Calenders are divided into 4 year cycles. + * 3 Non-Leap years, and 1 leap year. + * Each cycle takes 365*4 + 1 == 1461 days. + * There is a further cycle of 100 4 year cycles. + * Every 100 years, the normally expected leap year + * is not present. Every 400 years it is. + * This cycle takes 100 * 1461 - 3 == 146097 days + * The origin of the constant 2400001 is unknown. + * The origin of the constant 1721119 is unknown. + * The difference between 2400001 and 1721119 is the + * number of days From 0/0/0000 to our base date of + * 11/xx/1858. (678882) + * The origin of the constant 153 is unknown. + * + * This whole routine has problems with ndates + * less than -678882 (Approx 2/1/0000). + * + **************************************/ + // struct tm may include arbitrary number of additional members. + // zero-initialize them. + memset(times, 0, sizeof(struct tm)); -bool TimeStamp::encode(tm* times) const -{ - fb_assert(seconds > 0); - const tm* t = localtime(&seconds); - if (!t) - { - return false; - } - *times = *t; - return true; -} + nday -= 1721119 - 2400001; + const SLONG century = (4 * nday - 1) / 146097; + nday = 4 * nday - 1 - 146097 * century; + SLONG day = nday / 4; -bool TimeStamp::encode(ISC_TIMESTAMP* ts, bool precise) const -{ - tm times; - if (!encode(×)) - { - return false; + nday = (4 * day + 3) / 1461; + day = 4 * day + 3 - 1461 * nday; + day = (day + 4) / 4; + + SLONG month = (5 * day - 3) / 153; + day = 5 * day - 3 - 153 * month; + day = (day + 5) / 5; + + SLONG year = 100 * century + nday; + + if (month < 10) + month += 3; + else { + month -= 9; + year += 1; } - const int day = times.tm_mday; - int month = times.tm_mon + 1; - int year = times.tm_year + 1900; + times->tm_mday = (int) day; + times->tm_mon = (int) month - 1; + times->tm_year = (int) year - 1900; + + times->tm_yday = yday(times); + + if ((times->tm_wday = (nday + 3) % 7) < 0) + times->tm_wday += 7; +} + + +ISC_DATE TimeStamp::encode_date(const struct tm* times) +{ +/************************************** + * + * e n c o d e _ d a t e + * + ************************************** + * + * Functional description + * Convert a calendar date to a numeric day + * (the number of days since the base date). + * + **************************************/ + const SSHORT day = times->tm_mday; + SSHORT month = times->tm_mon + 1; + SSHORT year = times->tm_year + 1900; if (month > 2) - { month -= 3; - } - else - { + else { month += 9; year -= 1; } - const int c = year / 100; - const int ya = year - 100 * c; + const SLONG c = year / 100; + const SLONG ya = year - 100 * c; - ts->timestamp_date = - (((SINT64) 146097 * c) / 4 + (1461 * ya) / 4 + - (153 * month + 2) / 5 + day + 1721119 - 2400001); + return (ISC_DATE) (((SINT64) 146097 * c) / 4 + + (1461 * ya) / 4 + + (153 * month + 2) / 5 + day + 1721119 - 2400001); +} - ts->timestamp_time = - ((times.tm_hour * 60 + times.tm_min) * 60 + - times.tm_sec) * ISC_TIME_SECONDS_PRECISION + - (precise ? fractions * 10 : 0); +// Encode timestamp from UNIX datetime structure +void TimeStamp::encode(const struct tm* times) { + mValue.timestamp_date = encode_date(times); + mValue.timestamp_time = + ((times->tm_hour * 60 + times->tm_min) * 60 + + times->tm_sec) * ISC_TIME_SECONDS_PRECISION; +} - return true; +// Decode timestamp into UNIX datetime structure +void TimeStamp::decode(struct tm* times) const { + decode_date(mValue.timestamp_date, times); + + const ULONG minutes = mValue.timestamp_time / (ISC_TIME_SECONDS_PRECISION * 60); + times->tm_hour = minutes / 60; + times->tm_min = minutes % 60; + times->tm_sec = (mValue.timestamp_time / ISC_TIME_SECONDS_PRECISION) % 60; } void TimeStamp::generate() { - // Only millisecond precision is supported currently + // NS: We round generated timestamps to whole millisecond. + // Not many applications can deal with fractional milliseconds properly and + // we do not use high resolution timers either so actual time granularity + // is going to to be somewhere in range between 1 ms (like on UNIX/Risc) + // and 53 ms (such as Win9X) + + time_t seconds; // UTC time + int fractions; // milliseconds + #ifdef HAVE_GETTIMEOFDAY struct timeval tp; GETTIMEOFDAY(&tp); seconds = tp.tv_sec; - fractions = tp.tv_usec / 1000; + millis = tp.tv_usec / 1000; #else struct timeb time_buffer; ftime(&time_buffer); seconds = time_buffer.time; fractions = time_buffer.millitm; #endif - fb_assert(seconds > 0); + + // NS: Current FB behavior of using server time zone is not appropriate for + // distributed applications. We should be storing UTC times everywhere and + // convert timestamps to client timezone as necessary. Replace localtime + // stuff with these lines as soon appropriate functionality is implemented + // + // mValue.timestamp_date = seconds / 86400 + GDS_EPOCH_START; + // mValue.timestamp_time = (seconds % 86400) * ISC_TIME_SECONDS_PRECISION; + +#ifdef HAVE_LOCALTIME_R + struct tm times; + if (!localtime_r(&seconds, ×)) + system_call_failed::raise("localtime_r"); + encode(×); +#else + struct tm *times = localtime(&seconds); + if (!times) + system_call_failed::raise("localtime"); + encode(times); +#endif + + // Add fractions of second + mValue.timestamp_time += fractions * ISC_TIME_SECONDS_PRECISION / 1000; } } // namespace diff --git a/src/common/classes/timestamp.h b/src/common/classes/timestamp.h index 18cc0494b8..9328795a57 100644 --- a/src/common/classes/timestamp.h +++ b/src/common/classes/timestamp.h @@ -27,25 +27,86 @@ #ifndef CLASSES_TIMESTAMP_H #define CLASSES_TIMESTAMP_H +// struct tm declaration +#if defined(TIME_WITH_SYS_TIME) +#include +#include +#else +#if defined(HAVE_SYS_TIME_H) +#include +#else +#include +#endif +#endif + namespace Firebird { +// Wrapper class for ISC_TIMESTAMP supposed to implement date/time conversions +// and arithmetic. Small and not platform-specific methods are implemented +// inline. Usage of this class normally should involve zero overhead. +// +// Note: default "shallow-copy" constructor and assignment operators +// are just fine for our purposes +// +// TODO: migrate fbudf to this class. class TimeStamp { public: + // Number of the first day of UNIX epoch in GDS counting + enum { GDS_EPOCH_START = 40617 }; - explicit TimeStamp(bool empty = false); + // Default constructor. Fills timestamp with current date/time + TimeStamp() { generate(); } - void invalidate(); - void validate(); + // Altername constructor, may create empty timestamp object + explicit TimeStamp(bool zero) + { + if (zero) + invalidate(); + else + generate(); + } - bool encode(tm* times) const; - bool encode(ISC_TIMESTAMP* ts, bool precise) const; + // Construct wrapper around pre-existing timestamp + TimeStamp(const ISC_TIMESTAMP& from) : mValue(from) { } + // See if timestamp contains non-zero value + bool isEmpty() const { + return mValue.timestamp_date == 0 && mValue.timestamp_time == 0; + } + + // Set value of timestamp to zero + void invalidate() { + mValue.timestamp_date = 0; + mValue.timestamp_time = 0; + } + + // Assign value of timestamp to current date/time if it is zero + void validate() { + if (isEmpty()) generate(); + } + + // Encode timestamp from UNIX datetime structure + void encode(const struct tm* times); + + // Decode timestamp into UNIX datetime structure + void decode(struct tm* times) const; + + // Write access to timestamp structure we wrap + ISC_TIMESTAMP& value() { return mValue; } + + // Read access to timestamp structure we wrap + const ISC_TIMESTAMP& value() const { return mValue; } + + // ISC date/time helper routines. Both functions are signal-safe. + static void decode_date(ISC_DATE nday, struct tm* times); + static ISC_DATE encode_date(const struct tm* times); private: + ISC_TIMESTAMP mValue; - time_t seconds; - time_t fractions; + static int yday(const struct tm* times); + // Assign value of timestamp to current date/time void generate(); }; diff --git a/src/include/gen/autoconfig_msvc.h b/src/include/gen/autoconfig_msvc.h index 7ecb20288a..3add0e4506 100644 --- a/src/include/gen/autoconfig_msvc.h +++ b/src/include/gen/autoconfig_msvc.h @@ -159,6 +159,7 @@ #define HAVE_STRDUP #undef HAVE_MKSTEMP #undef HAVE_LLRINT +#undef HAVE_LOCALTIME_R /* Types */ diff --git a/src/jrd/cvt.cpp b/src/jrd/cvt.cpp index d215f23e7b..42867dec0c 100644 --- a/src/jrd/cvt.cpp +++ b/src/jrd/cvt.cpp @@ -1377,24 +1377,17 @@ void CVT_move(const dsc* from, dsc* to, FPTR_ERROR err) Otherwise, take the CURRENT date to populate the date portion of the timestamp */ - ISC_TIMESTAMP enc_times; + SLONG cur_date; if (tdbb && (tdbb->getType() == ThreadData::tddDBB) && tdbb->tdbb_request) { - if (!tdbb->tdbb_request->req_timestamp.encode(&enc_times, false)) - { - (*err)(isc_date_range_exceeded, 0); - } + cur_date = tdbb->tdbb_request->req_timestamp.value().timestamp_date; } else { - if (!Firebird::TimeStamp().encode(&enc_times, false)) - { - (*err)(isc_date_range_exceeded, 0); - } + cur_date = Firebird::TimeStamp().value().timestamp_date; } - ((GDS_TIMESTAMP*) (to->dsc_address))->timestamp_date = - enc_times.timestamp_date; + ((GDS_TIMESTAMP*) (to->dsc_address))->timestamp_date = cur_date; } return; @@ -2498,15 +2491,10 @@ static void string_to_datetime( conversion_error(desc, err); /* fetch the current time */ + *date = Firebird::TimeStamp().value(); - if (!Firebird::TimeStamp().encode(date, true)) - { - (err)(isc_date_range_exceeded, 0); - } - - if (strcmp(temp, NOW) == 0) { + if (strcmp(temp, NOW) == 0) return; - } if (expect_type == expect_sql_time) { conversion_error(desc, err); return; @@ -2631,10 +2619,8 @@ static void string_to_datetime( times.tm_mon = components[position_month]; times.tm_mday = components[position_day]; - if (!Firebird::TimeStamp().encode(×2)) - { - (err)(isc_date_range_exceeded, 0); - } + // Fetch current date/time + Firebird::TimeStamp().decode(×2); /* Handle defaulting of year */ diff --git a/src/jrd/evl.cpp b/src/jrd/evl.cpp index 3941bc000e..a5f4b9852a 100644 --- a/src/jrd/evl.cpp +++ b/src/jrd/evl.cpp @@ -19,7 +19,7 @@ * * All Rights Reserved. * Contributor(s): ______________________________________. - * $Id: evl.cpp,v 1.119 2004-11-01 08:29:16 dimitr Exp $ + * $Id: evl.cpp,v 1.120 2004-11-04 19:14:20 skidder Exp $ */ /* @@ -943,12 +943,7 @@ dsc* EVL_expr(thread_db* tdbb, jrd_nod* node) { // Use the request timestamp - ISC_TIMESTAMP enc_times; - if (!request->req_timestamp.encode(&enc_times, - node->nod_type == nod_current_timestamp)) - { - ERR_post(isc_date_range_exceeded, 0); - } + ISC_TIMESTAMP enc_times = request->req_timestamp.value(); memset(&impure->vlu_desc, 0, sizeof(impure->vlu_desc)); impure->vlu_desc.dsc_address = diff --git a/src/jrd/gds.cpp b/src/jrd/gds.cpp index 24db69e614..35d23566fd 100644 --- a/src/jrd/gds.cpp +++ b/src/jrd/gds.cpp @@ -50,6 +50,7 @@ #include "../jrd/constants.h" #include "../common/classes/locks.h" +#include "../common/classes/timestamp.h" #ifdef HAVE_UNISTD_H #include @@ -193,6 +194,7 @@ static char ib_prefix_msg_val[MAXPATHLEN]; #include "../jrd/jrd.h" #include "../common/utils_proto.h" +using Firebird::TimeStamp; // This structure is used to parse the firebird.msg file. struct gds_msg @@ -241,10 +243,6 @@ static void blr_print_verb(gds_ctl*, SSHORT); static int blr_print_word(gds_ctl*); static void init(void); -static int yday(const tm*); - -static void ndate(SLONG, tm*); -static GDS_DATE nday(const tm*); static void sanitize(TEXT*); static void safe_concat_path(TEXT* destbuf, const TEXT* srcbuf); @@ -495,12 +493,7 @@ void API_ROUTINE isc_decode_sql_date(const GDS_DATE* date, void* times_arg) * **************************************/ tm* times = (struct tm*) times_arg; - memset(times, 0, sizeof(*times)); - - ndate(*date, times); - times->tm_yday = yday(times); - if ((times->tm_wday = (*date + 3) % 7) < 0) - times->tm_wday += 7; + TimeStamp::decode_date(*date, times); } @@ -537,23 +530,12 @@ void API_ROUTINE isc_decode_timestamp(const GDS_TIMESTAMP* date, void* times_arg * Functional description * Convert from internal timestamp format to UNIX time structure. * - * Note: the date arguement is really an ISC_TIMESTAMP -- however the - * definition of ISC_TIMESTAMP is not available from all the source - * modules that need to use isc_encode_timestamp + * Note: This routine is intended only for public API use. Engine itself and + * utilities should be using TimeStamp class directly in type-safe manner. * **************************************/ - tm* times = (struct tm*) times_arg; - memset(times, 0, sizeof(*times)); - ndate(date->timestamp_date, times); - times->tm_yday = yday(times); - if ((times->tm_wday = (date->timestamp_date + 3) % 7) < 0) - times->tm_wday += 7; - - const ULONG minutes = date->timestamp_time / (ISC_TIME_SECONDS_PRECISION * 60); - times->tm_hour = minutes / 60; - times->tm_min = minutes % 60; - times->tm_sec = (date->timestamp_time / ISC_TIME_SECONDS_PRECISION) % 60; + Firebird::TimeStamp(*date).decode(reinterpret_cast(times_arg)); } @@ -593,7 +575,9 @@ void API_ROUTINE isc_encode_date(const void* times_arg, ISC_QUAD* date) * isc_encode_timestamp * **************************************/ - isc_encode_timestamp(times_arg, (GDS_TIMESTAMP*) date); + Firebird::TimeStamp temp; + temp.encode(reinterpret_cast(times_arg)); + *date = (ISC_QUAD&)temp.value(); } @@ -610,7 +594,7 @@ void API_ROUTINE isc_encode_sql_date(const void* times_arg, GDS_DATE* date) * **************************************/ - *date = nday((const struct tm*) times_arg); + *date = TimeStamp::encode_date((const struct tm*) times_arg); } @@ -636,24 +620,20 @@ void API_ROUTINE isc_encode_timestamp(const void* times_arg, GDS_TIMESTAMP* date { /************************************** * - * i s c _ e n c o d e _ t i m e s t a m p + * i s c _ e n c o d e _ d a t e * ************************************** * * Functional description * Convert from UNIX time structure to internal timestamp format. * - * Note: the date arguement is really an ISC_TIMESTAMP -- however the - * definition of ISC_TIMESTAMP is not available from all the source - * modules that need to use isc_encode_timestamp + * Note: This routine is intended only for public API use. Engine itself and + * utilities should be using TimeStamp class directly in type-safe manner. * **************************************/ - const tm* times = (const struct tm*) times_arg; - - date->timestamp_date = nday(times); - date->timestamp_time = - ((times->tm_hour * 60 + times->tm_min) * 60 + - times->tm_sec) * ISC_TIME_SECONDS_PRECISION; + Firebird::TimeStamp temp; + temp.encode(reinterpret_cast(times_arg)); + *date = temp.value(); } @@ -1125,15 +1105,14 @@ void API_ROUTINE gds__trace(const TEXT * text) const int days = now / SECS_PER_DAY; int rem = now % SECS_PER_DAY; + tm today; + TimeStamp::decode_date(days + TimeStamp::GDS_EPOCH_START, &today); today.tm_hour = rem / SECS_PER_HOUR; rem %= SECS_PER_HOUR; today.tm_min = rem / 60; today.tm_sec = rem % 60; - ndate(days + 40617 /* Number of first day of the Epoch in GDS counting */, - &today); - char buffer[1024]; // 1K should be enough for the trace message char* p = buffer; gds__ulstr(p, today.tm_year+1900, 4, '0'); p+=4; @@ -3544,135 +3523,6 @@ static void init(void) /* V4_GLOBAL_MUTEX_UNLOCK; */ } - -static int yday(const struct tm* times) -{ -/************************************** - * - * y d a y - * - ************************************** - * - * Functional description - * Convert a calendar date to the day-of-year. - * - * The unix time structure considers - * january 1 to be Year day 0, although it - * is day 1 of the month. (Note that QLI, - * when printing Year days takes the other - * view.) - * - **************************************/ - SSHORT day = times->tm_mday; - const SSHORT month = times->tm_mon; - const SSHORT year = times->tm_year + 1900; - - --day; - - day += (214 * month + 3) / 7; - - if (month < 2) - return day; - - if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) - --day; - else - day -= 2; - - return day; -} - - -static void ndate(SLONG nday, tm* times) -{ -/************************************** - * - * n d a t e - * - ************************************** - * - * Functional description - * Convert a numeric day to [day, month, year]. - * - * Calenders are divided into 4 year cycles. - * 3 Non-Leap years, and 1 leap year. - * Each cycle takes 365*4 + 1 == 1461 days. - * There is a further cycle of 100 4 year cycles. - * Every 100 years, the normally expected leap year - * is not present. Every 400 years it is. - * This cycle takes 100 * 1461 - 3 == 146097 days - * The origin of the constant 2400001 is unknown. - * The origin of the constant 1721119 is unknown. - * The difference between 2400001 and 1721119 is the - * number of days From 0/0/0000 to our base date of - * 11/xx/1858. (678882) - * The origin of the constant 153 is unknown. - * - * This whole routine has problems with ndates - * less than -678882 (Approx 2/1/0000). - * - **************************************/ - nday -= 1721119 - 2400001; - const SLONG century = (4 * nday - 1) / 146097; - nday = 4 * nday - 1 - 146097 * century; - SLONG day = nday / 4; - - nday = (4 * day + 3) / 1461; - day = 4 * day + 3 - 1461 * nday; - day = (day + 4) / 4; - - SLONG month = (5 * day - 3) / 153; - day = 5 * day - 3 - 153 * month; - day = (day + 5) / 5; - - SLONG year = 100 * century + nday; - - if (month < 10) - month += 3; - else { - month -= 9; - year += 1; - } - - times->tm_mday = (int) day; - times->tm_mon = (int) month - 1; - times->tm_year = (int) year - 1900; -} - - -static GDS_DATE nday(const tm* times) -{ -/************************************** - * - * n d a y - * - ************************************** - * - * Functional description - * Convert a calendar date to a numeric day - * (the number of days since the base date). - * - **************************************/ - const SSHORT day = times->tm_mday; - SSHORT month = times->tm_mon + 1; - SSHORT year = times->tm_year + 1900; - - if (month > 2) - month -= 3; - else { - month += 9; - year -= 1; - } - - const SLONG c = year / 100; - const SLONG ya = year - 100 * c; - - return (GDS_DATE) (((SINT64) 146097 * c) / 4 + - (1461 * ya) / 4 + - (153 * month + 2) / 5 + day + 1721119 - 2400001); -} - - static void sanitize(TEXT* locale) { /************************************** diff --git a/src/jrd/mov.cpp b/src/jrd/mov.cpp index 5b41d48eb5..f3cec27c4e 100644 --- a/src/jrd/mov.cpp +++ b/src/jrd/mov.cpp @@ -585,8 +585,5 @@ void MOV_time_stamp(GDS_TIMESTAMP* date) * Get the current timestamp in gds format. * **************************************/ - if (!Firebird::TimeStamp().encode(date, false)) - { - ERR_post(isc_date_range_exceeded, 0); - } + *date = Firebird::TimeStamp().value(); }