Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дата, Вычислить... 
V
    Опции темы
Сый
Дата 24.4.2006, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Даётся число дней, прошедших от определённой даты (например, начала некоторого года). Нужен алгоритм, вычисляющий по этому числу и дате текущий день, месяц и год. 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Akina
Дата 24.4.2006, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



См. описание функции DateAdd... 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
skalex
Дата 24.4.2006, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: нет
Всего: 23



Все переводим в секунды и пользуясь возможностями того или иного ЯП получаем искомые данные.
Например в PHP я бы это сделал так ...
Пусть дана дата 02.01.2006 и кол-во дней 35.
Код
echo strftime('%d.%m.%Y', mktime(0, 0, 0, 1, 2, 2006) + 35*24*60*60);
 
PM   Вверх
Сый
Дата 24.4.2006, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Само собой, есть готовые функции и т. д. Но возникает вопрос: зачем бы я размещал эту тему в разделе "Алгоритмы", если мне нужно было бы узнать о возможностях некоторых ЯП? 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
nostromo
Дата 24.4.2006, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



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

Добавлено @ 13:40 
Многие среды программирования и некоторые операционные системы поставляются с исходными текстами. Может посмотреть реализации там?  

Это сообщение отредактировал(а) nostromo - 24.4.2006, 13:41
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
skalex
Дата 24.4.2006, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: нет
Всего: 23



nostromo, вот и я про то же ...  smile  
PM   Вверх
Сый
Дата 24.4.2006, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



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

> Многие среды программирования и некоторые операционные системы поставляются с исходными текстами. Может посмотреть реализации там?  
К сожалению, таковых при себе сейчас не имею, а искать и качать - лень.  

Это сообщение отредактировал(а) Сый - 24.4.2006, 15:48
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
nostromo
Дата 24.4.2006, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: 5
Всего: 10



Вот, например, метод из исходников VisualWorks Smalltalk с хорошими комментариями.
Подсветки синтаксиса smalltalk, к сожалению, нет.
(Комментарии в смолтолке пишутся в кавычках.)
Код

convertGMT: totalSeconds do: aBlock 
    "Convert a UTC (GMT) time to a local date and time 
    (the two interact because of Daylight Saving Time).  
    The UTC time origin is midnight, Dec 31 1900.  Answer 
    with the result of invoking the argument aBlock with 
    two arguments representing the local date (an instance 
    of Date) and time (an integer representing time in 
    seconds since midnight)."

    | sec date seconds days dd start end secondsThisYear |
    sec := totalSeconds + secondsFromGMT.
    "Get the number of days since the origin. Since 86400 = 24 * 60 * 60 
    = 675 * 128, we can bring the total seconds back into SmallInteger 
    range by doing an initial shift, thereby trading LargeInteger shifting 
    and masking for multiplication and division."
    seconds := sec bitAnd: 127.
    sec := sec bitShift: -7.
    days := sec // 675.
    seconds := seconds + (sec \\ 675 bitShift: 7).
        "Decide if DST is in effect."
    secondsForDST ~= 0
        ifTrue: 
            ["This time zone does have DST"
            date := dd := Date fromDays: days.
            start := ((Date newDay: (dayStartDST >= 60
                            ifTrue: [dayStartDST + dd leap]
                            ifFalse: [dayStartDST])
                            + 1 year: dd year)
                        previous: self weekDayToStartDST) day * 86400 + timeStartDST.
            end := ((Date newDay: (dayEndDST >= 60
                            ifTrue: [dayEndDST + dd leap]
                            ifFalse: [dayEndDST])
                            + 1 year: dd year)
                        previous: self weekDayToStartDST) day * 86400 + timeEndDST - secondsForDST.
            secondsThisYear := dd day * 86400 + seconds.
            (dayStartDST < dayEndDST
                    ifTrue: ["Summer is mid-year."
                        secondsThisYear >= start and: [secondsThisYear < end]]
                    ifFalse: ["Summer is new-year."
                        secondsThisYear >= start or: [secondsThisYear < end]])
                ifTrue: 
                    ["DST is in effect. Correct the time."
                    seconds := seconds + secondsForDST.
                    date := Date fromDays: days + (seconds // 86400).
                    seconds := seconds \\ 86400]]
        ifFalse: ["No DST"
            date := Date fromDays: days].
    ^aBlock value: date value: seconds
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
Сый
Дата 24.4.2006, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Спасибо, но...
> с хорошими комментариями
Ни слова непонятно в этих комментариях.
> Подсветки синтаксиса smalltalk, к сожалению, нет.
От неё толку много не будет, т. к. код сложноват для понимания в любом случае.
Можно было бы его и описать словами. 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Akina
Дата 24.4.2006, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Дурацкий какой-то разговор... тебе именно алгоритм? его уже рассказали - отсчет от базы. или речь о построении решения конкретной задачи? тогда озвучь задачу... 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Сый
Дата 24.4.2006, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Нужно 2 функции: одна должна переводить дату в число дней от определённого момента, другая - это число в дату. Это не так просто, ведь нужно расчитать число дней в году, число дней во всех предыдущих годах, не високосный ли год, сколько дней в месяце и т. д. 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
skalex
Дата 24.4.2006, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: нет
Всего: 23



Сый, как правило в ЯП уже встроены функции для того, чтобы это все сделать с учетом всех ньюансов.  

Это сообщение отредактировал(а) skalex - 24.4.2006, 19:22
PM   Вверх
Сый
Дата 24.4.2006, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Я знаю. Но это не меняет ситуацию. 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
maxim1000
Дата 25.4.2006, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



если нужно хранить только дату - достаточно 32-битного числа на ОЧЕНЬ большой промежуток времени
так что за отсчет можно взять 0-й год
если не ошибаюсь, високосность - год делится на 4 минус годы, делящиеся на 100, плюс годы, делящиеся на 400

перевод из <год, месяц, число>:
1. days=год*365+год/4-год/100+год/400
(все деления нацело)
дальше - делаем массив из количеств дней в месяцах (для февраля надо учесть високосность)
2. добавляем к days первые <месяц> элементов
3. добавляем к days <число>

назад:
1. считаем с точностью до 400 лет (в таком отрезке 400*365+100*1-4*1+1 дней)
2. учитываем остаток с точностью 100 лет (внутри 400 лет каждая сотня  - 100*365+25*1-1 дней)
3. потом с точностью до 4 лет
4. потом узнаем точно год, потом месяц, потом число... 


--------------------
qqq
PM WWW   Вверх
Сый
Дата 25.4.2006, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Вот так осуществил преобразование в число дней:

Код

ЗАДАЧА Високосный-(Год: ЦЕЛ): КЛЮЧ;
УКАЗ
  ЕСЛИ ((Год ОСТАТОК 4 = 0) И (Год ОСТАТОК 100 # 0)) ИЛИ (Год ОСТАТОК 400 = 0) ТО
    ВОЗВРАТ ВКЛ ИНАЧЕ ВОЗВРАТ ОТКЛ КОН
КОН Високосный;

ЗАДАЧА ВЧисло-(День, Месяц, Год: ЦЕЛ): ЦЕЛ;
ПЕР
  Результат, Счётчик: ЦЕЛ;
ЗАДАЧА Месяцы(Номер: ЦЕЛ; Високосн: КЛЮЧ): ЦЕЛ;
ПЕР
  ч, Результат: ЦЕЛ;
  Мес: РЯД 12+1 ИЗ ЦЕЛ;
УКАЗ
  Мес[0] := 0; Мес[1] := 31; ЕСЛИ Високосн
  ТО Мес[2] := 29 ИНАЧЕ Мес[2] := 28 КОН; Мес[3] := 31;
  Мес[4] := 30; Мес[5] := 31; Мес[6] := 30; Мес[7] := 31;
  Мес[8] := 31; Мес[9] := 30; Мес[10] := 31;
  Мес[11] := 30; Мес[12] := 31;
  Результат := 0;
  ОТ ч := 1 ДО Номер ВЫП
    УВЕЛИЧИТЬ(Результат, Мес[ч-1])
  КОН;
  ВОЗВРАТ Результат
КОН Месяцы;
УКАЗ
  Результат := 0;
  ОТ Счётчик := 1 ДО Год-1 ВЫП
    ЕСЛИ Високосный(Счётчик) ТО УВЕЛИЧИТЬ(Результат, 366) ИНАЧЕ УВЕЛИЧИТЬ(Результат, 365) КОН;
  КОН;
  ВОЗВРАТ Результат + Месяцы(Месяц, Високосный(Год)) + День
КОН ВЧисло;
 

Это сообщение отредактировал(а) Сый - 4.5.2006, 10:12
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
skalex
Дата 25.4.2006, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: нет
Всего: 23



Сый, хорошая у тебя работа/развлечение ... Я подобные штуки видел когда в школе учился на уроках информатики ...  smile  было страшно и страшно по сей день!  smile  
PM   Вверх
Сый
Дата 26.4.2006, 07:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Ну надо же такому замечательному языку программирования, как Глагол, помогать развиваться, хотя бы реализуя различные программы/алгоритмы на нём  smile  
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Сый
Дата 27.4.2006, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Небольшая ошибка в приведённом мной коде:

В задаче "Дней" нужно не:
Код

ЕСЛИ Високосный(Год) ТО

а:
Код

ЕСЛИ Високосный(Счётчик) ТО
 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Сый
Дата 27.4.2006, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Вычислил я число прошедших веков:
Код

Веков := (Дней ДЕЛИТЬ (400*365+100*1-4*1+1))*4 + (Дней ОСТАТОК (400*365+100*1-4*1+1)) ДЕЛИТЬ (100*365+25*1-1)

Получил число целых четырёхсотлетий, умножил их на 4 (получил число веков в них), прибавил дни неполного четырёхсотлетия, делённые на число дней в сотне лет (то есть прибавил оставшиеся целые века). Как теперь правильно вычислить четырёхлетки, а далее год? 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Сый
Дата 28.4.2006, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Так вычислил четырёхлетки:
Код

  Четырёхлеток := Веков*25 + (Дней ОСТАТОК (400*365+100*1-4*1+1)) ОСТАТОК (100*365+25*1-1) ДЕЛИТЬ (365*4+1);
 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Сый
Дата 4.5.2006, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Вот написал, наконец-то, эту задачу:
Код

ЗАДАЧА ИзЧисла-(Дней: ЦЕЛ; День+,Месяц+,Год+:ЦЕЛ);
ПЕР
  Веков, Четырёхлеток, Годы, Дни: ЦЕЛ;
ЗАДАЧА ВыделитьМесяцы(Дни, Дней+: ЦЕЛ; Високосн: КЛЮЧ): ЦЕЛ;
ПЕР
  ч, ч1, Год: ЦЕЛ;
  Мес: РЯД 12+1 ИЗ ЦЕЛ;
УКАЗ
  Мес[0] := 0; Мес[1] := 31; ЕСЛИ Високосн
  ТО Мес[2] := 29 ИНАЧЕ Мес[2] := 28 КОН; Мес[3] := 31;
  Мес[4] := 30; Мес[5] := 31; Мес[6] := 30; Мес[7] := 31;
  Мес[8] := 31; Мес[9] := 30; Мес[10] := 31;
  Мес[11] := 30; Мес[12] := 31;
  ЕСЛИ Високосн ТО Год := 366 ИНАЧЕ Год := 365 КОН;
  ОТ ч := 12 ДО 0 ПО -1 ВЫП
    ЕСЛИ Год < Дни ТО Дней := Дни - Год; ВОЗВРАТ ч+1 КОН;
    УМЕНЬШИТЬ(Год, Мес[ч])
  КОН
КОН ВыделитьМесяцы;
УКАЗ
  Веков := (Дней ДЕЛИТЬ (400*365+100*1-4*1+1))*4 + (Дней ОСТАТОК (400*365+100*1-4*1+1)) ДЕЛИТЬ (100*365+25*1-1);
  Четырёхлеток := Веков*25 + Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ДЕЛИТЬ (365*4+1);
  ЕСЛИ Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ОСТАТОК (365*4+1) < 365*3 ТО
    Годы := Четырёхлеток*4 + (Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ОСТАТОК (365*4+1)) ДЕЛИТЬ 365 + 1;
    Дни := (Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ОСТАТОК (365*4+1)) ОСТАТОК 365
  ИНАЧЕ
    Годы := Четырёхлеток*4 + (Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ОСТАТОК (365*4+1) - 365*3) ДЕЛИТЬ 366 + 3 + 1;
    Дни := (Дней ОСТАТОК (400*365+100*1-4*1+1) ОСТАТОК (100*365+25*1-1) ОСТАТОК (365*4+1)) ОСТАТОК 366 + 3
  КОН;
  Месяц := ВыделитьМесяцы(Дни, День, Високосный(Годы));
  ЕСЛИ (Месяц = 0) И (День = 0) ТО
    Месяц := 12; День := 31; Год := Годы - 1
  ИНАЧЕ
    Год := Годы
  КОН
КОН ИзЧисла;

Так что учите Глагол  smile  
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Сый
Дата 30.5.2006, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 131
Регистрация: 23.1.2006

Репутация: 2
Всего: 3



Прошу оценить/протестировать готовую программу:
Код

(******************************************************************************) 
(**)                            ОТДЕЛ Дата;                                 (**) 
(******************************************************************************) 
(* НАЗНАЧЕНИЕ: основные функции для работы с календарём.                      *) 
(******************************************************************************) 

(****************************************************************************** 
 * Вычисляет, является ли год високосным. 
 ******************************************************************************) 
ЗАДАЧА Високосный-(Год: ЦЕЛ): КЛЮЧ; 
УКАЗ 
  ЕСЛИ ((Год ОСТАТОК 4 = 0) И (Год ОСТАТОК 100 # 0)) ИЛИ (Год ОСТАТОК 400 = 0) ТО 
    ВОЗВРАТ ВКЛ ИНАЧЕ ВОЗВРАТ ОТКЛ КОН 
КОН Високосный; 

(****************************************************************************** 
 * Возвращает число дней в указаном месяце. 
 ******************************************************************************) 
ЗАДАЧА ДнейВМесяце(Номер: ЦЕЛ; Високосн: КЛЮЧ): ЦЕЛ; 
УКАЗ 
  ВЫБРАТЬ Номер ИЗ 
    1: ВОЗВРАТ 31 
  | 2: ЕСЛИ Високосн ТО ВОЗВРАТ 29 ИНАЧЕ ВОЗВРАТ 28 КОН 
  | 3: ВОЗВРАТ 31 
  | 4: ВОЗВРАТ 30 
  | 5: ВОЗВРАТ 31 
  | 6: ВОЗВРАТ 30 
  | 7: ВОЗВРАТ 31 
  | 8: ВОЗВРАТ 31 
  | 9: ВОЗВРАТ 30 
  | 10: ВОЗВРАТ 31 
  | 11: ВОЗВРАТ 30 
  | 12: ВОЗВРАТ 31 
  ИНАЧЕ ВОЗВРАТ 0 КОН 
КОН ДнейВМесяце; 

(****************************************************************************** 
 * Переводит дату в число дней, прошедших от начала 1 года н. э. (числовое 
 * представление даты). Года до н. э. (отрицательные или 0) считаются как 1-й 
 * год н. э. 
 ******************************************************************************) 
ЗАДАЧА ВЧисло-(День, Месяц, Год: ЦЕЛ): ЦЕЛ; 
ПЕР 
  Результат, Рез, ч, Счётчик: ЦЕЛ; 
УКАЗ 
  Результат := 0; 
  ОТ Счётчик := 1 ДО Год-1 ВЫП 
    ЕСЛИ Високосный(Счётчик) ТО УВЕЛИЧИТЬ(Результат, 366) ИНАЧЕ УВЕЛИЧИТЬ(Результат, 365) КОН; 
  КОН; 
  ОТ ч := 1 ДО Месяц ВЫП 
    УВЕЛИЧИТЬ(Результат, ДнейВМесяце(ч-1, Високосный(Год))) 
  КОН; 
  ВОЗВРАТ Результат + День 
КОН ВЧисло; 

(****************************************************************************** 
 * Переводит число дней, прошедших от начала 1 года н. э. в дату. 
 * Задачи вГод, вМесяц и вДень возвращают соответственно год, месяц и день 
 * отдельно друг от друга, используя задачу ИзЧисла. 
 ******************************************************************************) 
ЗАДАЧА ИзЧисла-(Дней: ЦЕЛ; День+,Месяц+,Год+:ЦЕЛ); 
ПЕР 
  Годы, Дни: ЦЕЛ; 
ЗАДАЧА ДеньИМесяц(Дн, Дн1+: ЦЕЛ; Високосн: КЛЮЧ): ЦЕЛ; 
ПЕР 
  ч, ч1, Гд: ЦЕЛ; 
УКАЗ 
  ЕСЛИ Високосн ТО Гд := 366 ИНАЧЕ Гд := 365 КОН; 
  ОТ ч := 12 ДО 0 ПО -1 ВЫП 
    ЕСЛИ Гд < Дн ТО Дн1 := Дн - Гд; ВОЗВРАТ ч+1 КОН; 
    УМЕНЬШИТЬ(Гд, ДнейВМесяце(ч, Високосн)) 
  КОН 
КОН ДеньИМесяц; 
УКАЗ 
  ЕСЛИ Дней ОСТАТОК 146097 ОСТАТОК 36524 ОСТАТОК 1461 < 1095 ТО 
    Годы := (((Дней ДЕЛИТЬ 146097) * 4 + (Дней ОСТАТОК 146097) ДЕЛИТЬ 36524) 
            * 25 + Дней ОСТАТОК 146097 ОСТАТОК 36524 ДЕЛИТЬ 1461) 
            * 4 + (Дней ОСТАТОК 146097 ОСТАТОК 36524 ОСТАТОК 1461) ДЕЛИТЬ 365 + 1; 
    Дни := (Дней ОСТАТОК 146097 ОСТАТОК 36524 ОСТАТОК 1461) ОСТАТОК 365 
  ИНАЧЕ 
    Годы := (((Дней ДЕЛИТЬ 146097) * 4 + (Дней ОСТАТОК 146097) ДЕЛИТЬ 36524) 
            * 25 + Дней ОСТАТОК 146097 ОСТАТОК 36524 ДЕЛИТЬ 1461) 
            * 4 + (Дней ОСТАТОК 146097 ОСТАТОК 36524 ОСТАТОК 1461 - 1095) ДЕЛИТЬ 366 + 4; 
    Дни := Дней ОСТАТОК 146097 ОСТАТОК 36524 ОСТАТОК 1461 ОСТАТОК 366 + 3 
  КОН; 
  Месяц := ДеньИМесяц(Дни, День, Високосный(Годы)); 
  ЕСЛИ (Месяц = 0) И (День = 0) ТО 
    Месяц := 12; День := 31; Год := Годы - 1 
    (* Обработка частных случаев *) 
      АЕСЛИ (Месяц = 12) И (День = 31) ТО Год := Годы - 1 
      АЕСЛИ День > 31 ТО Месяц := 12; День := 31; Год := Годы - 1 
      АЕСЛИ Месяц > 12 ТО Месяц := 1; Год := Годы; 
        ЕСЛИ (НЕ Високосный(Годы)) И (Годы ОСТАТОК 100 = 0) И (Месяц = 1) И (День < 4) ТО 
          ЕСЛИ День = 1 ТО 
            Месяц := 12; День := 31; Год := Годы - 1 ИНАЧЕ УМЕНЬШИТЬ(День); Год := Годы КОН 
        КОН 
      АЕСЛИ (Месяц = 0) И (День < 31) ТО Месяц := 12; УВЕЛИЧИТЬ(День) 
  ИНАЧЕ 
    Год := Годы 
  КОН 
КОН ИзЧисла; 

(******************************************************************************) 
ЗАДАЧА вГод-(Дней: ЦЕЛ): ЦЕЛ; 
ПЕР 
  д, м, г: ЦЕЛ; 
УКАЗ 
  д := 0; м := 0; г := 0; 
  ИзЧисла(Дней, д, м, г); 
  ВОЗВРАТ г 
КОН вГод; 

ЗАДАЧА вМесяц-(Дней: ЦЕЛ): ЦЕЛ; 
ПЕР 
  д, м, г: ЦЕЛ; 
УКАЗ 
  д := 0; м := 0; г := 0; 
  ИзЧисла(Дней, д, м, г); 
  ВОЗВРАТ м 
КОН вМесяц; 

ЗАДАЧА вДень-(Дней: ЦЕЛ): ЦЕЛ; 
ПЕР 
  д, м, г: ЦЕЛ; 
УКАЗ 
  д := 0; м := 0; г := 0; 
  ИзЧисла(Дней, д, м, г); 
  ВОЗВРАТ д 
КОН вДень; 

(****************************************************************************** 
 * Возвращает число дней, которое необходимо прибавить к дате, чтобы перевести её 
 * из даты Грегорианского календаря в дату Юлианского календаря (старый стиль), 
 * используя числовое представление текущей даты. 
 ******************************************************************************) 
ЗАДАЧА СтарыйСтиль-(Дней: ЦЕЛ): ЦЕЛ; 
ПЕР 
  Век: ЦЕЛ; 
УКАЗ 
  Век := (Дней ДЕЛИТЬ (400*365+100*1-4*1+1))*4 + (Дней ОСТАТОК (400*365+100*1-4*1+1)) ДЕЛИТЬ (100*365+25*1-1) + 1; 
  ВОЗВРАТ (Век - ((Век - 1) ДЕЛИТЬ 4) - 3) 
КОН СтарыйСтиль; 

(****************************************************************************** 
 * Возвращает номер текущего дня недели (1 - понедельник, ..., 7 - воскресенье), 
 * используя числовое представление текущей даты. 
 ******************************************************************************) 
ЗАДАЧА ДеньНедели-(Дней: ЦЕЛ): ЦЕЛ; 
ПЕР 
  Добав : УЗКЦЕЛ; 
  гггг, мм, дд : ЦЕЛ; 
УКАЗ 
  ИзЧисла(Дней, дд, мм, гггг); 
  ЕСЛИ мм < 3 ТО 
     Добав := 1 
  ИНАЧЕ 
     Добав := 0; 
  КОН; 
  ВОЗВРАТ (( 3 * гггг - (7 * (гггг + (мм + 9) ДЕЛИТЬ 12)) ДЕЛИТЬ 4 + 
          (23 * мм) ДЕЛИТЬ 9 + дд + 2 + ((гггг - Добав) ДЕЛИТЬ 100 + 1) * 
          3 ДЕЛИТЬ 4 - 16) ОСТАТОК 7) + 1 
КОН ДеньНедели; 

КОН Дата.
 
--------------------
 Язык программирования, родственный языкам Паскаль и Оберон, использующий русские служебные слова - Глагол: http://glagol.nad.ru 
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0640 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.