2009-08-12 37 views
8

tôi có riêng của C++ DateTime lớp học của tôi định nghĩa là:C++ DateTime lớp

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 
}; 

tôi có 2 DateTime mà tôi cần phải so sánh để xem cái nào là lớn hơn (nhiều hơn gần đây) khác.

Có tự do có sẵn C++ DateTime lớp mà tôi có thể sử dụng để

  1. Chuyển đổi lớp DateTime tôi đến lớp DateTime họ
  2. lớp của họ nên cung cấp <,>, < =,> = nhà khai thác để so sánh

Nếu ví dụ cụ thể có thể được cung cấp tuyệt vời. Lưu ý rằng tôi cần phải so sánh xuống đến mili giây.

Tôi đã suy nghĩ về Boost hoặc Qt. Ưu tiên là Tăng.

+3

Nếu bạn có lớp học của riêng bạn tại sao bạn lại cần một lớp khác? –

+7

Hoặc quan trọng hơn, nếu bạn định sử dụng lớp của người khác, tại sao chỉ sử dụng nó để so sánh? Chỉ cần sử dụng lớp học của họ. Công việc được thực hiện cho bạn. Mương lớp học của bạn. – GManNickG

+0

Lý do là vì ứng dụng của tôi là thư viện C++ mà ứng dụng khác sẽ sử dụng. 1) Tôi không muốn họ phải bao gồm thư viện Boost để họ sử dụng thư viện của tôi. 2) Lớp DateTime này đã được sử dụng ở nhiều nơi của một hệ thống cũ. Cảm ơn các bình luận. – sivabudh

Trả lời

18

Xem Boost Date Time library

Và lớp học của bạn trông rất giống struct tm

EDIT: Bạn nói đúng đó struct tm không hỗ trợ millisecond chính xác.

Hãy xem Boost example. cái đó có giúp ích không?

+0

tôi liếc qua tài liệu đó rồi .. nhưng nó quá dày đặc. tôi cũng không thể tìm thấy một ví dụ với millisec. tôi đã tìm kiếm một ví dụ dọc theo dòng này: http://doc.trolltech.com/4.5/qdatetime.html. – sivabudh

+0

đúng là lớp của tôi rất giống struct tm ... tuy nhiên, sự khác biệt quan trọng là tôi cũng có một trường mili giây. – sivabudh

+0

struct tm không hỗ trợ mili giây kể từ đó, đó là một điều POSIX và thời gian kiểu UNIX bình thường chỉ được cung cấp cho lần thứ hai. –

2

Có gì sai khi sử dụng nội dung của <time.h> để triển khai lớp học của bạn? Đó là tiêu chuẩn C90.

+0

không có gì là sai với điều đó ... bạn có thể xin vui lòng có lẽ cung cấp một ví dụ về cách tôi có thể đi về bằng cách sử dụng ? – sivabudh

+3

Đây là C++. Đó phải là '#include ' – GManNickG

5

Tôi không biết về bất kỳ ra khỏi đỉnh đầu của tôi. Nhưng tôi sẽ xem xét viết lại lớp ngày của bạn để giữ một số nguyên 64 bit duy nhất mô tả mili giây kể từ kỷ nguyên thông thường (1970 là nó?). Sau đó, bạn được tự do chia cho 1000 và sử dụng các hàm CRT bình thường để định dạng dưới dạng chuỗi, cộng với bạn có thể lấy giá trị modulo 1000 để lấy phần mili giây.

Toán tử so sánh sau đó trở nên dễ dàng ..

+0

Tôi muốn giới thiệu một cái gì đó như thế này. Lưu trữ thời gian nội bộ như một số nguyên như thế này để so sánh dễ dàng, và sau đó cung cấp truy cập để có được các phần khác nhau của thời gian bị hỏng (giờ, tháng, vv). Nếu hiệu quả là một mối quan ngại, bạn có thể cache thời gian bị hỏng cho đến khi thời gian nội bộ được sửa đổi, do đó bạn không phải giữ lại kết quả năm để có được tháng, v.v. –

+0

Tức là, nếu bạn không lên kế hoạch để sử dụng tăng. –

+0

Nếu tôi chỉ có thể thăng cấp nhiều lần ... – phonetagger

8

Bạn có thể muốn kiểm tra QDateTime từ Qt, mà có người điều khiển cần thiết và chính xác ms.

Chuyển đổi từ lớp học của bạn có thể được thực hiện thông qua

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 

    QDateTime toQDateTime() { 
    return QDateTime(QDate(year, month, day), QTime(hour, min, sec, millisec)); 
    } 
}; 

Một cách khác xung quanh cũng tương tự như ;-)

1

GNU R sử dụng một sự thay thế struct tm với độ chính xác micro - thay vì (số nguyên) giây kể từ thời đại, bây giờ nó sử dụng một số dấu chấm động. Điều đó thực sự thực sự hữu ích. Đối với nhiều ứng dụng của tôi, tôi chỉ cần tăng gấp đôi xung quanh và chưa nhận được chuyển đổi thời gian. Xem R-2.9.1/src/main/datetime.c trong các nguồn R hiện tại.

Có điều đó trong một lớp C++ độc lập sẽ thuận tiện.

4

OK, đây là đoạn mã cuối cùng trả lời câu hỏi của riêng tôi. Tôi nghĩ đến việc chia sẻ điều này trong trường hợp nó có thể hữu ích cho một số người khác trong tương lai. Cảm ơn Fred Larson đã chỉ ra ví dụ Boost.

Tôi đã chọn Boost để thực hiện phép tính DateTime vì ứng dụng của tôi đã sử dụng Boost ở một nơi khác. Tôi nghĩ rằng tôi có thể đã có thể sử dụng Qt là tốt, mặc dù tôi không thể hoàn toàn xác nhận.

Giả sử DateTime được định nghĩa là:

class DateTime 
{ 
public: 
    int year; 
    int month; 
    int day; 
    int hour; 
    int min; 
    int sec; 
    int millisec; 
}; 

Để làm một DateTime so sánh đơn giản

bool DateTime::operator < (const DateTime& dt_) 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 

    ptime thisTime(date(this->year,this->month,this->day), 
        hours(this->hour) + 
        minutes(this->min) + 
        seconds(this->sec) + 
        boost::posix_time::millisec(int(this->millisec))); 

    ptime thatTime(date(dt_.year,dt_.month,dt_.day), 
        hours(dt_.hour) + 
        minutes(dt_.min) + 
        seconds(dt_.sec) + 
        boost::posix_time::millisec(int(dt_.millisec))); 

    return thisTime < thatTime; 
} 

Để thêm 2 DateTime với nhau để trả về một DateTime mới

DateTime DateTime::operator + (const DateTime& dt_) 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 

    date thisDate(this->year, this->month, this->day); 
    date newDate = thisDate + years(dt_.year) + months(dt_.month) + days(dt_.day); 

    ptime newDateTime(newDate, 
    hours(this->hour) + hours(dt_.hour) + 
    minutes(this->min) + minutes(dt_.min) + 
    seconds(this->sec) + seconds(dt_.sec) + 
    boost::posix_time::millisec(int(this->millisec)) + 
    boost::posix_time::millisec(int(dt_.millisec)) 
    ); 

    DateTime dateTime; 

    date t1_date = newDateTime.date(); 

    dateTime.year = t1_date.year(); 
    dateTime.month = t1_date.month(); 
    dateTime.day = t1_date.day(); 

    time_duration t1_time = newDateTime.time_of_day(); 

    dateTime.hour  = t1_time.hours(); 
    dateTime.min  = t1_time.minutes(); 
    dateTime.sec  = t1_time.seconds(); 
    dateTime.millisec = t1_time.fractional_seconds()/1000.0f; 

    return dateTime; 
} 
4

I mương lưu trữ ngày trong gregorian lứa tuổi trước đây. Tôi lưu trữ ngày dưới dạng số nguyên 32 bit (giống như một ngày Julian). Vì vậy, ngày được tạo thành (Năm * 1000) + DOY (DOY là ngày trong năm). I.e. - 2009001 Là ngày 1 tháng 1 năm 2009 - 2009365 là ngày 31 tháng 12 năm 2009

Lớp ngày của tôi tất nhiên cung cấp các phương pháp nhận Năm, Tháng và Ngày, cộng, lấy số ngày giữa Ngày tháng vv ..

Ngày và giờ, tôi sử dụng phao 64 bit, nơi phần nguyên của số thực giống như số nguyên (Julian like) ngày được mô tả ở trên, và phân số đại diện cho thời gian trong phần của một ngày.

I.e.

  • 2009001,04166666666 ~ là Jan 1,2009 01:00
  • 2009001,06249999999 ~ là Jan 1,2009 01:30
  • 2009001,95833333333 ~ là Jan 1,2009 11:00

Nếu bạn chỉ cần độ chính xác phút, bạn có thể sử dụng phao 32bit cho ngày và giờ nhưng bạn không thể chính xác đầy đủ lưu giây và mili giây.

Những lợi thế của việc lưu trữ ngày (và thời gian) theo cách này là:

  • Bạn chỉ cần 8bytes để đại diện cho dữ liệu và thời gian so với 28bytes (giả sử số nguyên 32bit) sử dụng bởi DateTime lớp trong câu hỏi.

  • So với ngày lưu trữ như giây từ một kỷ nguyên, khi nhìn vào số lượng (ví dụ như trong trình gỡ lỗi) bạn nhiều hơn hoặc ít hơn có thể xác định từ số năm và ngày trong năm, và gần đúng thời gian trong ngày (để nhận giờ, phút, giây thứ hai sau nửa đêm chỉ đơn giản là mulitply bằng 24, 1440, 86400 tương ứng).

  • So sánh ngày tháng là không đáng kể, chỉ cần so sánh các số (Một hoạt động CPU đơn lẻ so với một số nó sẽ lấy ví dụ DateTime).

  • Ít hoạt động so sánh hơn để thực hiện số học ngày.

Các disadvange này (cho thời gian thời gian) là một mất mát nhỏ chính xác (điều này thực chất là một điểm mute) và bạn phải làm một số làm tròn đơn giản để có được giá trị số nguyên thoải mái khi convering đến giá trị nguyên giờ phút và giây.

+0

Tôi thích kiểu này. –

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