/// @brief Initialize posix time values used in tests.
void initTimestamps() {
// Current time minus 1 hour to make sure it is in the past.
- timestamps_["today"] = boost::posix_time::second_clock::universal_time()
+ timestamps_["today"] = boost::posix_time::second_clock::local_time()
- boost::posix_time::hours(1);
// Yesterday.
timestamps_["yesterday"] = timestamps_["today"] - boost::posix_time::hours(24);
namespace data {
StampedElement::StampedElement()
- : timestamp_(boost::posix_time::microsec_clock::universal_time()) {
+ : timestamp_(boost::posix_time::microsec_clock::local_time()) {
}
void
StampedElement::updateModificationTime() {
- setModificationTime(boost::posix_time::microsec_clock::universal_time());
+ setModificationTime(boost::posix_time::microsec_clock::local_time());
}
} // end of namespace isc::data
// Checking that the delta between now and the timestamp is within
// 5s range should be sufficient.
boost::posix_time::time_duration delta =
- boost::posix_time::second_clock::universal_time() -
+ boost::posix_time::second_clock::local_time() -
element.getModificationTime();
EXPECT_LT(delta.seconds(), 5);
}
// Checking that the delta between now and the timestamp is within
// 5s range should be sufficient.
boost::posix_time::time_duration delta =
- boost::posix_time::second_clock::universal_time() -
+ boost::posix_time::second_clock::local_time() -
element.getModificationTime();
EXPECT_LT(delta.seconds(), 5);
}
: object_type_(object_type),
object_id_(object_id),
modification_type_(modification_type),
- modification_time_(boost::posix_time::microsec_clock::universal_time()),
+ modification_time_(boost::posix_time::microsec_clock::local_time()),
log_message_(log_message) {
// Check if the provided values are sane.
validate();
/// @brief Returns current time.
static boost::posix_time::ptime now() {
- return (boost::posix_time::microsec_clock::universal_time());
+ return (boost::posix_time::microsec_clock::local_time());
}
/// @brief Returns always the same time value.
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#include <config.h>
+#include <boost/date_time/gregorian/gregorian.hpp>
#include <mysql/mysql_binding.h>
+using namespace boost::posix_time;
using namespace isc::data;
namespace isc {
return (getBlob());
}
-boost::posix_time::ptime
+ptime
MySqlBinding::getTimestamp() const {
// Make sure the binding type is timestamp.
- validateAccess<boost::posix_time::ptime>();
+ validateAccess<ptime>();
// Copy the buffer contents into native timestamp structure and
// then convert it to posix time.
const MYSQL_TIME* database_time = reinterpret_cast<const MYSQL_TIME*>(&buffer_[0]);
return (convertFromDatabaseTime(*database_time));
}
-boost::posix_time::ptime
-MySqlBinding::getTimestampOrDefault(const boost::posix_time::ptime& default_value) const {
+ptime
+MySqlBinding::getTimestampOrDefault(const ptime& default_value) const {
if (amNull()) {
return (default_value);
}
}
MySqlBindingPtr
-MySqlBinding::createTimestamp(const boost::posix_time::ptime& timestamp) {
- MySqlBindingPtr binding(new MySqlBinding(MySqlBindingTraits<boost::posix_time::ptime>::column_type,
- MySqlBindingTraits<boost::posix_time::ptime>::length));
+MySqlBinding::createTimestamp(const ptime& timestamp) {
+ MySqlBindingPtr binding(new MySqlBinding(MySqlBindingTraits<ptime>::column_type,
+ MySqlBindingTraits<ptime>::length));
binding->setTimestampValue(timestamp);
return (binding);
}
MySqlBindingPtr
MySqlBinding::createTimestamp() {
- MySqlBindingPtr binding(new MySqlBinding(MySqlBindingTraits<boost::posix_time::ptime>::column_type,
- MySqlBindingTraits<boost::posix_time::ptime>::length));
+ MySqlBindingPtr binding(new MySqlBinding(MySqlBindingTraits<ptime>::column_type,
+ MySqlBindingTraits<ptime>::length));
return (binding);
}
void
MySqlBinding::convertToDatabaseTime(const time_t input_time,
- MYSQL_TIME& output_time) {
+ MYSQL_TIME& output_time) {
// Convert to broken-out time
struct tm time_tm;
output_time.neg = my_bool(0); // Not negative
}
+void
+MySqlBinding::convertToDatabaseTime(const ptime& input_time,
+ MYSQL_TIME& output_time) {
+ if (input_time.is_not_a_date_time()) {
+ isc_throw(BadValue, "Time value is not a valid posix time");
+ }
+
+ output_time.year = input_time.date().year();
+ output_time.month = input_time.date().month();
+ output_time.day = input_time.date().day();
+ output_time.hour = input_time.time_of_day().hours();
+ output_time.minute = input_time.time_of_day().minutes();
+ output_time.second = input_time.time_of_day().seconds();
+ output_time.second_part = input_time.time_of_day().fractional_seconds()
+ *1000000/time_duration::ticks_per_second();
+ output_time.neg = my_bool(0);
+}
+
void
MySqlBinding::convertToDatabaseTime(const time_t cltt,
- const uint32_t valid_lifetime,
- MYSQL_TIME& expire) {
+ const uint32_t valid_lifetime,
+ MYSQL_TIME& expire) {
// Calculate expiry time. Store it in the 64-bit value so as we can detect
// overflows.
cltt = mktime(&expire_tm) - valid_lifetime;
}
-boost::posix_time::ptime
+ptime
MySqlBinding::convertFromDatabaseTime(const MYSQL_TIME& database_time) {
- // Copy across fields from MYSQL_TIME structure.
- struct tm converted_tm;
- memset(&converted_tm, 0, sizeof(converted_tm));
-
- converted_tm.tm_year = database_time.year - 1900;
- converted_tm.tm_mon = database_time.month - 1;
- converted_tm.tm_mday = database_time.day;
- converted_tm.tm_hour = database_time.hour;
- converted_tm.tm_min = database_time.minute;
- converted_tm.tm_sec = database_time.second;
- converted_tm.tm_isdst = -1; // Let the system work out about DST
-
- // Convert to local time
- return (boost::posix_time::ptime_from_tm(converted_tm));
+ long fractional = database_time.second_part * time_duration::ticks_per_second()/1000000;
+ ptime pt(boost::gregorian::date(database_time.year,
+ boost::gregorian::greg_month(database_time.month),
+ database_time.day),
+ time_duration(database_time.hour, database_time.minute,
+ database_time.second, fractional));
+
+ return (pt);
}
MySqlBinding::MySqlBinding(enum_field_types buffer_type,
}
void
-MySqlBinding::setTimestampValue(const boost::posix_time::ptime& timestamp) {
- // Convert timestamp to tm structure.
- tm td_tm = to_tm(timestamp);
- // Convert tm value to time_t.
- time_t tt = mktime(&td_tm);
- // Convert time_t to database time.
+MySqlBinding::setTimestampValue(const ptime& timestamp) {
MYSQL_TIME database_time;
- convertToDatabaseTime(tt, database_time);
+ convertToDatabaseTime(timestamp, database_time);
// Copy database time into the buffer.
memcpy(static_cast<void*>(&buffer_[0]), reinterpret_cast<char*>(&database_time),
sizeof(MYSQL_TIME));
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
static void convertToDatabaseTime(const time_t input_time,
MYSQL_TIME& output_time);
+ /// @brief Converts posix time value to database time.
+ ///
+ /// @param input_time A posix time value representing local time.
+ /// @param output_time Reference to MYSQL_TIME object where converted time
+ /// will be put.
+ static void convertToDatabaseTime(const boost::posix_time::ptime& input_time,
+ MYSQL_TIME& output_time);
+
/// @brief Converts Lease Time to Database Times
///
/// Within the DHCP servers, times are stored as client last transmit time
/// @param database_time Reference to MYSQL_TIME object where database
/// time is stored.
///
- /// @return Database time converted to posix time.
+ /// @return Database time converted to local posix time.
static boost::posix_time::ptime
convertFromDatabaseTime(const MYSQL_TIME& database_time);
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#include <config.h>
#include <mysql/mysql_binding.h>
+#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <gtest/gtest.h>
// This test verifies that default timestamp is returned if binding is null.
TEST(MySqlBindingTest, defaultTimestamp) {
- boost::posix_time::ptime current_time = boost::posix_time::second_clock::universal_time();
+ boost::posix_time::ptime current_time = boost::posix_time::second_clock::local_time();
boost::posix_time::ptime past_time = current_time - boost::posix_time::hours(1);
auto binding = MySqlBinding::createNull();
EXPECT_TRUE(current_time == binding->getTimestampOrDefault(past_time));
}
+// This test verifies that the binding preserves fractional seconds in
+// millisecond precision.
+TEST(MySqlBindingTest, millisecondTimestampPrecision) {
+ // Set timestamp of 2019-01-28 01:12:10.123
+
+ // Fractional part depends on the clock resolution.
+ long fractional = 123*(boost::posix_time::time_duration::ticks_per_second()/1000);
+ boost::posix_time::ptime
+ test_time(boost::gregorian::date(2019, boost::gregorian::Jan, 28),
+ boost::posix_time::time_duration(1, 12, 10, fractional));
+
+ auto binding = MySqlBinding::createTimestamp(test_time);
+
+ boost::posix_time::ptime returned_test_time = binding->getTimestamp();
+
+ EXPECT_EQ(returned_test_time, test_time);
+}
+
}
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
"bigint_value BIGINT NULL,"
"string_value TEXT NULL,"
"blob_value BLOB NULL,"
- "timestamp_value TIMESTAMP NULL"
+ "timestamp_value TIMESTAMP(6) NULL"
")");
}
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createBlob(blob.begin(), blob.end()),
- MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::universal_time())
+ MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
};
testInsertSelect(in_bindings);
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createBlob(blob.begin(), blob.end()),
- MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::universal_time())
+ MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
};
testInsertSelect(in_bindings);
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createNull(),
MySqlBinding::createBlob(blob.begin(), blob.end()),
- MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::universal_time())
+ MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
};
testInsertSelect(in_bindings);
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString("shellfish"),
MySqlBinding::createNull(),
- MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::universal_time())
+ MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
};
testInsertSelect(in_bindings);
MySqlBinding::createInteger<int64_t>(-4096),
MySqlBinding::createString(""),
MySqlBinding::createBlob(blob.begin(), blob.end()),
- MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::universal_time())
+ MySqlBinding::createTimestamp(boost::posix_time::microsec_clock::local_time())
};
testInsertSelect(in_bindings);