Preventing network call while calling `date::make_zoned()`

Viewed 52

While connected to the web, the following program, which converts a given std::chrono::system_clock::time_point to a string, takes a whopping 1s32ms to complete. However, if my machine is not connected to the web, the program requires a reasonable 54ms.

#include "date/tz.h" // Howard Hinnant's date library
#include <chrono>
#include <iostream>

std::string tp2str(const std::chrono::system_clock::time_point &tp,
                                 const std::string &tz) {
    auto z = date::make_zoned(tz, tp);
    return date::format("%Y-%m-%d %H:%M:%S %Z (%A)", z);
}

int main() {
    const auto now = std::chrono::system_clock::now();
    std::cout << tp2str(now, "US/Eastern") << std::endl;
}

Examining the profiler output while connected reveals that the delay is on account of the function sequence date::remote_version ... Curl_http_connect which presumably attempts to connect to a remote web host.

Is there a way to prevent this behaviour while calling date::make_zoned() while still being connected to the web?

2 Answers

The documentation for Howard Hinnant's date library explains remote_version(), explains what it is for, and how to turn it off. I'll quote from the documentation:

The following functions are available only if you compile with the configuration macro HAS_REMOTE_API == 1. Use of this API requires linking to libcurl. AUTO_DOWNLOAD == 1 requires HAS_REMOTE_API == 1. You will be notified at compile time if AUTO_DOWNLOAD == 1 and HAS_REMOTE_API == 0. If HAS_REMOTE_API == 1, then AUTO_DOWNLOAD defaults to 1, otherwise AUTO_DOWNLOAD defaults to 0. On Windows, HAS_REMOTE_API defaults to 0. Everywhere else it defaults to 1. This is because libcurl comes preinstalled everywhere but Windows, but it is available for Windows.

None of these are available with USE_OS_TZDB == 1.

Most likely, you want to add a compile-time definition USE_OS_TZDB=1 to your build.

In case someone's interested in the CMakeLists.txt, here's what works for me:

cmake_minimum_required(VERSION 3.22)
project(date_test)

cmake_policy(SET CMP0077 NEW)

include( FetchContent )
FetchContent_Declare( date
        GIT_REPOSITORY https://github.com/HowardHinnant/date.git
        GIT_TAG        v3.0.1
        )
set( BUILD_TZ_LIB ON CACHE INTERNAL "build/install of TZ library")
set( USE_SYSTEM_TZ_DB ON CACHE INTERNAL "Use the operating system's timezone database" )
FetchContent_MakeAvailable(date)

set(CMAKE_CXX_STANDARD 20)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries (${PROJECT_NAME} PRIVATE date-tz)

where note the overrides for BUILD_TZ_LIB and USE_SYSTEM_TZ_DB cmake variables set in the CMakeLists.txt of the date repo.

Related