ИнформАрхив QSP
Календарь по методу счёта Юлианский дней
Календарь по рецепту evp. Синтетическая статья, основанная на серии сообщений.
Давным-давно были разработаны формулы для вычисления точной календарной даты из Юлианской даты. Юлианская дата — это число, показывающее, сколько точно прошло дней, начиная с полудня понедельника 24 ноября 4714 года до нашей эры.
Для тех, кто интересуется теорией, на википедии есть замечательная статья, всё подробно разъясняющая. Нас же интересуют непосредственно формулы, и что мы из них можем получить.
evp уже переложил все необходимые расчёты на QSP. Следующий код достаточно просто скопировать на отдельную локацию, и его можно тут же начать использовать. Для примера, будем считать, что данный код находится на локации "calendar"
.
hour = (time/60) MOD 24
minut = time MOD 60
weekday = (JDN MOD 7) + 1
JDa = JDN + 32044
JDb = (4*JDa + 3)/146097
JDc = JDa - (146097*JDb/4)
JDd = (4*JDc + 3)/1461
JDe = JDc - 1461*JDd/4
JDm = (5*JDe + 2)/153
day = JDe - (153*JDm+2)/5 + 1
month = JDm + 3 - 12*(JDm/10)
year = 100*JDb + JDd - 4800 + JDm/10
$hour_text = iif (hour < 10, '0<<hour>>', '<<hour>>')
$minut_text = iif (minut < 10, '0<<minut>>', '<<minut>>')
В самом начале игры нам нужно задать переменные JDNStart
и time
. Именно эти переменные будут хранить точное значение времени в нашей игре.
JDNStart
показывает, когда наша игра должна начаться. Эта переменная содержит число дней, прошедших с полудня понедельника 24 ноября 4714 года д.н.э и до начала нашей игры.
К примеру, наша игра должна начаться 7 ноября 1917 года, в среду. Открываем калькулятор. Подставляем в нужные поля дату 7 ноября 1917, а время пишем 12 часов 00 минут 00 секунд. Юлианский день начинается с полудня! И получаем число 2421540. Точное, без дробной части, число дней.
Это самое число и есть наш JDNStart
, вот и записываем 2421540 в переменную.
А в переменную time
мы записываем, соответственно, число минут, прошедших с начала стартового дня нашей игры (не от полудня, а от полуночи). Например, наша игра стартует в 15:37. Значит с начала дня прошло 15 часов 37 минут, и значит на старте игры мы должны в переменную time
записать число 15*60+37
.
Итого мы будем иметь две строчки кода на самой первой локации в нашей игре, описывающие время:
time=15*60+37
Помимо JDNStart
и time
на самой первой локации нужно ещё прописать в отдельные массивы текстовое представление для дней недели и месяцев:
$weekday_text[2] = 'Вторник'
$weekday_text[3] = 'Среда'
$weekday_text[4] = 'Четверг'
$weekday_text[5] = 'Пятница'
$weekday_text[6] = 'Суббота'
$weekday_text[7] = 'Воскресенье'
$month_text[1] = 'Январь'
$month_text[2] = 'Февраль'
$month_text[3] = 'Март'
$month_text[4] = 'Апрель'
$month_text[5] = 'Май'
$month_text[6] = 'Июнь'
$month_text[7] = 'Июль'
$month_text[8] = 'Август'
$month_text[9] = 'Сентябрь'
$month_text[10] = 'Октябрь'
$month_text[11] = 'Ноябрь'
$month_text[12] = 'Декабрь'
И вот теперь всё готово для того, чтобы мы могли пользоваться полноценным календарём в нашей игре.
Дальше всё просто. Каждый раз, когда мы совершаем действие, которое должно занять какое-то время, в коде этого действия необходимо предусмотреть изменение переменной time
. Например:
time += 45
gt 'smolny'
end
Нажав на действие, мы изменим значение переменной time
, т.е. переместимся во времени на 45 минут, и с помощью оператора goto
переместимся на локацию "smolny"
.
Чтобы увидеть то самое изменение времени на экране, мы должны просто вызвать код локации "calendar"
, чтобы все значения пересчитались, а затем вывести нужные значения на экран. Например, так:
*nl $weekday_text[weekday] + ',' + day + $month_text[month] + ' ' + year + 'года' + '. ' + $hour_text + ':' + $minut_text
Этот алгоритм хорошо работает на датах от 1 г. н.э. и дальше. Но если мы хотим его использовать для отображения дат до нашей эры, то нужно добавить вот эту строчку в самый конец локации "calendar"
:
Это становится необходимым, если вы действительно хотите, чтобы отображение дат полностью соответствовало Григорианскому календарю. Дело тут в том, что алгоритм вычисляет астрономический счет лет, при котором за -1-м годом следует нулевой год, а затем 1-й год. В Григорианском же календаре принято, что первому году н.э. предшествовал 1-й год до н.э. Нулевого года в Григорианском календаре нет.
Для закрепления понимания того, как это всё работает, напишите несколько локаций:
Локация "smolny"
*nl $weekday_text[weekday] + ', ' + day + ' ' + $month_text[month] + ' ' + year + 'года' + '. ' + $hour_text + ':' + $minut_text
act 'Ехать на вокзал':
time += 45
gs 'calendar'
gt 'station'
end
Локация "station"
*nl $weekday_text[weekday] + ', ' + day + ' ' + $month_text[month] + ' ' + year + 'года' + '. ' + $hour_text + ':' + $minut_text
act 'Ехать в Смольный':
time += 45
gs 'calendar'
gt 'smolny'
end
act 'Ехать в Москву (время в пути 1 сутки, 3 часа)':
time += 1620
gs 'calendar'
gt 'moscow'
end
Локация "moscow"
*nl $weekday_text[weekday] + ', ' + day + ' ' + $month_text[month] + ' ' + year + 'года' + '. ' + $hour_text + ':' + $minut_text
act 'Ехать в Питер (время в пути 1 сутки, 3 часа 45 минут)':
time += 1665
gs 'calendar'
gt 'station'
end
В стартовой локации напишите этот код:
JDNStart=2421540
time=3*60+37
! прописываем в массив названия месяцев и дней недели
$weekday_text[1] = 'Понедельник'
$weekday_text[2] = 'Вторник'
$weekday_text[3] = 'Среда'
$weekday_text[4] = 'Четверг'
$weekday_text[5] = 'Пятница'
$weekday_text[6] = 'Суббота'
$weekday_text[7] = 'Воскресенье'
$month_text[1] = 'Январь'
$month_text[2] = 'Февраль'
$month_text[3] = 'Март'
$month_text[4] = 'Апрель'
$month_text[5] = 'Май'
$month_text[6] = 'Июнь'
$month_text[7] = 'Июль'
$month_text[8] = 'Август'
$month_text[9] = 'Сентябрь'
$month_text[10] = 'Октябрь'
$month_text[11] = 'Ноябрь'
$month_text[12] = 'Декабрь'
! пересчитываем значения времени
gs 'calendar'
! переносимся в Смольный
gt 'smolny'
Пробуйте запустить и следите за датой 🙂