Giter Site home page Giter Site logo

date_time's Introduction

DateTime, part of the collection of Boost C++ Libraries, makes programming with dates and times as simple and natural as programming with strings and integers.

License

Distributed under the Boost Software License, Version 1.0.

Properties

  • C++03
  • Header only

Build Status

Branch GHA CI Appveyor Coverity Scan codecov.io Deps Docs Tests
master Build Status Build status Coverity Scan Build Status codecov Deps Documentation Enter the Matrix
develop Build Status Build status Coverity Scan Build Status codecov Deps Documentation Enter the Matrix

Directories

Note that the built library is only for build backward compatibility and contains no symbols. date_time is now header only.

Name Purpose
build build script for optional lib build
data timezone database
doc documentation
example use case examples
include headers
src source code for optional link library
test unit tests
xmldoc documentation source

More information

  • Ask questions: Be sure to read the documentation first to see if it answers your question.
  • Report bugs: Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
  • Submit Pull Requests against the develop branch. Note that by submitting patches you agree to license your modifications under the Boost Software License, Version 1.0. Be sure to include tests proving your changes work properly.
  • Discussions about the library are held on the Boost developers mailing list. Be sure to read the discussion policy before posting and add the [date_time] tag at the beginning of the subject line.

date_time's People

Contributors

alisdairm avatar belcourt avatar beman avatar danielae avatar danieljames avatar douggregor avatar eldiener avatar gawain-bolton avatar grafikrobot avatar imikejackson avatar jeffgarland avatar jeking3 avatar jewillco avatar jhunold avatar joachim-faulhaber avatar jurko-gospodnetic avatar jzmaddock avatar kojoley avatar lastique avatar marcelraad avatar mclow avatar orudge avatar p12tic avatar pdimov avatar pgroke-dt avatar sdarwin avatar steveire avatar straszheim avatar viboes avatar vprus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

date_time's Issues

formal support for c++20 operator<=>

In issue #13 (C++20 ambiguous comparison operator warning with clang 10) there's some discussion of how to support operator<=> correctly in date_time. This is an issue to track that set of changes.

time_duration is not a complete partial order regarding time_duration(not_a_date_time)

hi

please compile this program:

#include <boost/date_time/posix_time/ptime.hpp>
#include
#include

using namespace boost::posix_time;
using namespace std;

#define x(v) cout << #v << " : " << (v) << '\n';

int main(int argc, char *argv[])
{
time_duration a(not_a_date_time);
time_duration b;
x(a<b);
x(a>b);
x(a<=b);
x(a>=b);
x(b<a);
x(b>a);
x(b<=a);
x(b>=a);
x(a==b);
x(b==a);
x(a.is_special());
x(b.is_special());
vector<time_duration> v0, v1;
v0.push_back(time_duration());
v0.push_back(time_duration(not_a_date_time));
sort(v0.begin(), v0.end());
v1.push_back(time_duration(not_a_date_time));
v1.push_back(time_duration());
sort(v1.begin(), v1.end());
x(v0==v1);

map<time_duration, string> c,d;
c[time_duration()]=5;
c[time_duration(not_a_date_time)]=7;
d[time_duration(not_a_date_time)]=7;
d[time_duration()]=5;
x(c==d);

return 0;
}

the output is:

a<b : 0
a>b : 0
a<=b : 1
a>=b : 1
b<a : 0
b>a : 0
b<=a : 1
b>=a : 1
a==b : 0
b==a : 0
a.is_special() : 1
b.is_special() : 0
v0==v1 : 0
c==d : 0

if the time_duration datatype is a complete partial order which is for
example needed for it to be able to be sorted, then the above output is
partly illegal:

if not a<b and not b<a then must be a=b. but this is not the case.

if a<=b and b<=a then must be a=b. but this is not the case.

so as expected the two vectors v0 and v1 are not equal after being
sorted even though they certainly should be!

also the maps c and d should be equal but aren't.

I hope that this is a bug and not a feature. otherwise it should be documented that even though ptime and gregorian::date are complete partial orders (also regarding their not_a_date_time special value), time_duration isn't. But I really strongly hope that this is a bug.

cya
erik

Potential divide by zero?

Reported by the clang static analyzer, we have a potential divide by zero in

int_adapter operator/(const int rhs) const

where we have:

  int_adapter operator/(const int rhs) const
  {
    if(is_special() && rhs != 0)
    {
      return mult_div_specials(rhs);
    }
    return int_adapter<int_type>(value_ / rhs);
  }

However, I'm not sure if this is intentional? If it is, we should at least have a comment here explaining it.

Unmatched posix_time::time_input_facet format string delimiters are not considered an error

Test case (for testtime_input_facet):

  {
      // what if the separator characters between fields do not match the format string?
      const std::string value = "December 07|27|10.435945  5 2017";   // should be colons, not bars, see format string:
      boost::posix_time::time_input_facet* facet = new boost::posix_time::time_input_facet("%B %H:%M:%s %e %Y");
      boost::posix_time::ptime pt;
      check("expect colon got bar", failure_test(pt, value, facet)); // proves failbit was set
  }

Currently this test fails, as failbit does not get set. The code in time_facet.hpp blindly steps over anything that isn't a format token.

Warnings caused by wrong use of BOOST_CONSTEXPR_OR_CONST

CC @JeffGarland

Since commit 4e1b7cd gcc 9 shows warnings like the following:

./boost/date_time/time_duration.hpp:85:12: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]

    static BOOST_CONSTEXPR_OR_CONST time_resolutions resolution()

           ^~~~~~~~~~~~~~~~~~~~~~~~~

The problem is that the commit marked many functions with BOOST_CONSTEXPR_OR_CONST instead of BOOST_CONSTEXPR, which results in the functions returning const values in C++03.

BOOST_CONSTEXPR_OR_CONST is intended to declare constant variables, it is not supposed to be used with functions.

LINK : fatal error LNK1104: can not open file'libboost_date_time-vc142-mt-gd-x64-1_73.lib'

Hi,
It is my first time with boost libraries. I am trying to learn, so I download all boost libraries and build. It is successfully built, and I added include and linkers library path to cmake file. I am working on asio, asio code work fine, but when I used timer, compiler give the error. I checked file exists, I search on Internet, find some solutions, but they did not work. I looked precompiled files, but there is no any file for boost 1.7.3. Operating system is Windows 10 and I am working with Visual Studio Code and CMake. Is there any chance that date_time library is not built correctly? and How can I solve this problem?
Thanks in advance.

Working code:

#define _WIN32_WINNT  0x0A00 
#include <iostream>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
using namespace std;

int main()
{
  boost::asio::io_context io_context;
  boost::asio::post(io_context, []() { cout<<"test"<<endl; });
  for (;;)
  {
    try
    {

      io_context.run();
      break; 
    }
    catch (exception& e)
    {
      cout<<e.what()<<endl;
    }
  }
  int open;
  std::cin>>open;
  return 0;
}

Compiler Error Code:

#define _WIN32_WINNT  0x0A00 
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>

void print(const boost::system::error_code&, boost::asio::deadline_timer* t,int* count)
{
    if (*count < 5)
    {
        std::cout << *count << std::endl;
        ++(*count);
        t->expires_from_now(boost::posix_time::seconds(1));
        t->async_wait(boost::bind(print, boost::asio::placeholders::error, t, count));
    }
}

int main()
{ 
    boost::asio::io_service io;
    int count = 0;
    boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));

    t.async_wait(boost::bind(print, boost::asio::placeholders::error, &t, &count));
    io.run();
    std::cout << "Final count is " << count << std::endl;
    return 0;

}

Compiler Error:

LINK : fatal error LNK1104: can not open file'libboost_date_time-vc142-mt-gd-x64-1_73.lib'

CmakeLists.txt file:

cmake_minimum_required(VERSION 3.0.0)
SET(BOOST_INCLUDE  D:/libraries/boost_1_73_0)
SET(BOOST_LIB D:/libraries/boost_1_73_0/stage/lib)
project(boost-test VERSION 1.0)

set(EXEC main)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${BOOST_INCLUDE})
file(GLOB SOURCES src/*.cpp)
add_executable(${EXEC} ${SOURCES})
target_link_libraries(${EXEC} ${BOOST_LIB})

Default-constructing boost::posix_time::ptime and possibly other types is slow

I've noticed boost::posix_time::ptime default constructor in profiler traces when profiling an application that does non-insignificant amount of date/time handling. This was unexpected, because the compiler should be able to optimize the constructor to storing some constants to memory.

Turns out that the compiler fails to inline boost::gregorian::date::date(special_values). The following is the test case:

#include <boost/date_time/posix_time/ptime.hpp>

void do_stuff(boost::posix_time::ptime& time)
{
    time = boost::posix_time::ptime();
}

The following or equivalent assembly has been observed on GCC 6.5.0, 7.4.0 and 8.3.0 on -O2 or -O3 optimization levels on x86_64 with stack protector disabled (-fno-stack-protector):

_Z8do_stuffRN5boost10posix_time5ptimeE:
	push	rbx
	mov	rbx, rdi
	xor	esi, esi
	sub	rsp, 16
	lea	rdi, 12[rsp]
	call	_ZN5boost9gregorian4dateC1ENS_9date_time14special_valuesE
	movabs	rax, 9223372036854775806
	mov	QWORD PTR [rbx], rax
	add	rsp, 16
	pop	rbx
	ret

_ZN5boost9gregorian4dateC2ENS_9date_time14special_valuesE:
	cmp	esi, 4
	ja	.L641
	lea	rdx, .L643[rip]
	mov	esi, esi
	movsx	rax, DWORD PTR [rdx+rsi*4]
	add	rax, rdx
	jmp	rax
.L643:
	.long	.L642-.L643
	.long	.L644-.L643
	.long	.L649-.L643
	.long	.L646-.L643
	.long	.L647-.L643
.L647:
	mov	DWORD PTR [rdi], 5373484
	ret
.L646:
	mov	DWORD PTR [rdi], 2232400
	ret
.L649:
	mov	eax, -1
	mov	DWORD PTR [rdi], eax
	ret
.L644:
	xor	eax, eax
	mov	DWORD PTR [rdi], eax
	ret
.L642:
	mov	eax, -2
	mov	DWORD PTR [rdi], eax
	ret
.L641:
	mov	DWORD PTR [rdi], -2
	ret

As you can see, this is rather a large amount of instructions for a function that should just store some constant to memory.

After marking boost::gregorian::date::date(special_values) as BOOST_FORCEINLINE, we get the following:

_Z8do_stuffRN5boost10posix_time5ptimeE:
	movabs	rax, 9223372036854775806
	mov	QWORD PTR [rdi], rax
	ret

I propose that we apply this workaround to the library as it would improve the code size and speed for the majority of user workloads that are affected.

The only possibility this could be a regression would be in rarely executed call sites that pass non-constant value of special_values directly or indirectly to boost::gregorian::date::date. However, forcing inlining in such a case would just inflate code size a little bit and I suspect that the library user would still save code size overall due to significant reductions of code size around calls to default constructor of ptime and related types.

List of non BOOST-prefixed macros

The following macros are missing a BOOST_ prefix, which is against Boost library guidelines:

./boost/date_time/wrapping_int.hpp:#ifndef _DATE_TIME_WRAPPING_INT_HPP__
./boost/date_time/wrapping_int.hpp:#define _DATE_TIME_WRAPPING_INT_HPP__
./boost/date_time/int_adapter.hpp:#ifndef _DATE_TIME_INT_ADAPTER_HPP__
./boost/date_time/int_adapter.hpp:#define _DATE_TIME_INT_ADAPTER_HPP__
./boost/date_time/time_facet.hpp:#ifndef _DATE_TIME_FACET__HPP__
./boost/date_time/time_facet.hpp:#define _DATE_TIME_FACET__HPP__
./boost/date_time/date_parsing.hpp:#ifndef _DATE_TIME_DATE_PARSING_HPP___
./boost/date_time/date_parsing.hpp:#define _DATE_TIME_DATE_PARSING_HPP___
./boost/date_time/time_zone_base.hpp:#ifndef _DATE_TIME_TIME_ZONE_BASE__
./boost/date_time/time_zone_base.hpp:#define _DATE_TIME_TIME_ZONE_BASE__
./boost/date_time/adjust_functors.hpp:#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
./boost/date_time/adjust_functors.hpp:#define _DATE_TIME_ADJUST_FUNCTORS_HPP___
./boost/date_time/time_parsing.hpp:#ifndef _DATE_TIME_TIME_PARSING_HPP___
./boost/date_time/time_parsing.hpp:#define _DATE_TIME_TIME_PARSING_HPP___
./boost/date_time/local_time/posix_time_zone.hpp:#ifndef _DATE_TIME_POSIX_TIME_ZONE__
./boost/date_time/local_time/posix_time_zone.hpp:#define _DATE_TIME_POSIX_TIME_ZONE__
./boost/date_time/local_time/posix_time_zone.hpp:#endif // _DATE_TIME_POSIX_TIME_ZONE__
./boost/date_time/date_facet.hpp:#ifndef _DATE_TIME_DATE_FACET__HPP___
./boost/date_time/date_facet.hpp:#define _DATE_TIME_DATE_FACET__HPP___
./boost/date_time/date_generator_formatter.hpp:#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
./boost/date_time/date_generator_formatter.hpp:#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
./boost/date_time/date_generator_formatter.hpp:#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
./libs/date_time/src/gregorian/greg_names.hpp:#ifndef DATE_TIME_SRC_GREG_NAMES_HPP___
./libs/date_time/src/gregorian/greg_names.hpp:#define DATE_TIME_SRC_GREG_NAMES_HPP___
./libs/date_time/src/gregorian/greg_names.hpp:#endif // DATE_TIME_SRC_GREG_NAMES_HPP___
./boost/date_time/tz_db_base.hpp:#ifndef DATE_TIME_TZ_DB_BASE_HPP__
./boost/date_time/tz_db_base.hpp:#define DATE_TIME_TZ_DB_BASE_HPP__
./boost/date_time/tz_db_base.hpp:#endif // DATE_TIME_TZ_DB_BASE_HPP__
./boost/date_time/time_formatting_streams.hpp:#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
./boost/date_time/time_formatting_streams.hpp:#define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
./boost/date_time/dst_transition_generators.hpp:#ifndef DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
./boost/date_time/dst_transition_generators.hpp:#define DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
./boost/date_time/time_defs.hpp:#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP
./boost/date_time/time_defs.hpp:#define DATE_TIME_TIME_PRECISION_LIMITS_HPP
./boost/date_time/date.hpp:#ifndef DATE_TIME_DATE_HPP___
./boost/date_time/date.hpp:#define DATE_TIME_DATE_HPP___
./boost/date_time/format_date_parser.hpp:#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__
./boost/date_time/format_date_parser.hpp:#define DATE_TIME_FORMAT_DATE_PARSER_HPP__
./boost/date_time/time_duration.hpp:#ifndef DATE_TIME_TIME_DURATION_HPP___
./boost/date_time/time_duration.hpp:#define DATE_TIME_TIME_DURATION_HPP___
./boost/date_time/time_resolution_traits.hpp:#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
./boost/date_time/time_resolution_traits.hpp:#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
./boost/date_time/special_defs.hpp:#ifndef DATE_TIME_SPECIAL_DEFS_HPP__
./boost/date_time/special_defs.hpp:#define DATE_TIME_SPECIAL_DEFS_HPP__
./boost/date_time/c_time.hpp:#ifndef DATE_TIME_C_TIME_HPP___
./boost/date_time/c_time.hpp:#define DATE_TIME_C_TIME_HPP___
./boost/date_time/c_time.hpp:#endif // DATE_TIME_C_TIME_HPP___
./boost/date_time/parse_format_base.hpp:#ifndef DATE_TIME_PARSE_FORMAT_BASE__
./boost/date_time/parse_format_base.hpp:#define DATE_TIME_PARSE_FORMAT_BASE__
./boost/date_time/local_time_adjustor.hpp:#ifndef DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
./boost/date_time/local_time_adjustor.hpp:#define DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
./boost/date_time/date_formatting_limited.hpp:#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
./boost/date_time/date_formatting_limited.hpp:#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
./boost/date_time/time_zone_names.hpp:#ifndef DATE_TIME_TIME_ZONE_NAMES_HPP__
./boost/date_time/time_zone_names.hpp:#define DATE_TIME_TIME_ZONE_NAMES_HPP__
./boost/date_time/time_system_counted.hpp:#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP
./boost/date_time/time_system_counted.hpp:#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP
./boost/date_time/date_formatting_locales.hpp:#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
./boost/date_time/date_formatting_locales.hpp:#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
./boost/date_time/date_format_simple.hpp:#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___
./boost/date_time/date_format_simple.hpp:#define DATE_TIME_SIMPLE_FORMAT_HPP___
./boost/date_time/posix_time/ptime.hpp:#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
./boost/date_time/posix_time/posix_time_io.hpp:#ifndef DATE_TIME_POSIX_TIME_IO_HPP__
./boost/date_time/posix_time/posix_time_io.hpp:#define DATE_TIME_POSIX_TIME_IO_HPP__
./boost/date_time/posix_time/posix_time_io.hpp:#endif // DATE_TIME_POSIX_TIME_IO_HPP__
./boost/date_time/date_defs.hpp:#ifndef DATE_TIME_DATE_DEFS_HPP
./boost/date_time/date_defs.hpp:#define DATE_TIME_DATE_DEFS_HPP
./boost/date_time/gregorian/greg_ymd.hpp:#ifndef DATE_TIME_GREG_YMD_HPP__
./boost/date_time/gregorian/greg_ymd.hpp:#define DATE_TIME_GREG_YMD_HPP__
./boost/date_time/gregorian/gregorian_io.hpp:#ifndef DATE_TIME_GREGORIAN_IO_HPP__
./boost/date_time/gregorian/gregorian_io.hpp:#define DATE_TIME_GREGORIAN_IO_HPP__
./boost/date_time/gregorian/gregorian_io.hpp:#endif // DATE_TIME_GREGORIAN_IO_HPP__
./boost/date_time/microsec_time_clock.hpp:#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
./boost/date_time/microsec_time_clock.hpp:#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
./boost/date_time/time_system_split.hpp:#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP
./boost/date_time/time_system_split.hpp:#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP
./boost/date_time/period.hpp:#ifndef DATE_TIME_PERIOD_HPP___
./boost/date_time/period.hpp:#define DATE_TIME_PERIOD_HPP___
./boost/date_time/special_values_parser.hpp:#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
./boost/date_time/special_values_parser.hpp:#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
./boost/date_time/special_values_parser.hpp:#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
./boost/date_time/strings_from_facet.hpp:#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___
./boost/date_time/strings_from_facet.hpp:#define DATE_TIME_STRINGS_FROM_FACET__HPP___
./boost/date_time/date_names_put.hpp:#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
./boost/date_time/date_names_put.hpp:#define DATE_TIME_DATE_NAMES_PUT_HPP___
./boost/date_time/gregorian_calendar.hpp:#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__
./boost/date_time/gregorian_calendar.hpp:#define DATE_TIME_GREGORIAN_CALENDAR_HPP__
./boost/date_time/date_generator_parser.hpp:#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__
./boost/date_time/date_generator_parser.hpp:#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__
./boost/date_time/date_generator_parser.hpp:#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__
./boost/date_time/local_time/conversion.hpp:#ifndef DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
./boost/date_time/local_time/conversion.hpp:#define DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
./boost/date_time/local_time/conversion.hpp:#endif // DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
./boost/date_time/date_duration.hpp:#ifndef DATE_TIME_DATE_DURATION__
./boost/date_time/date_duration.hpp:#define DATE_TIME_DATE_DURATION__
./boost/date_time/locale_config.hpp:#ifndef DATE_TIME_LOCALE_CONFIG_HPP___
./boost/date_time/locale_config.hpp:#define DATE_TIME_LOCALE_CONFIG_HPP___
./boost/date_time/local_timezone_defs.hpp:#ifndef DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
./boost/date_time/local_timezone_defs.hpp:#define DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
./boost/date_time/time_clock.hpp:#ifndef DATE_TIME_TIME_CLOCK_HPP___
./boost/date_time/time_clock.hpp:#define DATE_TIME_TIME_CLOCK_HPP___
./boost/date_time/date_formatting.hpp:#ifndef DATE_TIME_DATE_FORMATTING_HPP___
./boost/date_time/date_formatting.hpp:#define DATE_TIME_DATE_FORMATTING_HPP___
./boost/date_time/time.hpp:#ifndef DATE_TIME_TIME_HPP___
./boost/date_time/time.hpp:#define DATE_TIME_TIME_HPP___
./boost/date_time/c_local_time_adjustor.hpp:#ifndef DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
./boost/date_time/c_local_time_adjustor.hpp:#define DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
./boost/date_time/compiler_config.hpp:#ifndef DATE_TIME_COMPILER_CONFIG_HPP___
./boost/date_time/compiler_config.hpp:#define DATE_TIME_COMPILER_CONFIG_HPP___
./boost/date_time/compiler_config.hpp://#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR
./boost/date_time/date_generators.hpp:#ifndef DATE_TIME_DATE_GENERATORS_HPP__
./boost/date_time/date_generators.hpp:#define DATE_TIME_DATE_GENERATORS_HPP__
./boost/date_time/dst_rules.hpp:#ifndef DATE_TIME_DST_RULES_HPP__
./boost/date_time/dst_rules.hpp:#define DATE_TIME_DST_RULES_HPP__
./boost/date_time/time_iterator.hpp:#ifndef DATE_TIME_TIME_ITERATOR_HPP___
./boost/date_time/time_iterator.hpp:#define DATE_TIME_TIME_ITERATOR_HPP___
./boost/date_time/filetime_functions.hpp:#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__
./boost/date_time/filetime_functions.hpp:#define DATE_TIME_FILETIME_FUNCTIONS_HPP__
./boost/date_time/filetime_functions.hpp:#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__
./boost/date_time/period_formatter.hpp:#ifndef DATETIME_PERIOD_FORMATTER_HPP___
./boost/date_time/period_formatter.hpp:#define DATETIME_PERIOD_FORMATTER_HPP___
./boost/date_time/period_parser.hpp:#ifndef DATETIME_PERIOD_PARSER_HPP___
./boost/date_time/period_parser.hpp:#define DATETIME_PERIOD_PARSER_HPP___
./boost/date_time/period_parser.hpp:#endif // DATETIME_PERIOD_PARSER_HPP___
./boost/date_time/special_values_formatter.hpp:#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
./boost/date_time/special_values_formatter.hpp:#define DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
./boost/date_time/posix_time/time_serialize.hpp:#ifndef POSIX_TIME_SERIALIZE_HPP___
./boost/date_time/posix_time/time_serialize.hpp:#define POSIX_TIME_SERIALIZE_HPP___
./boost/date_time/posix_time/posix_time_config.hpp:#ifndef POSIX_TIME_CONFIG_HPP___
./boost/date_time/posix_time/posix_time_config.hpp:#define POSIX_TIME_CONFIG_HPP___
./boost/date_time/posix_time/conversion.hpp:#ifndef POSIX_TIME_CONVERSION_HPP___
./boost/date_time/posix_time/conversion.hpp:#define POSIX_TIME_CONVERSION_HPP___
./boost/date_time/posix_time/posix_time.hpp:#ifndef POSIX_TIME_HPP___
./boost/date_time/posix_time/posix_time.hpp:#define POSIX_TIME_HPP___
./boost/date_time/posix_time/posix_time_system.hpp:#ifndef POSIX_TIME_SYSTEM_HPP___
./boost/date_time/posix_time/posix_time_system.hpp:#define POSIX_TIME_SYSTEM_HPP___
./boost/date_time/posix_time/time_period.hpp:#ifndef POSIX_TIME_PERIOD_HPP___
./boost/date_time/posix_time/time_period.hpp:#define POSIX_TIME_PERIOD_HPP___
./boost/date_time/posix_time/ptime.hpp:#ifndef POSIX_PTIME_HPP___
./boost/date_time/posix_time/ptime.hpp:#define POSIX_PTIME_HPP___
./boost/date_time/posix_time/posix_time_duration.hpp:#ifndef POSIX_TIME_DURATION_HPP___
./boost/date_time/posix_time/posix_time_duration.hpp:#define POSIX_TIME_DURATION_HPP___
./boost/date_time/posix_time/posix_time_legacy_io.hpp:#ifndef POSIX_TIME_PRE133_OPERATORS_HPP___
./boost/date_time/posix_time/posix_time_legacy_io.hpp:#define POSIX_TIME_PRE133_OPERATORS_HPP___
./boost/date_time/posix_time/posix_time_legacy_io.hpp:#endif // POSIX_TIME_PRE133_OPERATORS_HPP___
./boost/date_time/posix_time/posix_time_types.hpp:#ifndef POSIX_TIME_TYPES_HPP___
./boost/date_time/posix_time/posix_time_types.hpp:#define POSIX_TIME_TYPES_HPP___
./boost/date_time/date_duration_types.hpp:#ifndef DATE_DURATION_TYPES_HPP___
./boost/date_time/date_duration_types.hpp:#define DATE_DURATION_TYPES_HPP___
./boost/date_time/date_duration_types.hpp:#endif // DATE_DURATION_TYPES_HPP___
./boost/date_time/posix_time/date_duration_operators.hpp:#ifndef DATE_DURATION_OPERATORS_HPP___
./boost/date_time/posix_time/date_duration_operators.hpp:#define DATE_DURATION_OPERATORS_HPP___
./boost/date_time/posix_time/date_duration_operators.hpp:#endif // DATE_DURATION_OPERATORS_HPP___
./boost/date_time/local_time/custom_time_zone.hpp:#ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
./boost/date_time/local_time/custom_time_zone.hpp:#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
./boost/date_time/local_time/local_date_time.hpp:#ifndef LOCAL_TIME_LOCAL_DATE_TIME_HPP__
./boost/date_time/local_time/local_date_time.hpp:#define LOCAL_TIME_LOCAL_DATE_TIME_HPP__
./boost/date_time/local_time/date_duration_operators.hpp:#ifndef LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
./boost/date_time/local_time/date_duration_operators.hpp:#define LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
./boost/date_time/local_time/date_duration_operators.hpp:#endif // LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
./boost/date_time/local_time/dst_transition_day_rules.hpp:#ifndef LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
./boost/date_time/local_time/dst_transition_day_rules.hpp:#define LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
./boost/date_time/local_time/local_time_types.hpp:#ifndef LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
./boost/date_time/local_time/local_time_types.hpp:#define LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
./boost/date_time/local_time/local_time_types.hpp:#endif // LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
./boost/date_time/local_time/local_time.hpp:#ifndef LOCAL_TIME_LOCAL_TIME_HPP__
./boost/date_time/local_time/local_time.hpp:#define LOCAL_TIME_LOCAL_TIME_HPP__
./boost/date_time/iso_format.hpp:#ifndef ISO_FORMAT_HPP___
./boost/date_time/iso_format.hpp:#define ISO_FORMAT_HPP___
./boost/date_time/gregorian/formatters.hpp:#ifndef GREGORIAN_FORMATTERS_HPP___
./boost/date_time/gregorian/formatters.hpp:#define GREGORIAN_FORMATTERS_HPP___
./boost/date_time/gregorian/parsers.hpp:#ifndef GREGORIAN_PARSERS_HPP___
./boost/date_time/gregorian/parsers.hpp:#define GREGORIAN_PARSERS_HPP___
./boost/date_time/gregorian/formatters_limited.hpp:#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___
./boost/date_time/gregorian/formatters_limited.hpp:#define GREGORIAN_FORMATTERS_LIMITED_HPP___
./boost/date_time/gregorian/greg_calendar.hpp:#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__
./boost/date_time/gregorian/greg_calendar.hpp:#define GREGORIAN_GREGORIAN_CALENDAR_HPP__
./boost/date_time/gregorian/gregorian.hpp:#ifndef GREGORIAN_HPP__
./boost/date_time/gregorian/gregorian.hpp:#define GREGORIAN_HPP__
./boost/date_time/gregorian/greg_serialize.hpp:#ifndef GREGORIAN_SERIALIZE_HPP___
./boost/date_time/gregorian/greg_serialize.hpp:#define GREGORIAN_SERIALIZE_HPP___
./boost/date_time/gregorian/greg_facet.hpp:#ifndef GREGORIAN_FACET_HPP___
./boost/date_time/gregorian/greg_facet.hpp:#define GREGORIAN_FACET_HPP___
./boost/date_time/gregorian/greg_day.hpp:#ifndef GREG_DAY_HPP___
./boost/date_time/gregorian/greg_day.hpp:#define GREG_DAY_HPP___
./boost/date_time/gregorian/greg_duration.hpp:#ifndef GREG_DURATION_HPP___
./boost/date_time/gregorian/greg_duration.hpp:#define GREG_DURATION_HPP___
./boost/date_time/gregorian/greg_date.hpp:#ifndef GREG_DATE_HPP___
./boost/date_time/gregorian/greg_date.hpp:#define GREG_DATE_HPP___
./boost/date_time/gregorian/greg_month.hpp:#ifndef GREG_MONTH_HPP___
./boost/date_time/gregorian/greg_month.hpp:#define GREG_MONTH_HPP___
./boost/date_time/gregorian/greg_weekday.hpp:#ifndef GREG_WEEKDAY_HPP___
./boost/date_time/gregorian/greg_weekday.hpp:#define GREG_WEEKDAY_HPP___
./boost/date_time/gregorian/greg_year.hpp:#ifndef GREG_YEAR_HPP___
./boost/date_time/gregorian/greg_year.hpp:#define GREG_YEAR_HPP___
./boost/date_time/gregorian/greg_duration_types.hpp:#ifndef GREG_DURATION_TYPES_HPP___
./boost/date_time/gregorian/greg_duration_types.hpp:#define GREG_DURATION_TYPES_HPP___
./boost/date_time/gregorian/greg_duration_types.hpp:#endif // GREG_DURATION_TYPES_HPP___
./boost/date_time/gregorian/greg_day_of_year.hpp:#ifndef GREG_DAY_OF_YEAR_HPP___
./boost/date_time/gregorian/greg_day_of_year.hpp:#define GREG_DAY_OF_YEAR_HPP___
./boost/date_time/date_clock_device.hpp:#ifndef DATE_CLOCK_DEVICE_HPP___
./boost/date_time/date_clock_device.hpp:#define DATE_CLOCK_DEVICE_HPP___
./boost/date_time/constrained_value.hpp:#ifndef CONSTRAINED_VALUE_HPP___
./boost/date_time/constrained_value.hpp:#define CONSTRAINED_VALUE_HPP___

Inconsistent '%f' behaviour between boost::posix_time::time_facet and boost::posix_time::time_input_facet

I'm trying to convert a boost::posix_time::ptime to a specific string format (extended ISO) and then back to a boost::posix_time::ptime.

Surprisingly, it looks like for boost::posix_time::time_facet %f means 000000 to 999999 (with no decimal separator). But for boost::posix_time::time_input_facet, it means .000000 to .999999 (with decimal separator).

int main( int argc, char** argv )
{
    auto now = boost::posix_time::second_clock::local_time();

    std::stringstream outStr;
    {
        boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
        facet->format("%Y-%m-%dT%H:%M:%S.%f");
        outStr.imbue(std::locale(std::locale::classic(), facet));
        outStr << now;
    }
    std::cout << outStr.str() << std::endl;

    {
        static const std::string format = "%Y-%m-%dT%H:%M:%S.%f";
        const std::locale loc = std::locale(std::locale::classic(), new boost::posix_time::time_input_facet(format));
        std::istringstream is(outStr.str());
        is.imbue(loc);
        boost::posix_time::ptime converted;
        is >> converted;
        std::cout << converted << std::endl;
    }

    {
        static const std::string format = "%Y-%m-%dT%H:%M:%S%f";
        const std::locale loc = std::locale(std::locale::classic(), new boost::posix_time::time_input_facet(format));
        std::istringstream is(outStr.str());
        is.imbue(loc);
        boost::posix_time::ptime converted;
        is >> converted;
        std::cout << converted << std::endl;
    }

    return 0;
}

This outputs:

2019-04-30T12:23:29.000000
not-a-date-time
2019-Apr-30 12:23:29

While I would expect:

2019-04-30T12:23:29.000000
2019-Apr-30 12:23:29
not-a-date-time

Note that using "%Y-%m-%dT%H:%M:%S%F" works just fine (but has different behaviour when time is not a decimal value)

to_iso_extended_string documentation wrong about fraction print

I am using std::string to_iso_extended_string(ptime) and have reports that on some system it prints without the second fractions. Consulting the documentation and the header of boost 1.71 I was confronted with inconsistent documentation:

The Docs are saying it prints with fractions of a second:

std::string to_iso_extended_string(ptime)
Convert to form YYYY-MM-DDTHH:MM:SS,fffffffff where T is the date-time separator
2002-01-31T10:00:01,123456789

While the accoding header says:

//! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
/*!\ingroup time_format
*/
inline std::string to_iso_extended_string(ptime t){

So YYYY-MM-DDTHH:MM:SS,fffffffff or YYYY-MM-DDTHH:MM:SS, who is right?

Release Notes for Boost.DateTime release 1.67.0

  • [phrase library..[@/libs/date_time/ DateTime]:]
    • Fixed various year 2038 (32-bit) issues
      ([ticket 2818]) ([ticket 2819]) ([ticket 3487]) ([ticket 4543]) ([ticket 8450]) ([ticket 9158]) ([ticket 9489]) ([ticket 10570]) ([ticket 12609])
    • Fixed a binary serialization regression introduced in 1.66.0
      ([github date_time 56]) ([github_pr date_time 58]) ([github_pr date_time 70])
    • Updated the timezone database file
      ([ticket 4430]) ([ticket 10087]) ([github_pr date_time 68])
    • enhanced from_iso_string so it can read output of to_iso_string for special values
      ([ticket 1078]) ([github_pr date_time 69])
    • changed maximum supported year from 10000 to 9999 to resolve various issues
      ([ticket 13159]) ([ticket 12630]) ([github_pr date_time 71])
    • boost::date_time::period_parser::delimiter_strings did nothing
      ([ticket 11142]) ([github_pr date_time 63])
    • Ensure special values are not automatically translated to integral types
      ([ticket 11168]) ([github_pr date_time 64])
    • int_adapter is_signed should be const
      ([ticket 12363]) ([github_pr date_time 60])
    • boost::date_time::time_input_facet throws when using %j alone
      ([ticket 12910]) ([github_pr date_time 59])
    • Time input facet is not able to parse '%e' day
      ([ticket 13194]) ([github_pr date_time 54])
    • Improved github CI build environment for better project metrics and quality
      ([github_pr date_time 52]) ([github_pr date_time 72])
    • Fixed various compiler warnings
      ([ticket 3606]) ([ticket 9882]) ([github_pr date_time 62])

GCC suggest-override warnings

Complete list of warnings when Boost 1.72 is built with GCC 7.5 with -Wsuggest-override added to cxxflags:

./boost/date_time/date_generators.hpp:101:14: warning: ‘date_type boost::date_time::partial_date::get_date(boost::date_time::partial_date::year_type) const [with date_type = boost::gregorian::date; boost::date_time::partial_date::year_type = boost::gregorian::greg_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:142:24: warning: ‘std::__cxx11::string boost::date_time::partial_date::to_string() const [with date_type = boost::gregorian::date; std::__cxx11::string = std::__cxx11::basic_string]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:195:15: warning: ‘date_type boost::date_time::nth_kday_of_month::get_date(boost::date_time::nth_kday_of_month::year_type) const [with date_type = boost::gregorian::date; boost::date_time::nth_kday_of_month::year_type = boost::gregorian::greg_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:233:25: warning: ‘std::__cxx11::string boost::date_time::nth_kday_of_month::to_string() const [with date_type = boost::gregorian::date; std::__cxx11::string = std::__cxx11::basic_string]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:270:15: warning: ‘date_type boost::date_time::first_kday_of_month::get_date(boost::date_time::first_kday_of_month::year_type) const [with date_type = boost::gregorian::date; boost::date_time::first_kday_of_month::year_type = boost::gregorian::greg_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:290:25: warning: ‘std::__cxx11::string boost::date_time::first_kday_of_month::to_string() const [with date_type = boost::gregorian::date; std::__cxx11::string = std::__cxx11::basic_string]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:331:15: warning: ‘date_type boost::date_time::last_kday_of_month::get_date(boost::date_time::last_kday_of_month::year_type) const [with date_type = boost::gregorian::date; boost::date_time::last_kday_of_month::year_type = boost::gregorian::greg_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_generators.hpp:351:25: warning: ‘std::__cxx11::string boost::date_time::last_kday_of_month::to_string() const [with date_type = boost::gregorian::date; std::__cxx11::string = std::__cxx11::basic_string]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:263:20: warning: ‘void boost::date_time::all_date_names_put::do_put_month_short(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::month_enum) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::month_enum = boost::date_time::months_of_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:263:20: warning: ‘void boost::date_time::all_date_names_put::do_put_month_short(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::month_enum) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::month_enum = boost::date_time::months_of_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:268:20: warning: ‘void boost::date_time::all_date_names_put::do_put_month_long(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::month_enum) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::month_enum = boost::date_time::months_of_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:268:20: warning: ‘void boost::date_time::all_date_names_put::do_put_month_long(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::month_enum) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::month_enum = boost::date_time::months_of_year]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:273:20: warning: ‘void boost::date_time::all_date_names_put::do_put_special_value(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::special_value_enum) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::special_value_enum = boost::date_time::special_values]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:273:20: warning: ‘void boost::date_time::all_date_names_put::do_put_special_value(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::special_value_enum) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::special_value_enum = boost::date_time::special_values]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:277:20: warning: ‘void boost::date_time::all_date_names_put::do_put_weekday_short(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::weekday_enum) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::weekday_enum = boost::date_time::weekdays]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:277:20: warning: ‘void boost::date_time::all_date_names_put::do_put_weekday_short(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::weekday_enum) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::weekday_enum = boost::date_time::weekdays]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:281:20: warning: ‘void boost::date_time::all_date_names_put::do_put_weekday_long(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::weekday_enum) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::weekday_enum = boost::date_time::weekdays]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:281:20: warning: ‘void boost::date_time::all_date_names_put::do_put_weekday_long(boost::date_time::all_date_names_put::iter_type&, boost::date_time::all_date_names_put::weekday_enum) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::weekday_enum = boost::date_time::weekdays]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:286:20: warning: ‘void boost::date_time::all_date_names_put::do_month_sep_char(boost::date_time::all_date_names_put::iter_type&) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:286:20: warning: ‘void boost::date_time::all_date_names_put::do_month_sep_char(boost::date_time::all_date_names_put::iter_type&) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:291:20: warning: ‘void boost::date_time::all_date_names_put::do_day_sep_char(boost::date_time::all_date_names_put::iter_type&) const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:291:20: warning: ‘void boost::date_time::all_date_names_put::do_day_sep_char(boost::date_time::all_date_names_put::iter_type&) const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >; boost::date_time::all_date_names_put::iter_type = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:296:30: warning: ‘boost::date_time::ymd_order_spec boost::date_time::all_date_names_put::do_date_order() const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:296:30: warning: ‘boost::date_time::ymd_order_spec boost::date_time::all_date_names_put::do_date_order() const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:301:33: warning: ‘boost::date_time::month_format_spec boost::date_time::all_date_names_put::do_month_format() const [with Config = boost::gregorian::greg_facet_config; charT = char; OutputIterator = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/date_names_put.hpp:301:33: warning: ‘boost::date_time::month_format_spec boost::date_time::all_date_names_put::do_month_format() const [with Config = boost::gregorian::greg_facet_config; charT = wchar_t; OutputIterator = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/time_facet.hpp:272:18: warning: ‘void boost::date_time::time_facet::set_iso_format() [with time_type = boost::posix_time::ptime; CharT = char; OutItrT = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]
./boost/date_time/time_facet.hpp:276:18: warning: ‘void boost::date_time::time_facet::set_iso_extended_format() [with time_type = boost::posix_time::ptime; CharT = char; OutItrT = std::ostreambuf_iterator >]’ can be marked override [-Wsuggest-override]

BOOST_OVERRIDE was introduced in boostorg/config@ffe4e0f.

Conversion warnings C4244 in date_parsing.hpp when compiling 1.73 release candidate with VS2017

Visual Studio 2017's compiler generates multiple conversion warnings from int literals to unsigned short in the implementation of this function

inline unsigned short
    month_str_to_ushort(std::string const& s) 

warning C4244: 'initializing': conversion from '_Ty' to '_Ty2', possible loss of data
boost_fc31e493\boost\date_time\date_parsing.hpp(99): note: see reference to function template instantiation 'std::pair<const _Kty,_Ty>::pair<const char(&)[4],int,0>(_Other1,_Other2 &&) noexcept(false)' being compiled
[...]

One might just use explicit cast as in the BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX case to resolve that.

warning C4244: 'argument': conversion from 'int' to 'unsigned short', possible loss of data

C:\projects\boost-root\boost/date_time/adjust_functors.hpp(105): warning C4244: 'argument': conversion from 'int' to 'unsigned short', possible loss of data
C:\projects\boost-root\boost/date_time/adjust_functors.hpp(93): note: while compiling class template member function 'boost::gregorian::date_duration boost::date_time::month_functor<boost::gregorian::greg_durations_config::date_type>::get_neg_offset(const date_type &) const'
        with
        [
            date_type=boost::gregorian::greg_durations_config::date_type
        ]
C:\projects\boost-root\boost/date_time/date_duration_types.hpp(184): note: see reference to function template instantiation 'boost::gregorian::date_duration boost::date_time::month_functor<boost::gregorian::greg_durations_config::date_type>::get_neg_offset(const date_type &) const' being compiled
        with
        [
            date_type=boost::gregorian::greg_durations_config::date_type
        ]
C:\projects\boost-root\boost/date_time/date_duration_types.hpp(188): note: see reference to class template instantiation 'boost::date_time::month_functor<boost::gregorian::greg_durations_config::date_type>' being compiled
C:\projects\boost-root\boost/date_time/date_duration_types.hpp(187): note: while compiling class template member function 'boost::gregorian::date_duration boost::date_time::years_duration<boost::gregorian::greg_durations_config>::get_offset(const boost::gregorian::date &) const'
C:\projects\boost-root\boost/date_time/posix_time/date_duration_operators.hpp(77): note: see reference to function template instantiation 'boost::gregorian::date_duration boost::date_time::years_duration<boost::gregorian::greg_durations_config>::get_offset(const boost::gregorian::date &) const' being compiled
C:\projects\boost-root\boost/date_time/posix_time/date_duration_operators.hpp(77): note: see reference to class template instantiation 'boost::date_time::years_duration<boost::gregorian::greg_durations_config>' being compiled
C:\projects\boost-root\boost/date_time/adjust_functors.hpp(76): warning C4244: 'argument': conversion from 'int' to 'unsigned short', possible loss of data
C:\projects\boost-root\boost/date_time/adjust_functors.hpp(64): note: while compiling class template member function 'boost::gregorian::date_duration boost::date_time::month_functor<boost::gregorian::greg_durations_config::date_type>::get_offset(const date_type &) const'
        with
        [
            date_type=boost::gregorian::greg_durations_config::date_type
        ]
C:\projects\boost-root\boost/date_time/date_duration_types.hpp(189): note: see reference to function template instantiation 'boost::gregorian::date_duration boost::date_time::month_functor<boost::gregorian::greg_durations_config::date_type>::get_offset(const date_type &) const' being compiled
        with
        [
            date_type=boost::gregorian::greg_durations_config::date_type
        ]
compile-c-c++ ..\..\..\bin.v2\libs\thread\build\msvc-14.1\debug\link-static\threadapi-win32\threading-multi\win32\tss_pe.obj

J2000

We already have support for modified Julians and now I would like to add support for Julian 2000.
Will it be helpful to the community?

from_time_t(t1 + t2) gains incorrect and different results on Windows and Linux

OS: Windows 7 x64
Compilers: MSVC 2017 15.9.19, GCC 4.9.3
boost: 1.72.0

#include <boost/date_time/posix_time/posix_time.hpp>

namespace boost_ptime = boost::posix_time;

std::istringstream iss1{ "%H:%M:%S" };
iss1.imbue(std::locale(std::locale::classic(), new boost_ptime::time_input_facet("07:00:00")));
boost_ptime::ptime time_value1;
iss1 >> time_value1;

std::time_t t1 = 0;
if (!time_value1.is_not_a_date_time()) {
    t1 = boost_ptime::to_time_t(time_value1);
}

std::istringstream iss2{ "%Y-%m-%d" };
iss2.imbue(std::locale(std::locale::classic(), new boost_ptime::time_input_facet("2019-06-17")));
boost_ptime::ptime time_value2;
iss2 >> time_value2;

std::time_t t2 = 0;
if (!time_value2.is_not_a_date_time()) {
    t2 = boost_ptime::to_time_t(time_value2);
}

std::ostringstream oss;
oss.imbue(std::locale(std::locale::classic(), new boost_ptime::time_facet("%d.%m.%y %H:%M:%S")));
boost_ptime::ptime time_value3 = boost_ptime::from_time_t(t1 + t2);
oss << time_value3;

if (!oss.fail()) {
    printf("%s\n", oss.str().c_str());
}

On Windows it prints:

27.10.18 03:46:08

On Linux it crashes (sometimes not, but gains a different result):

terminate called after throwing an instance of 'boost::wrapexcept<boost::gregorian::bad_year>'
  what():  Year is out of valid range: 1400..9999

The same code over a standard library (std::get_time, std::put_time) works as expected.

formatting broken in czech (and others?)

Using boost 1.66.0 (Fedora 28, if that matters)

#include <langinfo.h>
#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/regex.hpp>


int main(int argc, char **argv) {
    namespace pt = boost::posix_time;
    pt::ptime now = pt::second_clock::local_time();
    using Facet = boost::posix_time::time_facet;
    std::stringstream ss;
    char *fmt;

    setlocale(LC_ALL, "");
    fmt = nl_langinfo(D_FMT);

    auto output_facet(new Facet(fmt));
    ss.imbue(std::locale(std::locale(), output_facet));
    ss << now;
    std::cout << ss.str() << std::endl;
}

Compile and run.

[notting@nostromo: ~]$ g++ -Wall -o test_datetime test_datetime.c  -lboost_date_time
[notting@nostromo: ~]$ LANG=cs_CZ.UTF-8 ./test_datetime 
%-d.%-m.2018

boost is not working properly in the presence of the - modifier. It also appears to ignore the O and E modifiers (used in Persian and other languages), but those at least still substitute ascii numbers properly.

Anomaly when running tests

I am seeing a strange anomaly when running date_time tests, both locally and in the regression tests. The xml serialization tests show all tests passing and yet the tests return a non-0 code indicating run-time failure. In looking at the code in testfrmwk.hpp, which prints the total results of the tests and then returns a difference between the tests run and the tests passed, the total results printout is predicated on whether tests passed != tests run or not, which shows they are equal, but the subsequent return, which is tests run - tests passed shows 3 more tests run than passed ! This suggests that something is getting overwritten in memory between one line and the next, but I have no idea why this is happening. If anybody else can trace this down it would be very helpful, since the regression tests show these tests failing across the board, where they are actually succeeding according to the test results.

boost::posix_time::microsec_clock::local_time() and boost::posix_time::second_clock::local_time() mistmatch

This code

auto loctime_1 = boost::posix_time::microsec_clock::local_time();
auto loctime_2 = boost::posix_time::second_clock::local_time();
auto seconds1 = loctime_1.time_of_day().total_seconds();
auto seconds2 = loctime_2.time_of_day().total_seconds();

I would expect seconds1 and seconds2 to be always equal assuming that loctime_1 and loctime_are called withing the same second.

On windows Embarcero Win32 clang C++ compiler I've found this to be not true when I set on Windows10 the time zone to Auckland,Wellington and the "Adjust for daylight saving time automatically" is on.

If I set "Adjust for daylight saving time automatically" off it does work. In linux it does work. Is this a bug?

Consider adding ccache for Travis cron job

Travis is configured to build Boost.DateTime every week on master and develop, the build takes 7 hours. Please consider configuring ccache.

Update: Previously overlooked and thought it is configured for every day job

date_time memory leak

Hi,
incidentally I ran into this memory leak.
Here the simple code:

try {
//Let's send in month 25 by accident and create an exception
string bad_date("20012509"); //2001-??-09
date wont_construct(from_undelimited_string(bad_date));
}
catch (std::exception& e) {
cout << " Exception: " << e.what() << endl; // memory leak!!!!!!!!
}

Exception thrown at 0x751A35D2 in TestCpp.exe: Microsoft C++ exception: boost::wrapexceptboost::gregorian::bad_month at memory location 0x0117E61C.
Detected memory leaks!
Dumping objects ->
{742} normal block at 0x014E1CA0, 4096 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
{714} normal block at 0x014CF068, 32 bytes long.
Data: < L L L > D8 EE 4C 01 D8 EE 4C 01 D8 EE 4C 01 01 00 CD CD
{713} normal block at 0x014DA330, 20 bytes long.
Data: < M M N p M > F0 A4 4D 01 F0 A4 4D 01 E0 0B 4E 01 70 A7 4D 01
{712} normal block at 0x014DA770, 16 bytes long.
Data: < 6 N > C8 36 B2 00 01 00 00 00 01 00 00 00 E0 0B 4E 01
{703} normal block at 0x014DBD88, 8 bytes long.
Data: < N > FC 0F 4E 01 00 00 00 00
{702} normal block at 0x014D9F08, 72 bytes long.
Data: < M M M > 08 9F 4D 01 08 9F 4D 01 08 9F 4D 01 01 01 CD CD
{701} normal block at 0x014DBCE0, 8 bytes long.
Data: < N > F0 0F 4E 01 00 00 00 00
{700} normal block at 0x014C6840, 48 bytes long.
Data: <@hl @hl @hl > 40 68 4C 01 40 68 4C 01 40 68 4C 01 01 01 CD CD
{699} normal block at 0x014DB848, 8 bytes long.
Data: < N > E4 0F 4E 01 00 00 00 00
{698} normal block at 0x014C76F0, 48 bytes long.
Data: < vL vL vL > F0 76 4C 01 F0 76 4C 01 F0 76 4C 01 01 01 CD CD
{695} normal block at 0x014DB8B8, 8 bytes long.
Data: < L > 9C 4C B4 00 00 00 00 00
{694} normal block at 0x014E0BE0, 1072 bytes long.
Data: < > 10 04 00 00 00 00 00 00 00 00 00 00 00 00 1A 00
{693} normal block at 0x014DB9D0, 8 bytes long.
Data: <`L > 60 4C B4 00 00 00 00 00
{692} normal block at 0x014CEED8, 32 bytes long.
Data: 68 F0 4C 01 68 F0 4C 01 68 F0 4C 01 01 01 CD CD
{691} normal block at 0x014DBC00, 8 bytes long.
Data: <TL | L > 54 4C B4 00 7C F0 4C 01
{690} normal block at 0x014DA4F0, 20 bytes long.
Data: <0 M 0 M > 30 A3 4D 01 30 A3 4D 01 CD CD CD CD CD CD CD CD
{160} normal block at 0x014C74A0, 16 bytes long.
Data: < hvL > 0C A5 B0 00 02 00 00 00 01 00 00 00 68 76 4C 01
{159} normal block at 0x014C7668, 44 bytes long.
Data: < 8 > FC A3 B0 00 00 00 00 00 38 A4 B0 00 04 A3 B0 00
{158} normal block at 0x014C78E0, 16 bytes long.
Data: < HbM > E8 A4 B0 00 02 00 00 00 01 00 00 00 48 62 4D 01
{157} normal block at 0x014D6248, 44 bytes long.
Data: < P > CC A2 B0 00 00 00 00 00 50 A3 B0 00 04 A3 B0 00
Object dump complete.

gregorian calendar day_number() uses wrong epoch

Documentation of day_number() says that:

Convert a ymd_type into a day number. The day number is an absolute number of days since the epoch start.

However, gregorian_calendar::day_number(gregorian_calendar::epoch()) is equal to 2232400. I would expect this to be zero.

The same behavior carries over to the date type. All of the following are true:

date(1400, Jan, 1).day_number() == 2232400
date(min_date_time).day_number() == 2232400
date(gregorian_calendar::epoch()).day_number() == 2232400

It's pretty strange such an issue has been unnoticed for so many years. Is it considered a bug at all? Maybe the documentation is wrong or unclear and I'm misunderstanding it?

Use constexpr in date_time

Certain of the methods in date_time would benefit from being marked constexpr.

For example, being able to use time_duration::ticks_per_second() in a constexpr context would be useful. This returns rep_type::res_adjust() which in turn seems to come from the resolution_adjust NTTP from time_resolution_traits .

Optional leading zero for the 'day of month' format specifier

The documentation for the format flags of date/time input facets state
"%d - Day of the month as decimal 01 to 31. When used to parse input, the leading zero is optional".

Does this also apply to the time input facet? The time input face code does something else:

this->m_parser.parse_day_of_month(sitr, stream_end) :

Hence, it fails to parse a date/time string of format "%m-%d-%Y %H:%M:%S", e.g. "6-5-2019 21:06:15".

Minimal example code:

wstring s = L"6-5-2019 21:06:15";

wistringstream in{ s };
in.imbue({ locale::classic(), new wtime_input_facet{L"%m-%d-%Y %H:%M:%S"} });

ptime pt;
in >> pt;
assert(!pt.is_not_a_date_time());

UBSAN: does not point to an object of type 'system_error' @ gregorian/testdate_input_facet.cpp:338

https://travis-ci.org/boostorg/date_time/jobs/597602723#L1287

/usr/include/c++/8/bits/ios_base.h:233:12: runtime error: member access within address 0x7ffce2926a20 which does not point to an object of type 'system_error'
0x7ffce2926a20: note: object is of type 'std::ios_base::failure[abi:cxx11]'
 fc 7f 00 00  48 7f 9c c0 d2 7f 00 00  a8 72 31 02 00 00 00 00  01 00 00 00 00 00 00 00  d0 00 9d c0
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'std::ios_base::failure[abi:cxx11]'
    #0 0x478f13 in std::ios_base::system_error::system_error(std::ios_base::system_error const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x478f13)
    #1 0x47935e in std::ios_base::failure[abi:cxx11]::failure(std::ios_base::failure[abi:cxx11] const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x47935e)
    #2 0x49cde0 in boost::exception_detail::error_info_injector<std::ios_base::failure[abi:cxx11]>::error_info_injector(std::ios_base::failure[abi:cxx11] const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x49cde0)
    #3 0x4985de in boost::exception_detail::enable_error_info_return_type<std::ios_base::failure[abi:cxx11]>::type boost::enable_error_info<std::ios_base::failure[abi:cxx11]>(std::ios_base::failure[abi:cxx11] const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x4985de)
    #4 0x48be10 in boost::wrapexcept<boost::exception_detail::remove_error_info_injector<std::ios_base::failure[abi:cxx11]>::type> boost::exception_detail::enable_both<std::ios_base::failure[abi:cxx11]>(std::ios_base::failure[abi:cxx11] const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x48be10)
    #5 0x479fc1 in void boost::throw_exception<std::ios_base::failure[abi:cxx11]>(std::ios_base::failure[abi:cxx11] const&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x479fc1)
    #6 0x490902 in boost::date_time::date_generator_parser<boost::gregorian::date, char>::extract_element(std::istreambuf_iterator<char, std::char_traits<char> >&, std::istreambuf_iterator<char, std::char_traits<char> >&, boost::date_time::date_generator_parser<boost::gregorian::date, char>::phrase_elements) const (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x490902)
    #7 0x481392 in boost::date_time::first_kday_before<boost::gregorian::date> boost::date_time::date_generator_parser<boost::gregorian::date, char>::get_kday_before_type<boost::date_time::date_input_facet<boost::gregorian::date, char, std::istreambuf_iterator<char, std::char_traits<char> > > >(std::istreambuf_iterator<char, std::char_traits<char> >&, std::istreambuf_iterator<char, std::char_traits<char> >&, std::ios_base&, boost::date_time::date_input_facet<boost::gregorian::date, char, std::istreambuf_iterator<char, std::char_traits<char> > > const&) const (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x481392)
    #8 0x4703f3 in boost::date_time::date_input_facet<boost::gregorian::date, char, std::istreambuf_iterator<char, std::char_traits<char> > >::get(std::istreambuf_iterator<char, std::char_traits<char> >&, std::istreambuf_iterator<char, std::char_traits<char> >&, std::ios_base&, boost::date_time::first_kday_before<boost::gregorian::date>&) const (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x4703f3)
    #9 0x4509b6 in std::basic_istream<char, std::char_traits<char> >& boost::gregorian::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, boost::date_time::first_kday_before<boost::gregorian::date>&) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x4509b6)
    #10 0x454f04 in bool failure_test<boost::date_time::first_kday_before<boost::gregorian::date>, std::ios_base::failure[abi:cxx11]>(boost::date_time::first_kday_before<boost::gregorian::date>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::ios_base::failure[abi:cxx11] const&, boost::date_time::date_input_facet<boost::gregorian::date, char, std::istreambuf_iterator<char, std::char_traits<char> > >*) (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x454f04)
    #11 0x412a16 in main ../../libs/date_time/test/gregorian/testdate_input_facet.cpp:338
    #12 0x7fd2bf4c982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #13 0x40adb8 in _start (/home/travis/build/boostorg/boost-root/bin.v2/libs/date_time/test/testdate_input_facet.test/gcc-8/debug/cxxstd-03-iso/threading-multi/undefined-sanitizer-norecover/visibility-hidden/testdate_input_facet+0x40adb8)
EXIT STATUS: 1
====== END OUTPUT ======

During builds (msvc-14.1) of Boost.Thread, warnings in DateTime

https://www.boost.org/development/tests/develop/output/teeks99-09-p-win2012R2-64on64-thread-msvc-14-1-warnings.html#test_once_lib

test_once_lib
D:\teeks99-09\run\boost_root\boost/date_time/date.hpp(71): warning C4459: declaration of 'm' hides global declaration
D:\teeks99-09\run\boost_root\boost/date_time/year_month_day.hpp(36): warning C4459: declaration of 'm' hides global declaration
D:\teeks99-09\run\boost_root\boost/date_time/gregorian_calendar.ipp(25): warning C4459: declaration of 'm' hides global declaration
D:\teeks99-09\run\boost_root\boost/date_time/gregorian_calendar.ipp(80): warning C4459: declaration of 'm' hides global declaration
D:\teeks99-09\run\boost_root\boost/date_time/gregorian_calendar.ipp(119): warning C4459: declaration of 'm' hides global declaration

minor comment edit needed

I was looking for the US parser by comment and it was confusing not to find it. Line 38 in gregorian\parsers.hpp should read 'where with order month-day-year'. And thanks for a wonderful library!

Compilation failure while building CppRestSDK

While building CppRestSDK from commit 96e7d20e398b629de2935f9ac32cfa2780cd0b0b, the build fails due to:

                 from /cpprestsdk/Release/src/http/client/http_client.cpp:16:
/boost/boost/date_time/wrapping_int.hpp: In instantiation of ‘IntT boost::date_time::wrapping_int2<int_type_, wrap_min, wrap_max>::calculate_wrap(IntT) [with IntT = int; int_type_ = short int; int_type_ wrap_min = 1; int_type_ wrap_max = 12]’:
/boost/boost/date_time/wrapping_int.hpp:126:26:   required from ‘IntT boost::date_time::wrapping_int2<int_type_, wrap_min, wrap_max>::add(IntT) [with IntT = int; int_type_ = short int; int_type_ wrap_min = 1; int_type_ wrap_max = 12]’
/boost/boost/date_time/adjust_functors.hpp:71:118:   required from ‘boost::date_time::month_functor<date_type>::duration_type boost::date_time::month_functor<date_type>::get_offset(const date_type&) const [with date_type = boost::gregorian::date; boost::date_time::month_functor<date_type>::duration_type = boost::gregorian::date_duration]’
/boost/boost/date_time/date_duration_types.hpp:67:16:   required from ‘boost::date_time::months_duration<base_config>::duration_type boost::date_time::months_duration<base_config>::get_offset(const date_type&) const [with base_config = boost::gregorian::greg_durations_config; boost::date_time::months_duration<base_config>::duration_type = boost::gregorian::date_duration; boost::date_time::months_duration<base_config>::date_type = boost::gregorian::date]’
/boost/boost/date_time/posix_time/date_duration_operators.hpp:33:37:   required from here
/boost/boost/date_time/wrapping_int.hpp:151:14: error: conversion to ‘boost::date_time::wrapping_int2<short int, 1, 12>::int_type {aka short int}’ from ‘int’ may alter its value [-Werror=conversion]
       value_ -= (wrap_max - wrap_min + 1);
       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/boost/boost/date_time/wrapping_int.hpp:156:14: error: conversion to ‘boost::date_time::wrapping_int2<short int, 1, 12>::int_type {aka short int}’ from ‘int’ may alter its value [-Werror=conversion]
       value_ += (wrap_max - wrap_min + 1);
       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors

The date_time commit is 061aec8, though the issue remains active in as many commits as I can find . . .

enhancement request local_date_time::check_dst

Release: 1.64
At date_time/local_time/local_date_time.hpp:199 we have:

        tz->dst_local_start_time(d.year()).date(),
        tz->dst_local_start_time(d.year()).time_of_day(),
        tz->dst_local_end_time(d.year()).date(),
        tz->dst_local_end_time(d.year()).time_of_day(),
        tz->dst_offset()

We did some performance evaluation and found that caching d.year(), dst_local_start_time() and dst_local_end_time() improved performance substantially.

Flaky test: if at second boundary can fail and cause CI build to fail

https://travis-ci.org/boostorg/date_time/jobs/330925380#L1373

testing.capture-output ../../bin.v2/libs/date_time/test/testmicrosec_time_clock.test/gcc-7/debug/cxxstd-03-iso/testmicrosec_time_clock.run

====== BEGIN OUTPUT ======
2018-Jan-20 01:55:59
2018-Jan-20 01:55:59.911262000
Pass :: hours match
Pass :: minutes match
Pass :: seconds match
Pass :: hours date
...failed testing.capture-output ../../bin.v2/libs/date_time/test/testmicrosec_time_clock.test/gcc-7/debug/cxxstd-03-iso/testmicrosec_time_clock.run...

Pass :: last is less
2018-Jan-20 01:55:59
2018-Jan-20 01:56:00.003424000
Pass :: hours match
FAIL :: minutes match
FAIL :: seconds match
Pass :: hours date
Pass :: last is less
2018-Jan-20 01:56:00
2018-Jan-20 01:56:00.109788000
Pass :: hours match
Pass :: minutes match
Pass :: seconds match
Pass :: hours date
Pass :: last is less

time_duration inefficient compared to ptime and gregorian::date

compile this program:

#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <iostream>
#include <vector>
#include <chrono>

using namespace boost::posix_time;
using namespace boost::gregorian;
using namespace std;

int main(int argc, char *argv[])
{
  const int64_t count = 1000000;

  {
    vector<time_duration> v;
    v.reserve(count);
    for (int64_t i=0; i<count; ++i) v.push_back(seconds(i));

    auto start = chrono::high_resolution_clock::now();
    sort(v.begin(), v.end());
    auto finish = std::chrono::high_resolution_clock::now();
    cout << "time_duration sort: " << chrono::duration<double>(finish - start).count() << "s\n";
  }

  {
    vector<int64_t> v;
    v.reserve(count);
    for (int64_t i=0; i<count; ++i) v.push_back(i);

    auto start = chrono::high_resolution_clock::now();
    sort(v.begin(), v.end());
    auto finish = std::chrono::high_resolution_clock::now();
    cout << "int64_t sort: " << chrono::duration<double>(finish - start).count() << "s\n";
  }

  {
    vector<date> v;
    v.reserve(count);
    date d(1400,1,1);
    for (int64_t i=0; i<count; ++i) {
      v.push_back(d);
      d+=date_duration(1);
    }

    auto start = chrono::high_resolution_clock::now();
    sort(v.begin(), v.end());
    auto finish = std::chrono::high_resolution_clock::now();
    cout << "date sort: " << chrono::duration<double>(finish - start).count() << "s\n";
  }

  {
    vector<ptime> v;
    v.reserve(count);
    ptime p(date(1400,1,1));
    for (int64_t i=0; i<count; ++i) {
      v.push_back(ptime(p));
      p+=hours(5)+minutes(4)+seconds(3);
    }

    auto start = chrono::high_resolution_clock::now();
    sort(v.begin(), v.end());
    auto finish = std::chrono::high_resolution_clock::now();
    cout << "ptime sort: " << chrono::duration<double>(finish - start).count() << "s\n";
  }

  return 0;
}

program output on my machine:

time_duration sort: 3.60364s
int64_t sort: 0.560309s
date sort: 0.610657s
ptime sort: 1.36204s

the question is, what is so special about time_duration making it so unbelievably inefficient? it is even more inefficient than ptime!

gregorian::date/date_time deserialized via exception handling

The deserialization of boost::gregorian::date in greg_serialize.hpp relies on exception handling ("catch(bad_lexical_cast&") for deserializing "special" values, which causes unnecessary delays in the typical case of deserializing uninitialized datetime values.

gcc9 c++2a Wdeprecated-copy -- implicity declared operator= for date_duration, date, and friends

Some warnings from develop with gcc9 in 2a mode.

Warnings: teeks99-dkr-dg9-warn - date_time / gcc-9c++2awarn
Rev b44058fda48dd994d394d4483472a7abe55031b8 / Sun, 22 Mar 2020 01:13:31 +0000
testdate_duration

../libs/date_time/test/gregorian/testdate_duration.cpp:44:22: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]

testdate_input_facet

../boost/date_time/date_facet.hpp:509:23: warning: implicitly-declared 'boost::date_time::period_parser<boost::gregorian::date, char>& boost::date_time::period_parser<boost::gregorian::date, char>::operator=(const boost::date_time::period_parser<boost::gregorian::date, char>&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/date_facet.hpp:550:19: warning: implicitly-declared 'boost::date_time::special_values_parser<boost::gregorian::date, char>& boost::date_time::special_values_parser<boost::gregorian::date, char>::operator=(const boost::date_time::special_values_parser<boost::gregorian::date, char>&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/date_facet.hpp:635:12: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/date_facet.hpp:638:12: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]

testgenerators

../boost/date_time/date_generators.hpp:463:11: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/date_generators.hpp:481:11: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]

testgreg_serialize

../boost/date_time/gregorian/greg_serialize.hpp:121:6: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]

testgreg_serialize_xml

../boost/date_time/gregorian/greg_serialize.hpp:121:6: warning: implicitly-declared 'constexpr boost::gregorian::date_duration& boost::gregorian::date_duration::operator=(const boost::gregorian::date_duration&)' is deprecated [-Wdeprecated-copy]

testlocal_time_iterator

../boost/date_time/time_iterator.hpp:30:16: warning: implicitly-declared 'boost::local_time::local_date_time_base<>& boost::local_time::local_date_time_base<>::operator=(const boost::local_time::local_date_time_base<>&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/time_iterator.hpp:25:16: warning: implicitly-declared 'boost::local_time::local_date_time_base<>& boost::local_time::local_date_time_base<>::operator=(const boost::local_time::local_date_time_base<>&)' is deprecated [-Wdeprecated-copy]

testlocal_time_period

../boost/date_time/period.hpp:176:12: warning: implicitly-declared 'boost::local_time::local_date_time_base<>& boost::local_time::local_date_time_base<>::operator=(const boost::local_time::local_date_time_base<>&)' is deprecated [-Wdeprecated-copy]
../boost/date_time/period.hpp:177:12: warning: implicitly-declared 'boost::local_time::local_date_time_base<>& boost::local_time::local_date_time_base<>::operator=(const boost::local_time::local_date_time_base<>&)' is deprecated [-Wdeprecated-copy]

Retire built-in and aging time zone database in favor of using IANA

Problem

If you apply timezone to a time in the past and that timezone changed the timezone specification to behave differently after a certain point, the existing timezone database does not encapsulate the older formats. Therefore the result is wrong for times in the past where that timezone changed rules.

Solution

The IANA time zone database is the most complete database available:

https://www.iana.org/time-zones

They have data, code, or combined releases. Their time zone information contains the start and end time for each zone change - something that the built-in csv file in the data directory does not have.

Recommend retiring the built-in time zone database in favor of using the IANA database and modifying the time zone code to apply time zones based on the valid time ranges for those zones. Sounds like a fair amount of work.

Background

https://svn.boost.org/trac10/ticket/10087
https://svn.boost.org/trac10/ticket/596

warning in to_time_t when std::time_t is 32-bit

I have 32-bit std::time_t and boost 1.67 installed
Visual Studio gives me warning C4244: 'return': conversion from '__int64' to 'time_t', possible loss of data
at boost\date_time\posix_time\conversion.hpp
The warning is raised at boost::posix_time::to_time_t
May be wrap return statement by static_caststd::time_t ? Is it safe enough?

Unnecessary runtime dependency to Library induced by boost::gregorian::greg_month

Environment

Boost Version: 1.70
Compiler: Visual Studio 2017 – 15.9.12
OS: Windows 10

Steps to reproduce:

  1. Install boost-date-time via vcpkg
  2. Create Windows Console Project and integrate vcpkg packages
  3. Use the following testfile
#include "pch.h"
#include <boost/date_time/gregorian/greg_month.hpp>
int main()
{
    boost::gregorian::greg_month m(1);
    return 0;
}
  1. Compile.program

Expected behavior:

The resulting file should have no references to the boost dll.

Observed behaviour:

The resulting file has a reference:

dumpbin /nologo /imports:boost_date_time-vc141-mt-gd-x32-1_70.dll DateTimeLinkDependency.exe

Dump of file DateTimeLinkDependency.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    boost_date_time-vc141-mt-gd-x32-1_70.dll
                41B0E0 Import Address Table
                41B328 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                    2 ??0greg_month@gregorian@boost@@QAE@G@Z

Temporary fix:

Change in boost\date_time\gregorian\greg_month.hpp:

From

class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep {

to

class BOOST_SYMBOL_VISIBLE greg_month : public greg_month_rep {

after that:

Dump of file DateTimeLinkDependency.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

  Summary

        1000 .00cfg
        1000 .data
        1000 .idata
        1000 .msvcjmc
        4000 .rdata
        1000 .reloc
        1000 .rsrc
        D000 .text
       10000 .textbss

Impact

All our programs using date_time::gregorian::date must be accompanied by the date_time dll.

The behavior seems a little bit similar to #34!?

Best regards
Sönke

header-only date_time breaks Wave build

Wave, and perhaps other Boost libraries, attempt to link against date_time. New CI builds for those libraries are failing. Could there be a provision for a helpful error message, or perhaps a "stub" library similar to the one provided for System?

make date_time all inline

This change completely removes the library from date-time in all compiler modes from 98 to 20. In large part the library remains feature intact with the exception of the removal of the pre 133 facet support (see issue #61). This brings a number of benefits:

  • no need for users to build and link library
  • gregorian and posix_time are no longer dependent on shared_ptr
  • test code is radically simplified and executes faster
  • facilitates constexpr support ( also now added - see issue #123 )

The test code has been updated to minimize support on legacy, non streams based io. In addition, all the variations of dll versus static are no longer required which reduces the number of tests and the time to run.

C++20 ambiguous comparison operator warning with clang 10

Hi,

When using C++20 with clang >= 10, we get the following warnings:

#include "boost/date_time.hpp"

bool f()
{
    return boost::posix_time::ptime(boost::gregorian::date(2028, 4, 17)) == boost::posix_time::ptime(boost::gregorian::date(2028, 4, 17));
}
<source>:5:74: error: ISO C++20 considers use of overloaded operator '==' (with operand types 'boost::posix_time::ptime' and 'boost::posix_time::ptime') to be ambiguous despite there being a unique best viable function [-Werror,-Wambiguous-reversed-operator]
    return boost::posix_time::ptime(boost::gregorian::date(2028, 4, 17)) == boost::posix_time::ptime(boost::gregorian::date(2028, 4, 17));
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/celibs/boost_1_71_0/boost/date_time/time.hpp:126:10: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
    bool operator==(const time_type& rhs) const
         ^
1 error generated.
Compiler returned: 1

See a live example on compiler explorer: https://godbolt.org/z/6yYb7C

Do you know how to fix this ?

Cheers,
Romain

MSVC build failures: `special_value_from_string` redefinition

Current develop (revision 4a46476) fails to compile with any MSVC version, as can be seen here:

.\boost/date_time/gregorian/parsers.hpp(26) : error C2375: 'boost::gregorian::special_value_from_string' : redefinition; different linkage
        .\boost/date_time/gregorian/greg_month.hpp(142) : see declaration of 'boost::gregorian::special_value_from_string'

Remove the link library to resolve linking/visibility concerns

The link library can cause problems, for example:

#34
also the mailing list topic of "[boost] [all] Request for out of the box visibility support".

By removing the link library entirely this issue goes away. In my discussion with Jeff Garland, the original author:

If you look carefully at what is going on in the .cpp files it’s basically for standard string conversion support for things like months. So greg_month supports things like to_long_string() which need to take a ‘1’ and convert it into ‘January’. Anyway, there’s a few places in the library that this is used which would have to be replaced by a header compatible implementation.

For example see line 67 here.
https://github.com/boostorg/date_time/blob/develop/include/boost/date_time/date_parsing.hpp

Anyway, the c++98 compatible solutions can already be found in the library — you just need to make the statics part of a template — here’s one of the examples from the facet code — it’s a bit strange but it works. The facets have been header only since they came into the library.

https://github.com/boostorg/date_time/blob/develop/include/boost/date_time/date_names_put.hpp
//part of a template...
static const char_type default_special_value_names[3][17];

template<class Config, class charT, class OutputIterator>
const typename date_names_put<Config, charT, OutputIterator>::char_type
date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
{'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
{'-','i','n','f','i','n','i','t','y'},
{'+','i','n','f','i','n','i','t','y'} };

Anyway hope that helps

to_posix_string() returns invalid timezone string

The following code
tz_database tz_db; tz_db.load_from_file("./date_time_zonespec.csv"); time_zone_ptr nyc = tz_db.time_zone_from_region("Europe/Stockholm"); auto s = nyc->to_posix_string(); setenv("TZ", s.c_str(), 1);
will set TZ to "CET+01CEST+01,M3.5.0/02:00,M10.5.0/03:00" which will cause Stockholm local time to be 10:00:00 when UTC(GMT/London) time is 11:00:00 which clearly is incorrect.

ANSI/IEEE Std 1003.1 section 8.3 Other Environment Variables reads for TZ variable

Offset Indicates the value added to the local time to arrive at Coordinated Universal Time

gnu.org reads the same
It also says regarding offset

This is positive if the local time zone is west of the Prime Meridian and negative if it is east.

But Boost 1.69 date-time says

A posix_time_zone is unique in that the object is created from a Posix time zone string (IEEE Std 1003.1). A POSIX time zone string takes the form of:
"std offset dst [offset],start[/time],end[/time]" (w/no spaces).
'std' specifies the abbrev of the time zone. 'offset' is the offset from UTC.
"PST-8PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"
"PST-8PDT,M4.1.0,M10.1.0"
These two are actually the same specification (defaults were used in the second string). This zone lies eight hours west of GMT …”

If I add -8 to a PST local time I will NOT get GMT=UTC time!! It seems like somewhere here (most likely in to_posix_string()) is a huge bug since the Posix/GNU and Boost interpretation of the Posix timezone strings contradict each other.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.