2012-12-09 227 views
4

我想知道是否存在任何C相對容易和短日期比較函數++。 我的日期類型爲char*,並且具有以下格式:DD\MM\YYYY比較在C++ 2個日期

謝謝。

+0

相關:http://stackoverflow.com/questions/1650715/c-standard-date-time-class。我寫了自己的日期類來做這些操作。你也可以輕鬆做到這一點。 – AgA

+1

還檢查出支持一些日期和時間實用程序的C++ 11s new * chrono *頭。 – Snps

+0

反斜槓,而不是正斜槓? – Potatoswatter

回答

6

解析通常是在流,而不是字符串做,但你可以使用一個stringstream。現在

std::istringstream date_s("04\\10\\1984"); 
struct tm date_c; 
date_s >> std::get_time(&date_c, "%d\\%m\\%Y"); 
std::time_t seconds = std::mktime(& date_c); 

您可以使用<,以確定哪些早期是比較秒。

注意,std::get_time在C++ 11是新的。它是根據strptime定義的,它來自POSIX但不是C99標準的一部分。如果C++ 11庫不可用,則可以使用strptime。如果你很勇敢,你也可以使用std::time_get方面......雖然這很醜陋。

如果您不想知道除此之外的其他日期的任何信息,可以使用std::lexicographical_compare。這將是一個單線,但功能名稱是如此之久。

// return true if the date string at lhs is earlier than rhs 
bool date_less_ddmmyyyy(char const *lhs, char const *rhs) { 
    // compare year 
    if (std::lexicographical_compare(lhs + 6, lhs + 10, rhs + 6, rhs + 10)) 
     return true; 
    if (! std::equal(lhs + 6, lhs + 10, rhs + 6)) 
     return false; 
    // if years equal, compare month 
    if (std::lexicographical_compare(lhs + 3, lhs + 5, rhs + 3, rhs + 5)) 
     return true; 
    if (! std::equal(lhs + 3, lhs + 5, rhs + 3)) 
     return false; 
    // if months equal, compare days 
    return std::lexicographical_compare(lhs, lhs + 2, rhs); 
} 

how to convert datetime to unix timestamp in c?見。

+1

對於std :: get_time示例,在Visual Studio 2013中,我需要首先將tm結構memset爲零,以便讓mktime工作。例如:memset(&date_c,0,sizeof(date_c)); – bossbarber

1

你需要從一個字符串中提取數字數據。最糟糕的情況是一堆循環和字符串到整數轉換函數。

你可以用的sscanf和sprintf很容易做到這一點。如果你已經習慣了printfscanf那麼這很容易理解,你可以很容易地適應其他案件。沒有祕密的魔法函數調用。

#include <stdio.h> 
void main() 
{ 
    char* date1 = "9\\12\\2012"; 
    char* date2 = "6\\11\\2013"; 

    int day1,month1,year1; 
    int day2,month2,year2; 

    sscanf(date1,"%d\\%d\\%d",&day1,&month1,&year1); //reads the numbers 
    sscanf(date2,"%d\\%d\\%d",&day2,&month2,&year2); //from the string 

    if (year1<year2 || month1<month2 || day1<day2) //compares 2 dates 
    { 
     printf("date1 < date2\n"); 
    } 
    else 
    { 
     printf("date1 >= date2\n"); 
    } 

    char newdate[15]; 

    sprintf(newdate,"%d\\%d\\%d",13,2,1998); //make a date string from numbers 
    printf("%s\n",newdate); 
} 
+0

謝謝,但我只有一個'\'之間的D \ M \ Y而不是兩個 –

+2

第二個是逃避斜線 – fbstj

+3

我希望沒有人使用這個,因爲日期比較是錯誤的。應該是'if(year1!= year2){return year1 mandrake

2

如果這真的是一個固定的格式,你可以用簡單的C字符串比較

int date_cmp(const char *d1, const char *d2) 
{ 
    int rc; 
    // compare years 
    rc = strncmp(d1 + 6, d2 + 6, 4); 
    if (rc != 0) 
     return rc; 

    // compare months 
    rc = strncmp(d1 + 3, d2 + 3, 2); 
    if (rc != 0) 
     return rc; 

    // compare days 
    return strncmp(d1, d2, 2); 
} 

這就像strncmp做到這一點。如果d1早於d2,則返回小於0的值;如果兩者都是相同日期,則返回0;如果d1晚於d2,則返回大於0的值。

另一種方法是將它與strptimemktime轉換爲time_tdifftime

struct tm tm; 
time_t t1, t2; 
strptime(d1, "%d\\%m\\%Y", &tm); 
t1 = mktime(&tm); 
// do the same with d2 
double diff = difftime(t1, t2); 
1

如何比較這大約一個有效的解決方案?如果您忽略斜槓,您的固定大小日期只需要8個字符。所以通過一些移位和字節交換,你可以將它們比作64位整數。這比比較字符串要快。

using std::cout; 
using std::endl; 
typedef unsigned __int16 U2; 
typedef unsigned __int32 U4; 
typedef unsigned __int64 U8; 
#define bswap2 _byteswap_ushort 
#define bswap4 _byteswap_ulong 
#define bswap8 _byteswap_uint64 

const int YYYYMMDD = 0; 
const int YYYY_MM_DD = 1; 
const int DDMMYYYY = 2; 
const int DD_MM_YYYY = 3; 

// compiler will optimize the if's out. 
template <int FMT> 
U8 DateToInt(char* sz) { 
    if (FMT == YYYYMMDD) { 
     return bswap8(*(U8*)sz); 
    } 
    if (FMT == YYYY_MM_DD) { 
     U4 y = *(U4*)sz, m = *(U2*)(sz + 5), d = *(U2*)(sz + 8); 
     return ((U8)bswap4(y) << 32) | (bswap2(m) << 16) | bswap2(d); 
    } 
    if (FMT == DD_MM_YYYY) { 
     U4 y = *(U4*)(sz + 6), m = *(U2*)(sz + 3), d = *(U2*)sz; 
     return ((U8)bswap4(y) << 32) | (bswap2(m) << 16) | bswap2(d); 
    } 
} 

template<int FMT1, int FMT2 = FMT1> 
__int64 CompareDate(char* sz1, char* sz2) { 
    return DateToInt<FMT1>(sz1) - DateToInt<FMT2>(sz2); 
} 

void main() { 
    cout << CompareDate<YYYYMMDD>("20151025", "20151026") << endl; 
    cout << CompareDate<YYYYMMDD>("20151025", "20151024") << endl; 
    cout << CompareDate<YYYYMMDD, YYYY_MM_DD>("20151025", "2015/10/26") << endl; 
    cout << CompareDate<YYYYMMDD, YYYY_MM_DD>("20151025", "2015/10/24") << endl; 
    cout << CompareDate<YYYYMMDD, DD_MM_YYYY>("20151025", "26/10/2015") << endl; 
    cout << CompareDate<YYYYMMDD, DD_MM_YYYY>("20151025", "24/10/2015") << endl; 
} 

輸出

-1 
1 
-1 
1 
-1 
1