Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run time specification of tzdb location with environment variable #788

Open
samuel-emrys opened this issue Jun 18, 2023 · 3 comments · May be fixed by #807
Open

Run time specification of tzdb location with environment variable #788

samuel-emrys opened this issue Jun 18, 2023 · 3 comments · May be fixed by #807

Comments

@samuel-emrys
Copy link

Hi Howard/all,

Summary

To facilitate package management, I think it would be very useful to add an environment variable specifying the location of either a binary or a source database, which is read at runtime to discover the location of the database. This has the following benefits:

  • Allows a user to keep their timezone database up to date without considering re-compilation
  • Allows a user to be flexible about where the timezone database is stored
  • Allows date to be used portably without compilation of paths into the resulting library (when not used as header only)

Context

I'm currently in the process of uplifting the conan date package to use the newly added tz package, which packages the tzdb. Currently it only supports a binary package, but can be uplifted to also package the source distribution.

The challenge I'm facing is that conan stores it packages in the conan cache, ~/.conan/p. Conan provides the facilities to make these packages available at runtime to consumer libraries via environmental scripts, which would be a convenient way to manage the tzdb to ensure that it remains modern, and distribute it with software releases. The challenge is that there doesn't seem to be a flexible way to tell date that this is where the tzdb lives.

To illustrate this, I thought I'd enumerate the ways that currently exist to customise tzdb location and talk about why these are unsuitable from a packaging perspective.

USE_SYSTEM_TZ_DB=1

  • This will set AUTO_DOWNLOAD=0 and HAS_REMOTE_API=0 to ensure that what's available locally is used
  • Will also set INSTALL=. and USE_OS_TZDB=1, which will use the compiled variant of tzdb in the system installation location
  • From a package management perspective, this does most of the right things, except that it doesn't appear as though I can define the location of the database. It looks specifically at the following locations, as far as I can tell:
    • /usr/share/zoneinfo
    • /usr/share/zoneinfo/uclibc
    • /var/db/timezone/zoneinfo
    • /etc/localtime

The problem for package management

Because the location of the database can't be defined, it's not possible to use this to point at a portable version of a compiled database in a custom location.

I could look at attempting to install tzdb from conan into the system locations here, but I don't feel this would be wise - this is the domain of system package management and I'm not sure what effect this would have on system package managers.

MANUAL_TZ_DB=1

  • This will set AUTO_DOWNLOAD=0 and HAS_REMOTE_API=0 to ensure that what's available locally is used
  • Will also set USE_OS_TZDB=0 to ensure that the system database is not used, if present
  • This expects the user will either:
    • invoke set_install(const std::string& s) in their code to set the location of the database. My assumption is that this refers to a source database only, and this can't be configured for a binary database.
    • Pass a value to INSTALL= when compiling, which means that ${INSTALL}/tzdata is searched for the source database
    • Populate ~/Downloads/tzdata themselves

The problem for package management

  • Relies on the user to set something that can be reasonably captured as a property of the date recipe - adds additional boilerplate
  • Only allows setting for a source version of the database
  • If the user actually specifies a path here, this would create a non-portable binary because it contains a path unlikely to exist in the deployment environment

MANUAL_TZ_DB=0 and USE_SYSTEM_TZ_DB=0

  • Will set AUTO_DOWNLOAD=1, HAS_REMOTE_API=1, USE_OS_TZDB=0
  • Will add a dependency on curl and attempt to download the latest version of the database src to ~/Downloads/tzdata

The problem for package management

Offloads management of tzdata as a dependency to the date library, rather than managed by the dependency (package) manager. Not a problem in and of itself, but orthogonal to the philosophy of using a package manager to manage dependencies.

Related issues

Customisation/management of these locations seems like an oft-requested feature:

These seem to have been stagnant for a few years now - in particular #611 seems to be the closest to what would be required here. Is there any intention to add this kind of customisation to the date library or is this kind of thing not being considered now that there's been acceptance of this into stdlib?

@samuel-emrys
Copy link
Author

@HowardHinnant do you have any thoughts on whether this can be supported?

@HowardHinnant
Copy link
Owner

I'm sure it could be. I don't have the time to do it, or even to review someone else's work. Plus I am encouraging migration off of this library to C++20 chrono. I know that implementations are lagging, but MSVC is up to date, and gcc will be with gcc-14. Adding this feature (which does not exist in C++20 chrono) would hamper such migration.

I would have no objection whatsoever to someone forking this repository and providing this functionality on their own fork. I'd even be willing to link to it on my readme.

@samuel-emrys
Copy link
Author

samuel-emrys commented Dec 7, 2023

No problems, thanks for providing your position. I'll see if I can put some time into an implementation of this - I think the easiest way for me to handle this would be to submit a PR against this repo and use that as a patch for the conan recipe. Appreciate you may not have time to review and it sounds like acceptance might be counter to your aims of promoting chrono migration; if that position doesn't change then anybody who wants to use the patch they can use my fork (or, hopefully the conan package).

As for the migration - I'm fully on board with a desire to move to chrono and will as soon as it satisfies my requirements. The following are currently my blockers:

  • I can't use C++20 for all of the projects in which I require the date features
  • Many of the projects I work on require multi-compiler/compiler version/operating system compatibility, so if the functionality is present on Windows but not macOS or Linux, then I'm constrained to the lowest common denominator.

So, until the relevant chrono implementations reach sufficient maturity to unblock the above, there will still be a use case for using date for us.

samuel-emrys added a commit to samuel-emrys/date that referenced this issue Jan 13, 2024
…iable

This adds the ability for a user to populate the TZDATA environment
variable to specify the location in which to look for the timezone
database, which allows for a runtime query of this location. Without
this, date currently only supports compile time determination of the
database location.

This facilitates the ability to:
* Use a timezone database provided by a package manager
* Keep the timezone database up to date without re-compilation
* Be flexible about where the timezone database is stored

Closes HowardHinnant#788
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants