Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дата, Вычислить... 
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   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

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


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

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


 




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


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

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