2011-01-28 32 views
6

Tôi muốn chuyển một số boost::posix_time::ptime qua mạng dưới dạng boost::int64_t. Theo số A way to turn boost::posix_time::ptime into an __int64, tôi có thể dễ dàng xác định epoch riêng của mình và chỉ chuyển số time_duration từ tham chiếu epoch đó dưới dạng số nguyên 64 bit. Nhưng làm cách nào để chuyển đổi lại thành ptime?Chuyển đổi int64_t thành time_duration

#include <iostream> 
#include <cassert> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time/gregorian/greg_month.hpp> 

using namespace std; 

using boost::posix_time::ptime; 
using boost::posix_time::time_duration; 
using boost::gregorian::date; 

int main(int argc, char ** argv){ 
    ptime t = boost::posix_time::microsec_clock::local_time(); 

    // convert to int64_t 
    ptime myEpoch(date(1970,boost::gregorian::Jan,1)); 
    time_duration myTimeFromEpoch = t - myEpoch; 
    boost::int64_t myTimeAsInt = myTimeFromEpoch.ticks(); 

    // convert back to ptime 
    ptime test = myEpoch + time_duration(myTimeAsInt); 

    assert(test == t); 
    return 0; 
} 

Điều này không hoạt động vì công cụ xây dựng 01 số đếm là đối số riêng tư. Tôi cũng quan tâm đến bất kỳ cách nào khác để chỉ đơn giản chuyển rằng ptime qua các loại dữ liệu đơn giản.

+1

Giá trị trả về bằng dấu() có thể di chuyển giữa các máy không? Bạn có thể cần phải sử dụng ticks_per_second() để bình thường hóa nó. Nếu myEpoch giống nhau ở cả hai đầu, tại sao bạn không thể chuyển dấu thời gian epoch giây 64 bit? – hplbsh

+0

Nó hoạt động với độ phân giải mili giây. Bạn có thể đăng bình luận của mình làm câu trả lời không? – tibur

Trả lời

5

giải pháp Làm việc với độ phân giải millisecond:

int main(int argc, char ** argv){ 
    ptime t = boost::posix_time::microsec_clock::local_time(); 

    // convert to int64_t 
    ptime myEpoch(date(1970,boost::gregorian::Jan,1)); 
    time_duration myTimeFromEpoch = t - myEpoch; 
    boost::int64_t myTimeAsInt = myTimeFromEpoch.total_milliseconds(); 

    // convert back to ptime 
    ptime test = myEpoch + boost::posix_time::milliseconds(myTimeAsInt); 

    cout << test << endl; 
    cout << t << endl; 

    time_duration diff = test - t; 

    assert(diff.total_milliseconds()==0); 
    return 0; 
} 

Cảm ơn 12a6.

+3

Tôi không nghĩ rằng câu trả lời này hoạt động cho các hệ thống 32 bit. Tôi đã thử điều này trên một hệ thống 32 bit sử dụng một kỷ nguyên của 1901-01-01 00:00:00 và nó sẽ không hoạt động. Rõ ràng nó hoạt động cho bạn nhưng đối số 'milliseconds()' là kiểu dài và trả về từ 'total_milliseconds()' cũng là kiểu dài nên bạn không bị mất bất cứ thứ gì trong đoạn mã ngầm từ int64_t đến dài. – mathematician1975

+0

Điều này chỉ hoạt động trên các trình biên dịch có thời lượng dài 64 bit bất kể nền tảng. Trong MSVC 32 bit, dài 32 bit. –

2

trình với bất cứ điều gì max độ phân giải thư viện boost::datetime của bạn được biên dịch để (thường là micros/nanos):

time_duration time_duration_from_ticks(time_duration::tick_type ticks) 
{ 
    return time_duration(
     0,           // hours 
     0,           // minutes 
     ticks/time_duration::ticks_per_second(), // seconds 
     ticks % time_duration::ticks_per_second()); // fractional_seconds 
} 

(Lưu ý rằng time_duration::tick_typeint64_tnếu bạn đã thiết lập tăng datetime của bạn với độ phân giải micro giây mà thôi, đó là mặc định)

+1

Nhưng, đối số 'giây' phải là 32 bit trên trình biên dịch VS2013 của Windows 7 của tôi. Vì vậy, vấn đề 2038 vẫn tồn tại với giải pháp này. –

+0

Tôi phải là câm, nhưng tôi không thấy lý do tại sao nó phải là 32 bit -'ticks' sẽ là 64 bit (ngay cả trên 32 bit vòm). –

+2

Nếu bạn nhìn vào hàm tạo cụ thể này cho 'time_duration', bạn sẽ thấy rằng tham số thứ ba được định nghĩa là 32 bit. Trong thực tế, tôi đã sử dụng constructor này và ngày tháng là sai - chính xác như là một trong những mong chờ cho năm 2038 vấn đề. Tuy nhiên, nó có thể được thực hiện đơn giản và tránh các vấn đề 2038 bằng cách sử dụng mili giây; xem http://stackoverflow.com/a/26211377/368896 để có câu trả lời. –

0

với độ phân giải micro TIME_DURATION:.

boost::posix_time::microseconds(_ts/TICKS_PER_MICROSECOND) 

nơi TICKS_PER_MICROSECOND là số lượng bọ ve trên mỗi micro giây (ví dụ: 10 nếu ve là hectonan giây, như trong Windows FILETIME).

Lý do tại sao hàm tạo mili giây dường như hoạt động đối với một số người là nó chấp nhận kiểu tham số dài, là 64 bit trong một số trình biên dịch. Trong MSVC, nó là 32 bit trên nền tảng 32 bit, vì vậy nó sẽ không hoạt động. Các nhà xây dựng micro giây chấp nhận một số nguyên 64 bit, mà nên là "đủ cho tất cả mọi người".

Các vấn đề liên quan