rysto
rysto

Reputation: 11

Boost.DateTime: How do I create a local_date_time representing today in a arbitrary timezone at a specific time?

I am using Boost.DateTime and I need to create a local_date_time object representing the current date in a particular time zone, at a specific time. It is important to note that this time will not necessarily be either UTC or the system time zone. I need this code to work with an arbitrary time zone.

For example, if it is currently Jan 10 2025 23:30:00 in the America/New_York time zone, I might want to create a local_time object representing that date at 16:30 (so I should get the date Jan 10 2025 16:30:00). If one hour passes and the current date/time because Jan 11 2025 00:30:00, then the same algorithm and target time should result in the date/time object Jan 11 2025 16:30:00.

I have not been able to come up with a way of accomplishing this is Boost.DateTime that isn't ridiculous. The obvious path would seem to be to use boost::local_time::local_sec_clock() to get the current date/time in my chosen time zone, and then construct a new local_date_time object with the date component of local_sec_clock and my chosen time:

local_date_time TodayAtTime(time_zone_ptr timezone, time_duration targetTime)
{
  local_date_time now = local_sec_clock::local_time(timezone);
  return local_date_time(now.date(), targetTime, timezone, local_date_time::EXCEPTION_ON_ERROR);
}

The above fails, however, as local_date_time::date() appears to returns today's date in UTC, not in the timezone associated with the local_date_time object. This godbolt link demonstrates the problem:

https://godbolt.org/z/j3acfznos

The only viable method I have found so far is to serialize now to a std::ostringstream, parse the string to find the year, month and day, and use that to construct the local_date_time. That is a ridiculously convoluted method, however. Surely there is a way to achieve what I need natively in the Boost.DateTime API?

Upvotes: 0

Views: 42

Answers (1)

Nimrod
Nimrod

Reputation: 3553

The key point is to get the local date, considering using UTC offset and daylight saving time(if applicable). The code is as follows,

const auto utcTime = baseDate.utc_time();
auto localPTime = utcTime + baseDate.zone()->base_utc_offset();

if (baseDate.zone()->has_dst()) {
    localPTime += baseDate.zone()->dst_offset();
}
date localDate = localPTime.date();

Demo

Upvotes: 0

Related Questions