2014-10-23 43 views
10

Điều gì sẽ là điều tốt nhất tiếp theo cho strptime khi chúng ta có chuỗi ngày giờ bằng mili giây?Cách tốt nhất để phân tích cú pháp thời gian ngày mili giây là C++ 11

Given:

"30/03/09 16:31:32.121" 

chúng ta không thể sử dụng strptime thường xuyên vì struct tm không lưu trữ millisseconds. Có một lớp học mới có thể đạt được điều này?

+0

['std :: get_time'] (http://en.cppreference.com/w/cpp/io/manip/get_time) là C++ 11 nhưng phản ánh đặc điểm' strptime'. Bạn có cần lưu trữ mili giây không, hay bạn chỉ cần hiển thị nó? –

+0

Mục tiêu của tôi là lưu trữ thời gian ngày này trong một thời gian chrono, vì vậy tôi cần nó được phân tích cú pháp và lưu trữ. – Nezquick

+0

Với 0,1214 bạn không yêu cầu mili giây, nhưng trong 1/10 mili giây hoặc 100 micro giây. –

Trả lời

6

tôi sẽ phân tích các lĩnh vực này bằng tay (đọc vào int và double cho giây), sau đó sử dụng days_from_civil để chuyển đổi năm/tháng/ngày vào một chrono::system_clock::time_point:

std::chrono::system_clock::time_point t(days(days_from_civil(y, m, d))); 

nơi days là:

using days = std::chrono::duration<int, std::ratio<86400>>; 

Sau đó, bạn có thể thêm vào đó giờ, phút và giây. Để xử lý các phân đoạn giây bạn sẽ cần phải làm một điệu nhảy nhẹ:

double s; 
your_stream >> s; // 32.121 
using namespace std::chrono; 
duration<double> dsecs(s); 
seconds sec = duration_cast<seconds>(dsecs); 
milliseconds ms = duration_cast<milliseconds>(dsecs - sec); 
t += sec + ms; 

Nếu bạn thích, sử dụng round from here cho chuyển đổi mili giây của bạn:

milliseconds ms = round<milliseconds>(dsecs - sec); 

duration_cast là cắt ngắn về phía zero. Có các chế độ làm tròn khác: sàn, tròn, ceil, at this link.

Quấn tất cả lên trong một chức năng gọn gàng để dễ dàng sử dụng lại. :-)

Mã trên tất cả đều giả định UTC. Nếu ngày/giờ mà bạn đang phân tích cú pháp được biết là được bù trừ từ UTC, bạn có thể cộng/trừ chênh lệch đó. Mọi triển khai đã biết của system_clock theo dõi Unix time, là giây từ 1970-01-01 theo múi giờ UTC.

Cập nhật

Kể từ khi viết câu trả lời này tôi đã phát triển một more general library rằng OP dường như được tìm kiếm tại thời điểm đó. Nó có thể phân tích một loạt các độ chính xác thứ hai tiểu trực tiếp vào một std::chrono::system_clock::time_point như thế này:

#include "date.h" 
#include <iostream> 
#include <sstream> 

int 
main() 
{ 
    std::istringstream in{"30/03/09 16:31:32.121\n" 
          "30/03/09 16:31:32.1214"}; 
    std::chrono::system_clock::time_point tp; 
    in >> date::parse("%d/%m/%y %T", tp); 
    using namespace date; 
    std::cout << tp << '\n'; 
    in >> date::parse(" %d/%m/%y %T", tp); 
    std::cout << tp << '\n'; 
} 

này kết quả đầu ra:

2009-03-30 16:31:32.121000 
2009-03-30 16:31:32.121400 

thư viện này sử dụng các kỹ thuật và các công cụ tương tự như tôi đã mô tả ban đầu, nhưng được đóng gói lên và sẵn sàng để đi như một thư viện tiêu đề duy nhất.

+0

thay vì sử dụng days_from_civil (một lib bên ngoài khác) Tôi đã sử dụng time_t thông thường để có được phần làm việc :) Tôi đã kết thúc bằng cách sử dụng google: re2 để đọc các mô hình kể từ khi tôi muốn một cái gì đó chung chung hơn một chút. Cảm ơn – Nezquick

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