Bug - Not A Bug today_to_string() returns game date, not system date

fxer

Member
Maybe the wiki description is inaccurate, but it states today_to_string() will return your system date, whereas gameday_to_string() will return the actual kol date. However it's 11:30pm on may 30th on my system, and today_to_string() is returning 20160531. So is today_to_string() actually designed to return the game date converted into a 365 calendar date, and has nothing to do with "local system settings"?
 

fronobulax

Developer
Staff member
Code:
public static Value today_to_string( Interpreter interpreter )
	{
		return new Value( KoLConstants.DAILY_FORMAT.format( new Date() ) );
	}

I note with some amusement that the code was last edited in 2008.

new Date() allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond. The date is then formatted to yyyyMMdd using the US for any localization required. I'm not sure when/why the formatting would round vs. truncate but I am comfortable in saying that what you are seeing is a Java feature not deliberately modified by KoLmafia.

The time at which the Date object was allocated is casually referred to as "now" or the system date as reported by your computer. I think your hypothesis that the results of today_to_string have anything to do with KoL's concept of "Game Day" are not supported by the code.

I'm willing to treat this as an interesting observation for now rather than look for something to "fix" and I am not sure how I can clarify the wiki entry.
 

xKiv

Active member
I can verify (experimentally) that "KoLConstants.DAILY_FORMAT.format( new Date() )" works off my local time, using the system's time zone.
(I actually tried the same format with time and timezone info included)
Some important points:
- Date doesn't even know which timezone it is in, it's just hours, minutes, seconds, milliseconds.
- I don't know exactly where java gets the idea of current timezone
- java's idea of current timezone doesn't necessarily have to match your system clock's idea of current timezone
- the clock in your computer's GUI doesn't necessarily show time in the same timezone that's default for your system

So, it's possible that your clock is showing, say, 11:30 pm 20160530 in a non-DST timezone, but java is showing the same time as 00:30 am 20160531 DST.
Or java is getting time from hw clock in UTC, while the system knows that you are in, for example, UTC-5.
(this is mostly conjecture though, it shouldn't happen on a properly configured system unless you are stuck with a very old OS)
 

theo1001

Member
Experimented with changing the time on my pc to test this.

Code:
> ash now_to_string("yyyy.MM.dd G 'at' HH:mm:ss z")

Returned: 2016.05.31 AD at 06:29:04 EEST

> ash today_to_string()

Returned: 20160530

Code:
> ash now_to_string("yyyy.MM.dd G 'at' HH:mm:ss z")

Returned: 2016.05.31 AD at 06:31:14 EEST

> ash today_to_string()

Returned: 20160531

p.s: 6:30 AM is when rollover is for me.
 

fxer

Member
Used the below piece of code to verify java 8 on win 10 outputs my proper system date. fronobulax mentioned the code hasn't been updated since 2008, I know java 8 got a huge new Date and Time API, maybe that changed something?

Code:
import java.util.Date;                                                                                                                     
public class Dte {

    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date.toString());
    }   
}

I can also confirm theo1001's test with setting my clock to a minute before and a minute after rollover (8:30PM PDT for me)

Code:
> ash     now_to_string("yyyy.MM.dd G 'at' HH:mm:ss z")

Returned:     2016.05.31 AD at 20:29:43 PDT

> ash     today_to_string()

Returned: 20160531

Code:
>     ash now_to_string("yyyy.MM.dd G 'at' HH:mm:ss z")

Returned:     2016.05.31 AD at 20:32:03 PDT

>     ash today_to_string()

Returned: 20160601
 
Last edited:

xKiv

Active member
Does mafia change its timezone to match kol rollover "timezone" ?


now_to_string uses "new GregorianCalendar()" formatted using "new SimpleDateFormat( the format paramete value here )" instantiated every time.

today_to_string uses "new Date()" formatted using "new SimpleDateFormat( "yyyyMMdd", Locale.US )" instantiated as constant (i.e. once)

Two differences here:
1) Date isn not timezone-aware, GregorianCalendar is timezone-aware.
2) using pre-instantiated formatter vs. using newly instantiated formatter



Oh look, KolMafia.main (at lines 296 toi 298 in my workspace) does this:
Code:
TimeZone koltime = (TimeZone) TimeZone.getTimeZone( "GMT-0330" );

KoLConstants.DAILY_FORMAT.setTimeZone( koltime );

Mystery explained.
 

fronobulax

Developer
Staff member
OK. There is a discrepancy between the wiki and the code behavior. If it were up to me I would modify the code so that today_to_string() returned the no kidding local time, using all the computer's defaults and time zone information. I would spot check some of the other time functions to verify that they use local settings and change them if they didn't. That would satisfy my OCD tendencies.

But, we could just edit the wiki - an asterisk or something - and leave the code alone. That has the advantage that if there is anyone unintentionally relying on the behavior they will continue to be able to do so.

Thoughts?

I suspect this is well within my capacity to implement and test over the weekend...
 

xKiv

Active member
The current functionality of today_to_string is useful (for example last new years, when I had a condition in my logout script to remove pants; also because it is the same for everyone in the world at the same moment).
Can't do the same things with gameday_to_int, because that returns "( dayDifference + 96 ) % 96;" - index of the current day-of-kol-calendar-year.
And gameday_to_string simply translates gameday_to_int ti the name of the day in kol's calendar (i.e. "Jarlsuary 1").

My conclusion: the only needed change is on the wiki;
today_to_string is meant to unambiguously identify current kol day (rollover-to-rollover) in a human readable way
local time (using the user's computer's timezone) is time_to_string or now_to_string
date and time (in seconds from rollover) within kol's 96-day calendar are gameday_to_string, gameday_to_int, gametime_to_int
I can't tell if there's a "number of days since some fixed rollover"
 

theo1001

Member
One thing to note is that rollover happens at 8:30 p.m. (Arizona time), not midnight so the date is still technically wrong.

Items that change effects based on the day of the week (Tuesday's ruby, potion of the field gar) do not change their effects until midnight, so presumably that is when the (real world) date changes in KoL.

Still i can't think of any possible use i'd have for the function so having it either way is fine.
 

Veracity

Developer
Staff member
Considering that all sorts of thing depend on KoL server date/time, it is completely intentional that we return that to your script. If we returned your real local time, I confidently expect that we'd get bug reports because script expectations based on time did not agree with KoL.
 

xKiv

Active member
One thing to note is that rollover happens at 8:30 p.m. (Arizona time), not midnight so the date is still technically wrong.

It's technically and factually correct in the (artificial) timezone that has midnight at rollover. Which is the only timezone that matters for identifying kol days.
 

fxer

Member
Considering that all sorts of thing depend on KoL server date/time, it is completely intentional that we return that to your script. If we returned your real local time, I confidently expect that we'd get bug reports because script expectations based on time did not agree with KoL.

I currently use today_to_string() to uniquely identify a kol date in a big map, so the current functionality is perfect for me.

I just updated the wiki pages for both today_to_string() and gameday_to_string() (which had a similar, inaccurate note about system time). Anyone feel free to edit it if you have a better description
 

xKiv

Active member
I just thought of one more time/date thing that can/should be tracked (and I don't know if/how mafia does it).
Tuesday's ruby, potion of the field gar, and maybe a couple other things depend on server's day-of-week in (iirc) arizona time. Unless that changed with the cloud move.
 

heeheehee

Developer
Staff member
I just thought of one more time/date thing that can/should be tracked (and I don't know if/how mafia does it).
Tuesday's ruby, potion of the field gar, and maybe a couple other things depend on server's day-of-week in (iirc) arizona time. Unless that changed with the cloud move.

Doesn't look like it. Tuesday's ruby has +5% item drops (Thursday's effect), even though it's currently Friday where the servers are now.
 

fronobulax

Developer
Staff member
Considering that all sorts of thing depend on KoL server date/time, it is completely intentional that we return that to your script. If we returned your real local time, I confidently expect that we'd get bug reports because script expectations based on time did not agree with KoL.

Since my fingerprints circa 2012 are all over the ash time functions, I am probably to blame. Looking at the code I see today_to_string, now_to_string_ and gameday_to_string. At some point the differences got obscured.

today_to_string gets the current time in the KoL server time zone and this can be used for rollover calculations and any other KoL function that depends upon the real world calendar.

now_to_string gets the current time according to the user's computer. This is local time without regard to KoL.

gameday_to_string gets the current time as expressed in the KoL Calendar and is for things that depend on the internal calendar.

So this is definitely an issue with incorrect/incomplete documentation (and not code) since there is a clear intent to deal with three distinct cases. As usual, I made a couple of comments after five minutes of investigation and ten minutes would have lead me to a different, and more correct solution.
 
Top