Calendar Extension

There doesn’t seem to be an extension for a calendar that keeps track of days (months, years) as well as minutes. Am I really the first person who has ever wanted to keep track of more than 24 hours of time?

Anyhow, if there isn’t one, I’ll have to code one myself. It seems simple enough to start with this:

The day is a number that varies. At 12:00 AM: now the day is the day + 1.

But there’s a major problem: If you ever skip time with “increase the time of day…” or similar, you may skip 12:00 AM and the day won’t increment. How can I check whether 12 AM has passed, regardless of whether or not it has actually been 12 AM?

Replace your “increase the time of day” lines with a procedure that checks for the passage of midnight?

If I remember correctly, that’s not the only problem. A rule that fires “at 12AM” will only fire the first time it’s 12AM, not on subsequent days.

Maybe you can use a new kind of value for date-times, and replace the advance time rule and the “time of day” variable to make use of it.

Interesting. I did not know that about every time trigger only firing once per game. There must be a way to reset that during the game, I would hope.

Anyway, to roll the day counter over every day at midnight, I tested and confirmed this works:

[code]“A Clock Strikes Midnight”

Use no scoring.

Clockless is a room. “Despite there being no clocks immediately visible, somehow, you can sense the precise time. Freaky.” The time of day is 11:45 PM. The previous time is a time that varies. The previous time is 11:44 PM. The day is a number that varies. The day is one.

When play begins:
now the right hand status line is “Day [day], [time of day]”.

Every turn:
let the previous day be the day;
if the previous time is before 12:00 AM:
if the time of day is after 11:59 PM:
increase the day by 1;
if the time of day is before the previous time:
increase the day by 1;
otherwise if the time of day is before the previous time:
if the time of day is after 11:59 PM:
increase the day by 1;
if the day is not the previous day:
say “You sense that somewhere, a clock has since struck midnight.”;
now the previous time is the time of day.

After waiting for the seventh time: say “Time passes.[paragraph break]You’re feeling a little brrzap-y.”

Before waiting more than 20 times: instead try brrzapping.

Brrzapping is an action applying to nothing. Understand “brrzap” as brrzapping.

Carry out brrzapping for the first time: now the time of day is 3:17 AM.
Carry out brrzapping for the second time: now the time of day is 2:33 AM.
Carry out brrzapping for the third time: now the time of day is 11:05 AM.
Carry out brrzapping for the fourth time: now the time of day is 7:51 AM.
Carry out brrzapping for the fifth time: now the time of day is 5:14 PM.
Carry out brrzapping for the sixth time: now the time of day is 1:30 AM.
Carry out brrzapping for the seventh time: now the time of day is 11:44 PM.

Report brrzapping: say “BRRZAP!”

Carry out brrzapping for the eight time:
say “BRRRRRZZAP!!”;
now the left hand status line is “”;
now the right hand status line is “Timeless”;
end the story saying “You have brrzapped right out of existence.”[/code]
The solution was made a fair bit more complex by Inform’s odd choice of considering times between 12:00 AM and 3:59 AM to be ‘after’ all the other times, rather than before them. But this seems to work correctly even when the time is shifted by large increments (by typing ‘BRRZAP’).

Caveats: This solution assumes: that any time jumps are of less than 24 hours (in the case of jumping more than 24 hours, you’d have to add more to the day counter manually); and that all time jumps go forwards only (in the case of the player travelling backwards in time, you’d have to manually subtract a number of days from the jump-forward day, rather than from the current day).

There may well be a more elegant solution, but I’m new to i7 and this was the best I could do with present knowledge.

Paul.

P.S. Due to the ‘every turn’ routine running before the game time advances rather than afterward, my clock striking can appear to the player to happen a minute late, at 12:01. It wasn’t immediately obvious to me how to finetune that. Also, I wonder if there is a way in i7 to test if a time is ‘on or before’ / ‘on or after’ another time…

I made my own extension for handling real time events.

Here is the part that concerns new time values, maybe you can get some inspiration from it (and this is still just a draft):

Book 1 - Dates, short times, concise times and concise dates

Part  1 - New kinds of value

Chapter A - Dates

Section 1 - What a date is

A date is a kind of value.
2012/12/31 specifies a date with parts years, months and days.
12/31 specifies a date with parts months and days.	

Section 2 - Printing a date

Section 3 - Deciding what date is the date of day

To decide what date is the/-- date of day:
	decide on the date with years part (years of day) months part (months of day) days part (days of day);




Chapter B - Short times

Section 1 - What a short time is

A short time is a kind of value.
59'9 specifies a short time with parts seconds and deciseconds.

Section 2 - Printing a short time

To say (target - a short time):
	say "[if seconds part of target < 10]0[end if]", seconds part of target, "[unicode 8242]", deciseconds part of target;

Section 3 - Deciding what short time is the short time of day
	



Chapter C - Concise times

Section 1 - What a concise time is

A concise time is a kind of value.
23:59:59'9 specifies a concise time with parts hours, minutes, seconds and deciseconds.

To decide what time is the/-- time part of (target - a concise time):
	decide on (minutes part of target) minutes after (hours part of target) hours.
To decide what short time is the/-- short time part of (target - a concise time):
	decide on the short time with seconds part (seconds part of target) deciseconds part (deciseconds part of target).

Section 2 - Printing a concise time

To say (CT - concise time):
	say "[time part of CT]:[short time part of CT]".

Section 3 - Deciding what concise time is the concise time of day

To decide what concise time is the/-- concise time of day:
	decide on the concise time with hours part (hours part of the time of day) minutes part (minutes part of the time of day) seconds part (seconds part of the short time of day) deciseconds part (deciseconds part of the short time of day);

[°°°° value too big
Chapter D - Concise dates

Section 1 - What a concise date is

A concise date is a kind of value.
2012/12/31 23:59:59'9 specifies a concise date with parts years, months, days, hours, minutes, seconds and deciseconds.
2012/12/31 23:59:59 specifies a concise date with parts years, months, days, hours, minutes and seconds.
2012/12/31 23:59 specifies a concise date with parts years, months, days, hours and minutes.
2012/12/31 23 specifies a concise date with parts years, months, days and hours.

To decide what time is the/-- time part of (target - a concise date):
	decide on (minutes part of target) minutes after (hours part of target) hours.
To decide what date is the/-- date part of (target - a concise date):
	decide on the date with years part (years part of target) months part (months part of target) days part (days part of target).
To decide what short time is the/-- short time part of (target - a concise date):
	decide on the short time with seconds part (seconds part of target) deciseconds part (deciseconds part of target).
To decide what concise time is the/-- concise time part of (target - a concise date):
	decide on the concise time with hours part (hours part of target) minutes part (minutes part of target) seconds part (seconds part of target) deciseconds part (deciseconds part of target).

Section 2 - Printing a concise date

Section 3 - Deciding what concise date is the concisme date of day

To decide what concise date is the/-- concise date of day:
	[decide on the concise date with years part (the years of day) months part (the months of day) days part (the days of day) hours part (hours part of the time of day) minutes part (minutes part of the time of day) seconds part (seconds part of the short time of day) deciseconds part (deciseconds part of the short time of day).]
	decide on 2010/04/01 15:54:0'0;
]



Part 2 - Comparing

Chapter A - Before

Section 1 - Short times vs short times

To decide whether (st - a short time) is before (st2 - a short time):
	if st is less than st2:
		decide yes;
	else:
		decide no;
To decide whether (st - a short time) is after (st2 - a short time):
	if st less than st2:
		decide no;
	else:
		decide yes;

Section 2 - Short times vs times

[
To decide whether (st - a short time) is before (t - a time):
		decide .[        here !]
To decide whether (st - a short time) is after (t - a time):
	if st is before t:
		decide no.
To decide whether (t - a time) is before (st - a short time):
	if st is before t:
		decide no.
To decide whether (t - a time) is after (st - a short time):
	if st is before t:
		decide yes;
]

Section 3 - Short times vs concise times

To decide whether (st - a short time) is before (ct - a concise time):
	if st is less than the short time part of ct:
		decide yes;
	else:
		decide no;
To decide whether (st - a short time) is after (ct - a concise time):
	if st is before ct:
		decide no;
	else:
		decide yes;
To decide whether (ct - a concise time) is before (st - a short time):
	if st is before ct:
		decide no;
	else:
		decide yes;
To decide whether (ct - a concise time) is after (st - a short time):
	if st is before ct:
		decide yes;
	else:
		decide no;

Section 4 - Concise times vs times

To decide whether (ct - a concise time) is before (t - a time):
	if the time part of ct is before t:
		decide yes;
	else:
		decide no;
To decide whether (ct - a concise time) is after (t - a time):
	if ct is before t:
		decide no;
	else:
		decide yes;
To decide whether (t - a time) is before (ct - a concise time):
	if ct is before t:
		decide no;
	else:
		decide yes;
To decide whether (t - a time) is after (ct - a concise time):
	if ct is before t:
		decide yes;
	else:
		decide no;

Section 5 - Concise times vs concise times

To decide whether (ct - a concise time) is before (ct2 - a concise time):
	if the time part of ct is before the time part of ct2:
		decide yes;
	else if the time part of ct is the time part of ct2:
		if the short time part of ct is less than the short time part of ct2:
			decide yes;
	else:
		decide no.
To decide whether (ct - a concise time) is after (ct2 - a concise time):
	if ct is before ct2:
		decide no;
	else:
		decide yes;




Part 3 - Before and after TODO

To decide what concise time is (ct - concise time) after (delta - concise time):
	decide on ct plus delta;


Part 4 - At (TODO)

To At (ct - a concise time) sharp:
	say "TODO";


Part 5 - Hacking the time printing routine

Include(-
	! This is the Original PrintTimeOfDay routine.
	#ifndef TWENTYFOUR_HOUR_TIME;
	[ PrintTimeOfDay t h aop;
		if (t<0) { print "<no time>"; return; }
		if (t >= TWELVE_HOURS) { aop = "pm"; t = t - TWELVE_HOURS; } else aop = "am";
		h = t/ONE_HOUR; if (h==0) h=12;
		print h, ":";
		if (t%ONE_HOUR < 10) print "0"; print t%ONE_HOUR, " ", (string) aop;
	];
	#ifnot;
	[ PrintTimeOfDay t h aop;
		if (t<0) { print "<no time>"; return; }
		if (t >= TWENTY_FOUR_HOURS) {  t=t-TWENTY_FOUR_HOURS; }
		h = t/ONE_HOUR;
		print h, ":";
		if (t% ONE_HOUR <10) print "0"; print t% ONE_HOUR;
	];
	#endif;
-) instead of "Digital Printing" in "Time.i6t".

It’s not that unusual. It means that Inform either a) is or b) is not time zone aware, depending on the underlying implementation. I’d be willing to bet that three weeks from now you’ll find the same behavior applying between 12:00 AM and 4:59 AM. I suspect you could test it by temporarily changing your computer’s active time zone.

4:00 am is specifically mentioned in the Inform 7 manual as a turnover time that was chosen to conform to people’s expectations of what is meant by an early time or a late time. Inform just considers 4am as the division point between days rather than midnight. What I meant by odd is that I think it’s odd to expect all good IF characters to go to bed by 4am. It doesn’t actually simplify anything – it just moves it – and it obfuscates something that was formerly generally understood, as this thread demonstrates. But hey, I can live with it. 8)

Paul.

Wow. I even went to the trouble of looking up Toronto’s time zone just to make sure I wasn’t making things up.

Take that, Occam’s Razor!

Heh heh — I just recently read through the manual for the first time, so it’s fresh in my mind, particularly the oddities. 87

What I came up with was very much like what Laroquod has; the main difference is that instead of comparing times, I just compared hours. The plus is that it gets around the 4:00 problem.

The minus is that, if you increase the time of day past midnight (but not if you set it to a specific time), it will register as an hour past 24 for that turn (although the time of day displays correctly). The next turn it will correct itself and increment the day. Any ideas why it would do this?

I called the date “current day, current month, current year” rather than “day, month, year” to allow for the inclusion of other dates (say, a character’s birthday).

[code]Month is a kind of value.
The months are January, February, March, April, May, June, July, August, September, October, November, and December.
A month can be short, leap, medium, or long. A month is usually long.
February is short.
April, June, September, and November are medium.
The current day is a number that varies.
The current month is a month that varies.
The current year is a number that varies.

The current day is 31.
The current month is August.
The current year is 2010.
The time of day is 8:00 PM.

The current hour is a number that varies.
The last hour is a number that varies.
The current hour is 20.
The last hour is 20.

Every turn (this is the time increment rule):
now the last hour is the current hour;
now the current hour is the hours part of the time of day;
if the current hour < the last hour:
increment the current day;
if the current month is short:
Let X be the current day - 28;
if X > 0:
increment the current month;
now the current day is X;
if the current month is medium:
Let X be the current day - 30;
if X > 0:
increment the current month;
now the current day is X;
if the current month is long:
Let X be the current day - 31;
if X > 0:
if the current month is December:
now the current month is January;
increment the current year;
otherwise:
increment the current month;
now the current day is X.

The Bedroom is a room. “The perpetual mess serves as a deterrent to adults.”

The clock is in the bedroom. “A clock hangs on the wall. Each tick brings with it a foreboding sense of doom.”

Instead of examining the clock:
say “The current hour is [current hour].”;
say “It’s [the time of day].”

The calendar is in the bedroom. “There’s also a calendar, as if you needed to be reminded.”

Instead of examining the calendar:
say “It’s [the current month] [the current day], [the current year].”;
if the current month is September:
if the current day is 1:
if the current hour > 8:
say “[first time]Oh no! You’ve missed the first day of school![only]”

Instead of waiting:
say “You procrastinate.”;
let X be a random number between 30 and 120;
increase the time of day by X minutes.

Instead of sleeping:
say “You go back to sleep.”;
now the time of day is a random time.

Test calendar with “examine clock / examine calendar / sleep / examine clock / examine calendar / wait / examine clock / examine calendar / sleep / sleep / examine calendar”.[/code]

I was trying to get a properly formatted date to work, but I couldn’t figure out how to make the numerical month and the named month be recognized as the same thing.

Ish McGravin’s “Weather” extension has calendar capabilities. It’s worked well for me, although IIRC, I did need to make a bug-fix in the year-turn over so it happened on January 1st and not February 1st. (It’s been awhile, so it might have been an introduced bug via some special conditions - still worth double-checking that area.)

It has extra stuff (notably the titular weather), but it would be trivial to strip that out.

What it doesn’t have is the ability to easily tell how much time has passed since a certain time. It’s on my list of things to-do, but surprisingly complicated, given that the extension has separate tracking for months, days, and years.