2012-02-10 32 views
8

Tôi có dấu thời gian epoch phân số, được biểu thị là double, mà tôi muốn chuyển đổi thành std::chrono::time_point thích hợp. Kỷ nguyên là kỷ nguyên UNIX thông thường kể từ 1/1/1970. Tôi biết rằng có tồn tại std::chrono::system_clock::from_time_t, nhưng một time_t không có một phần phân đoạn. Điều gì sẽ là cách tốt nhất để làm điều này với C++ 11 có nghĩa là gì?Làm thế nào để chuyển đổi một dấu thời gian epoch phân đoạn (đôi) thành một tiêu chuẩn :: chrono :: time_point?

Câu hỏi này có liên quan đến unix timestamp to boost::posix_time::ptime, ngoại trừ việc yêu cầu phiên bản C++ 11 thay vì phiên bản Boost của nó.

+0

Bạn đã đọc qua [N2661] (http://www.open-std.org/jtc1/sc22/ wg21/docs/papers/2008/n2661.htm)? – ildjarn

+0

"(...) dấu thời gian epoch phân số, được biểu thị bằng' double' "Đơn vị nào? Bạn có biết thời đại? –

+0

@ R.MartinhoFernandes: đó là kỷ nguyên UNIX chuẩn kể từ 1/1/1970. – mavam

Trả lời

12

Giả sử kỷ nguyên giống như loại clock đã biết, bạn có thể sử dụng thời lượng với đại diện double và chuyển đổi thành thời lượng được đồng hồ sử dụng.

// change period to appropriate units - I'm assuming seconds 
typedef std::chrono::duration<double, std::ratio<1>> d_seconds; 

d_seconds since_epoch_full(324324.342); 
auto since_epoch = std::chrono::duration_cast<clock::duration>(since_epoch_full); 
clock::time_point point(since_epoch); 

Điều này sẽ ổn cho bất kỳ phép tính nào liên quan đến đồng hồ đó, vì bạn sử dụng cùng độ chính xác như đồng hồ nhưng có thể mất một số độ chính xác trong chuyển đổi. Nếu bạn không muốn mất rằng bạn sẽ phải sử dụng chuyên môn time_point sử dụng loại thời lượng dựa trên double đó. Và sau đó sử dụng nó trong tính toán của bạn (tất nhiên, với tất cả các caveats của toán học dấu chấm động).

typedef std::chrono::time_point<clock, d_seconds> d_time_point; 

Tuy nhiên, điều này sẽ làm phức tạp mọi tính toán liên quan đến cùng một đồng hồ, vì nó sẽ yêu cầu chuyển đổi. Để làm cho điều này dễ dàng hơn, bạn có thể tạo trình bao bọc đồng hồ của riêng mình thực hiện chuyển đổi và sử dụng:

template <typename Clock> 
struct my_clock_with_doubles { 
    typedef double rep; 
    typedef std::ratio<1> period; 
    typedef std::chrono::duration<rep, period> duration; 
    typedef std::chrono::time_point<my_clock_with_doubles<Clock>> time_point; 
    static const bool is_steady = Clock::is_steady; 

    static time_point now() noexcept { 
     return time_point(std::chrono::duration_cast<duration>(
        Clock::now().time_since_epoch() 
       )); 
    } 

    static time_t to_time_t(const time_point& t) noexcept { 
     return Clock::to_time_t(typename Clock::time_point(
          std::chrono::duration_cast<typename Clock::duration>(
           t.time_since_epoch() 
          ) 
         )); 
    } 
    static time_point from_time_t(time_t t) noexcept { 
     return time_point(std::chrono::duration_cast<duration>(
        Clock::from_time_t(t).time_since_epoch() 
       )); 
    } 
}; 
+0

có gì với '324324.342'? – Puppy

+0

Cảm ơn câu trả lời. Bạn có nghĩ đến việc xây dựng sự mất mát về độ chính xác không? Ngoài ra, kiểu đồng hồ trong 'd_time_point' có thể tùy ý không? – mavam

+0

@Matthias: mất độ chính xác là do loại thời lượng gốc của đồng hồ có thể không thể biểu thị thời lượng chính xác mà bạn có là 'double'. Ví dụ: nếu thời lượng là 10,5 giây, nhưng đồng hồ sử dụng thời lượng không thể tách rời với khoảng thời gian 1 giây, nó sẽ trở thành 10 giây hoặc 11 giây khi được chuyển đổi. Lý tưởng nhất, kiểu đồng hồ trong 'd_time_point' phải là kiểu đồng hồ với cùng một thời đại. –

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