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();
}