Как отсортировать дату (ГГММДД) и проверить ее?

0

Я создаю проект, который требует даты в формате YYMMDD, поэтому я ищу способ, который я могу использовать для проверки его "даты" и как я могу сортировать даты? Любая помощь приветствуется.

Тип данных должен быть int.

  • 0
    Пожалуйста, дайте нам больше информации, например, какой тип данных является датой? это строка без пробелов?
  • 0
    @CoffeeandCode Это int .
Показать ещё 8 комментариев
Теги:
validation

6 ответов

2
Лучший ответ

http://www.boost.org/doc/libs/1_35_0/doc/html/date_time.html должен сделать все это, а затем некоторый std::string ds("2002/1/25"); date d(from_string(ds)); std::string ds("2002/1/25"); date d(from_string(ds));

  • 0
    Он должен быть int и иметь длину 6 (YYMMDD).
  • 0
    Можете ли вы предоставить код? если это int, то сортировка должна быть легкой?
Показать ещё 7 комментариев
1

include      // std::cout
include     // std::sort
include        // std::vector 

int getYear (int date) {int year = (дата /10000);

return (year < 20)? возвращение (год <20)? 2000+year: year; 2000 + год: год;

} int getMonth(int date) { } int getMonth (int date) {

int month = (дата /100)% 100; return (date/100)% 100;

} int getDay (int date) {int d2 = (дата /10)% 10; int d1 = (date/100) % 10; int d1 = (дата /100)% 10;

return d2*10+d1; return d2 * 10 + d1;

} bool myfunction (int i,int j) { } bool myfunction (int i, int j) {

if (getYear (i)> getYear (j)) возвращает true; if (getYear (i) == getYear (j) && getMonth (i)> getMonth (j)) возвращает true; if (getYear (i) == getYear (j) && getMonth (i) == getMonth (j) && getDay (i)> getDay (j)) возвращает true; return false; }

int main() {int myints [] = {130525,951022, 130624, 121212};

std::vector<int> myvector (myints, myints+4); std::sort (myvector.begin(), myvector.end(), myfunction); std::cout << "Year: " << getYear(130525); std::cout << "Month:" << getMonth(130525); std::cout << "Day:" << getDay(130525); std::cout << std::endl <<std::endl; std::cout << "Year: " << getYear(951022); std::cout << "Month:" << getMonth(951022); std::cout << "Day:" << getDay(951022); std::cout << std::endl; std::cout << "myvector contains:"; for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; }

Сделано boo boo, это правильный обновленный pastebin http://pastebin.com/yvBNrcTU

1

Если вы получаете дату в формате, который не гарантированно работает, сохраните входной YYMMDD в виде строки. Возьмите первые два символа из строки (это должно быть тривиально, строки - массивы символов и массивы имеют прямой доступ). Убедитесь, что эти два символа могут быть преобразованы в целое число от 00 до 99 включительно. Если это не так (например, если это буквы или символы), возвращает false. Делайте то же самое в течение месяцев, которое может быть только между 01 и 12. Используйте потоки для преобразования символов в числа. Делайте то же самое в течение нескольких дней, должна быть установлена кепка 31 и пол 01.

Если вы хотите подтвердить, что такая дата действительно может быть действительной на основе календаря, следует применять слегка модифицированный алгоритм. (Например, високосный год будет иметь дополнительный день в феврале, тогда как он должен быть незаконным в непиковые годы).

Наконец, чтобы отсортировать их, определите пользовательский компаратор для класса, который должен быть создан под именем Date. Затем сохраните объекты Date в коллекции (ваш выбор) и примените алгоритм сортировки, посылая ему пользовательский компаратор. Сорт должен быть похож на сортировку счисления, где значительными цифрами будут годы.

Если какое-либо из этого звучит запутанным, сообщите мне, и я подробно расскажу.

  • 0
    Ну, я понимаю все, что вы сказали, кроме последнего предложения о сортировке. Вы не возражаете, если объясните это немного больше или какой-нибудь код psuedo / c ++?
  • 0
    Да, я согласен, я должен был подумать, что я сказал немного лучше. В основном, каждая дата содержится в ведрах, основанных на их годах. Поэтому, глядя только на год, сортируйте их в каждом ведре (скажем, 84). Затем, глядя на каждый кусок в год, делайте ежемесячные ведра. Для каждого ежемесячного сегмента, наконец, сортируйте их по полям дня. Я рекомендую читать по радикальным сортам. Нетрудно найти реализацию C ++ онлайн.
1

Поскольку у вас есть только даты с 1980 года, дешевый и грязный способ их сортировки заключается в том, чтобы хранить дату как целое число формата SSMMDD, где SS, а не год, годы с 1980 года. Тогда они будут в числовой порядок, и вы можете сортировать их без пользовательского сравнения. При чтении даты:

if (YY >= 80) {
    SS -= 80;
} else {
    SS += 20;
}

Конечно, вам придется применить обратное преобразование к дате перед ее выходом.

1

Если передать как простое целое число, вы можете использовать std :: to_string, затем проанализировать эту строку, чтобы проверить каждые два символа.

Пример:

bool check_year(int year){
    ... check year for roll-over e.g. 99 to 00 ...
    ... if too low or high, false ...
}

bool check_day(int month, int day){
    ... check day based on month ...
    ... if too high, false ...
}

bool is_date_good(int date)
{
    std::string yolo = std::to_string(date);

    int check;

    check = stoi(yolo.substr(0, 2));
    if(!check_year(check))
        return false;

    check = stoi(yolo.substr(2, 2));
    if(check > max_month) // should be 12
        return false

    int month = check;
    check = stoi(yolo.substr(4, 2));

    if(!check_day(month, day))
        return false;

    return true;
}
  • 0
    Обратите внимание, однако, что ОП сказал, что он не использует C ++ 11.
  • 0
    Это для проверки, которую, я думаю, я хорошо понимаю сейчас. Но проблема в сортировке.
Показать ещё 1 комментарий
1

Похоже, что все остальные используют строки. Если у вас есть int с форматом YYMMDD и он гарантированно всегда будет в этом формате, вам действительно не нужны строки. Здесь, как я хотел бы получить отдельные номера из него:

struct date { int year; int month; int day; };

date getDate(int yymmdd) {
    date d;
    d.day = yymmdd % 100;
    yymmdd /= 100;
    d.month = yymmdd % 100;
    yymmdd /= 100;
    d.year = yymmdd;
    return d;
}

Теперь, проверка этого - целая другая проблема. Сроки сложны, и вы, вероятно, пропустите что-то, если у вас нет тестового набора, чтобы работать против, поэтому определенно рекомендуется использовать boost.date или что-то подобное. В противном случае вам нужно будет проверить, соответствует ли день <= 28, 29, 30 или 31, в зависимости от того, в каком месяце он находится, и если этот год - високосный год (это происходит не каждые 4 года). Но определенно рекомендуется просто пойти с проверенной библиотекой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню