2012-12-09 6 views
4

C++에서 상대적으로 쉽고 간단한 날짜 비교 함수가 있는지 궁금합니다. 내 날짜는 char*이며 다음과 같은 형식입니다. DD\MM\YYYYC++에서 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에서 mktime을 작동 시키려면 먼저 tm struct를 0으로 memset해야했습니다. 예를 들면 다음과 같습니다. 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 문자열 비교이 strncmp처럼 작동

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); 
} 

와 함께 할 수 있습니다. d1d2보다 빠른 경우 0보다 작은 값을, d2보다 작 으면 d1 인 경우 0을, 같은 날짜 인 경우 0을 반환합니다.

또 다른 방법은 효율적인 솔루션에 대한 time_tstrptimemktime로 변환하고 difftime

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 
관련 문제