Преобразование даты в числовой формат

Задача: 

Условие и цель задачи. Пользователь вводит дату в формате ‘dd.mm.yyyy’, которая присваивается строчной переменной s. Необходимо преобразовать строку в запись d, имеющую три числовых поля – day, month, year.

Алгоритм решения задачи: 

Алгоритмы преобразования строчного представления даты в численное могут использоваться в программах, которые выполняют какие-либо вычисления, связанные с датами.

Мы не будем писать сразу наиболее эффективную и короткую программу. Сначала алгоритм решения будет достаточно прозрачным и простым.

Программа на языке Паскаль: 

Алгоритм 1. Линейная программа

Введенная пользователем дата находится в строчной переменной s.

Извлечение любого символа из строки производится так же, как получение элемента массива по его индексу. Например, s[1] приведет к извлечению первого символа сроки. Можно даже извлечь срез: s[1..2] извлечет первые два символа. Однако как их преобразовать в число?

Функция ord возвращает порядковый номер переданного ей аргумента. Если ей передать символ, то она вернет его номер в таблице символов. Это будет величина целого типа. Например, символ ‘0’ (ноль) может быть 48-м. Поэтому ord(‘0’) вернет 48. Далее номера цифр идут по порядку друг за другом: ‘1’ – 49, ‘2’ – 50, ‘3’ – 51 и т.д.

Чтобы перевести символьное представление цифры (например, ‘7’) в число (7), достаточно выполнить такое выражение: ord(‘7’) – ord(‘0’). Разница номеров между данными символами как раз составляет семь единиц. Таким образом, мы можем перевести символьное представление цифры в число.

Следующая проблема заключается в том, что числа в дате двузначные (день и месяц) и четырехзначные (год). Мы же получили значение только отдельных цифр. Однако, имея цифры и зная их позицию в числе, нетрудно вычислить само число. Например, если первое число 2 (десятки), а второе 4 (единицы), то получить 24 легко: 2 * 10 + 4. Год wxyz вычисляется по формуле w * 1000 + x * 100 + y * 10 + z.

Кроме того, следует не забыть пропустить точки в строке даты. Это символы под номерами 3 и 6. Они никакого участия в вычислениях принимать не должны.

type date = record
        year:1900..2050;
        month:1..12;
        day:1..31;
     end;
 
var
    d: date;
    s: string;
    k,l,m,n: byte;
 
begin
    write('Введите дату в формате dd.mm.yyy: ');
    readln(s);
 
    k := ord(s[1])-ord('0');
    l := ord(s[2])-ord('0');
    d.day := 10 * k + l;
 
    k := ord(s[4])-ord('0');
    l := ord(s[5])-ord('0');
    d.month := 10 * k + l;
 
    k := ord(s[7])-ord('0');
    l := ord(s[8])-ord('0');
    m := ord(s[9])-ord('0');
    n := ord(s[10])-ord('0');
    d.year := 1000 * k + 100 * l + 10 * m + n;
 
    writeln(d.day);
    writeln(d.month);
    writeln(d.year);
 
readln
end.

Алгоритм 2. Использование цикла и массива

Как можно заметить, слишком много раз в предыдущей программе выполняется выражение ord(s[цифра])-ord('0'). Подобные действия лучше выполнять в цикле, а результат помещать не в переменные, а массив.

Требуется преобразовать в цикле все символы строки, за исключением 3-го и 6-го (тех, которые являются точкой), и заполнить массив.

type date = record
        year:1900..2050;
        month:1..12;
        day:1..31;
     end;
 
var
    d: date;
    s: string;
    i, j: byte;
    a: array [1..8] of byte;
 
begin
    write('Введите дату в формате dd.mm.yyy: ');
    readln(s);
 
    i := 1;
    for j := 1 to 10 do
        if s[j] <> '.' then begin
            a[i] := ord(s[j]) - ord('0');
            i := i + 1
        end;
 
    d.day := 10 * a[1] + a[2];
    d.month := 10 * a[3] + a[4];
    d.year := 1000 * a[5] + 100 * a[6] + 10 * a[7] + a[8];
 
    writeln(d.day);
    writeln(d.month);
    writeln(d.year);
 
readln
end.

Алгоритм 2. Быстрое решение

На самом деле не обязательно использовать массив, цикл и даже лишние переменные. Все делается гораздо проще, однако выражения получаются достаточно длинными и могут быть непонятны для начинающих.

type date = record
        year:1900..2050;
        month:1..12;
        day:1..31;
     end;
 
var
    d: date;
    s: string;
 
begin
    write('Введите дату в формате dd.mm.yyy: ');
    readln(s);
 
    d.day := 10 * (ord(s[1])-ord('0')) + (ord(s[2])-ord('0'));
    d.month := 10 * (ord(s[4])-ord('0')) + (ord(s[5])-ord('0'));
    d.year := 1000 * (ord(s[7])-ord('0')) + 100 * (ord(s[8])-ord('0'));
    d.year := d.year + 10 * (ord(s[9])-ord('0')) + (ord(s[10])-ord('0'));
 
    writeln(d.day);
    writeln(d.month);
    writeln(d.year);
 
readln
end.