boost:从当前时区获取当前local_date_time

时间:2012-01-05 17:27:26

标签: c++ boost timezone boost-date-time

问题是:

  • 我知道如何获得当地时间的提升

代码:

    boost::local_time::local_date_time currentTime(
        boost::posix_time::second_clock::local_time(),
        boost::local_time::time_zone_ptr());
    std::cout << currentTime.local_time() << std::endl;
  • 我知道如何从机器获取当前时区数据(我希望它是正确的方式)

代码:

tzset();
// the var tzname will have time zone names
// the var timezone will have the current offset
// the var daylight should show me if there is daylight "on"

但我仍然无法使用当前time_zone获取local_date_time ...有人知道,怎么做?

3 个答案:

答案 0 :(得分:1)

好的,至于现在我还是不知道答案的全部内容

但是有代码可以帮助打印当前时区偏移量

(基于此处相关问题的答案(stackoverflow)和一些内部增强代码)

我绝对不确定它能在所有机器上正常工作,但现在它总比没有好:

boost::posix_time::time_duration getUtcOffset(const boost::posix_time::ptime& utcTime)
{
    using boost::posix_time::ptime;
    const ptime localTime = boost::date_time::c_local_adjustor<ptime>::utc_to_local(utcTime);
    return localTime - utcTime;
}

std::wstring getUtcOffsetString(const boost::posix_time::ptime& utcTime)
{
    const boost::posix_time::time_duration td = getUtcOffset(utcTime);
    const wchar_t fillChar = L'0';
    const wchar_t timeSeparator = L':';

    std::wostringstream out;
    out << (td.is_negative() ? L'-' : L'+');
    out << std::setw(2) << std::setfill(fillChar)
        << boost::date_time::absolute_value(td.hours());
    out << L':';
    out << std::setw(2) << std::setfill(fillChar)
        << boost::date_time::absolute_value(td.minutes());
    return out.str();
}
int main()
{
    const boost::posix_time::ptime utcNow =
        boost::posix_time::second_clock::universal_time();

    const std::wstring curTimeOffset = getUtcOffsetString(utcNow);
    std::wcout << curTimeOffset.c_str() << std::endl;  // prints  -05:00  on my comp 
}

答案 1 :(得分:1)

由于您说您有时区信息,唯一的问题是如何使用boost来格式化您需要的字符串。以下是示例代码:

  using namespace boost::local_time;
  using namespace boost::posix_time;

  // Composing this string is the most tricky part. Syntax see in:
  // boost\date_time\local_time\posix_time_zone.hpp
  string posix_tz_def("PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00");
  local_date_time ldt(second_clock::local_time(),
                      time_zone_ptr(new posix_time_zone(posix_tz_def)));

  std::stringstream ss;
  local_time_facet* output_facet = new local_time_facet();
  ss.imbue(std::locale(std::locale::classic(), output_facet));
  output_facet->format("%Y-%m-%dT%H:%M:%S %Q");
  ss << ldt;

  string formatted_datetime = ss.str();  // 2012-01-05T18:14:06 -05:00

在这种方法中,最有问题的部分是posix时区字符串。我认为每个时区都应该有包含这些字符串的数据库,而boost提供了一个用于处理.csv文件的模板。如果你需要的唯一东西是在字符串中偏移,只需将DTS设置为0:00:00,而不关心其余部分。例如,使用此字符串:PST-5:30PDT0,0,365(永远PDT,移位0)。用你需要的偏移代替“-5:00”。

尽管如此,C ++ / boost方式将通过派生date_time::time_zone_base来实现自己的时区提供程序。

可以找到更多样本和想法here

答案 2 :(得分:0)

所以,如果你还需要获得正确的UTC偏移量,那么我应该稍微修改一下,以产生正确的时区字符串:

static boost::posix_time::time_duration utc_offset(
    second_clock::local_time() - second_clock::universal_time());
std::ostringstream ss_posix_tz_def;
// We don't care about real zone name so, just put any three letters.
ss_posix_tz_def << "LOC" << utc_offset;
string posix_tz_def = ss_posix_tz_def.str();

另一种解决方案是编写一个全新的时区提供程序。就像这个简单的一样:

// We assume local TZ doesn't have DST, UTC offset is calculated basing on
// local system clocks. Thus, using of this provider for time calculations for
// an arbitrary date is not a good idea.
class machine_time_zone : public boost::local_time::custom_time_zone {
 public:
  typedef boost::local_time::custom_time_zone base_type;
  typedef base_type::time_duration_type time_duration_type;

  machine_time_zone()
    : boost::local_time::custom_time_zone(
        time_zone_names("Local machine TZ", "LOC", "", ""),
        GetUTCOffset(),
        boost::local_time::dst_adjustment_offsets(
            time_duration_type(0, 0, 0),
            time_duration_type(0, 0, 0), time_duration_type(0, 0, 0)),
        boost::shared_ptr<boost::local_time::dst_calc_rule>()) {
  }

  // This method is not precise, real offset may be several seconds more or less.
  static const boost::posix_time::time_duration& GetUTCOffset() {
    using boost::posix_time::second_clock;
    static boost::posix_time::time_duration utc_offset(
      second_clock::local_time() - second_clock::universal_time());
    return utc_offset;
  }
};

在构建local_date_time时传递它:

local_date_time ldt(second_clock::local_time(),
                    time_zone_ptr(new machine_time_zone()));