我想知道C ++中是否有相对容易和短的日期比较函数。
我的日期属于char*
类型,格式如下:DD\MM\YYYY
感谢。
答案 0 :(得分: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, rhs+2 );
}
答案 1 :(得分: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
晚于{{1,则返回大于0的值}}
另一种方法是将strptime
和mktime
转换为d2
并将其与difftime
进行比较
time_t
答案 2 :(得分:1)
您需要从字符串中提取数字数据。最糟糕的情况是一堆循环和字符串到整数转换函数。
您可以使用sscanf和sprintf轻松完成。如果您已经习惯printf
和scanf
,那么这很容易理解,您可以轻松地将其调整到其他情况。没有秘密魔法函数调用。
#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);
}
答案 3 :(得分: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