|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Edit: another example of something that should return back to the original time, and it does with timeapi off, but with /timeapi on, it goes back in time 10 hours, which i assume is due to my timezone's local time adjusted for daylight is GMT-5 Ack. This was harder to track down than I expected. There are quite a few API calls involved in converting between unix/system/file times, some of which apply offsets themselves, and the drop-ins can call each other in some cases. This issue has hopefully been fixed for the next version.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
Nope, don't have experience with it. When you say "you are expecting", are you implying that I'm expecting something I shouldn't? If your effective timezone right now is GMT+0 you won't see the entire effect I'm seeing. And someone else tested XP and saw the same effects I was describing earlier, except it was doubling their GMT offset instead of mine.
//var -s %a Jan 01 12:00:00 2019 | timeapi off | var %aoff $ctime(%a) | timeapi on | var %aon $ctime(%a) | echo -a $calc(%aon - %aoff ) | var -s %a Jun 01 12:00:00 2019 | timeapi off | var %aoff $ctime(%a) | timeapi on | var %aon $ctime(%a) | echo -a $calc(%aon - %aoff )
There 2 effects going on, and I'm not sure that $asctime can be blamed for both. The 1 hour offset seems to be a problem in $asctime(N) where it never transitions on/off daylight time. However the above code doesn't use $asctime at all, and it's showing a 1 hour effect.
When clock is set to USA Central with the current date during daylight time, the GMT offset is -5. The above snippet shows -39600 then -36000, or -11 hrs and -10 hrs. When clock is set backwards 1 month to be in standard time where GMT offset is -6, the results are -43200 then -39600, or -12hrs and -11hrs.
So it looks like there's a 1 hour issue in both $asctime and $ctime, as well as a doubling of the GMT offset for $ctime(string)
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Nope, don't have experience with it. When you say "you are expecting", are you implying that I'm expecting something I shouldn't? I was hoping you would know what I'd need to do in this case to return the result that you think is right. At this point, I am not convinced I know enough about this subject to be sure. After spending the last week reading about timezones and DST, I have come away thinking that its not as simple as it sounds, eg. deciding between prior or subsequent DST states at DST transition points, historical DST, dynamic DST, matching ISO timezone/DST rules, updating to the latest rules, CRT functions not supporting the latest changes (currently using Visual Studio 2008), Windows APIs not supporting these except in recent versions, libraries specifically written to handle timezone/DST not working correctly, leap seconds only applying prior to 1970 (although Windows 10 now includes them in API results), and so on. Regarding /timeapi on|off: I thought this would be useful to allow comparisons between the CRT and API results. However, as the APIs are more up-to-date, the results may actually differ, not to mention that they may return different results on different versions of Windows. That said, the new API implementation does have several bugs and I have implemented fixes in the next version, so we will have to see how that turns out.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
Can you confirm beta 907 is using the new API? I can't find any differences in $asctime compared to no-beta, but /timeapi no longer reports any messages to indicate if it's switching the API on/off.
What makes it look like the new API isn't enabled is that the no-differences also includes reverting to the old behavior of $asctime(N) not recognizing negative numbers or $ctime(string) not recognizing dates prior to 1970.
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Can you confirm beta 907 is using the new API? I can't find any differences in $asctime compared to no-beta, but /timeapi no longer reports any messages to indicate if it's switching the API on/off. The /timeapi command is showing the on/off message here for me with beta 907.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
sorry. i got bit by an alias i was trying to use that could run the timeapi in both beta and nobeta.
I'm not yet seeing any issues with $asctime, but $ctime is translating date strings in the opposite daylight zone to a different N than before, which results in a 1 hour earlier difference when translating a january timestring to N, then using asctime back to timestring:
//var -s %a $ctime(jan 29 12:34:56 2019) , %b $asctime(%a)
In nobeta this returns to 12:34:45, but in 907 it displays 1 hour earlier at 11:34:56
The difference is in the N created by $ctime(string) not in the string returned by $asctime(N)
Nobeta reported $ctime(Jan 01 00:00:00 1970) as 21600, reflecting the wintertime GMT-6 offset of USA Central's standard time. 907 reports it as 18000 reflecting the current date's GMT-5 daylight offset.
The difference localizes to the hour when time transitions between daylight and standard time. The following reports 3600 in nobeta, but 7200 in 907:
//var -s %a $ctime(mar 10 03:00:00 2019) , %b $ctime(mar 10 01:00:00 2019) , %c %a - %b
I got mirc to crash while testing negative dates, so trying to localize where the culprit lies.
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Just to confirm: do you mean that these issues are happening with /timeapi on or off or both?
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
sorry for not being clear. the most recent report was with /timeapi ON
my prior statements about not finding any differences vs nobeta was because that alias had me frozen in OFF mode.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
update: looks like the beta 907 crash was due to $asctime(N) using N which is either too large positive or too large negative. I had used a loop where I had assumed an echo error would break out of the loop when $asctime(N) returned $null for being out of range. But instead it crashed when N went too far below range.
For negatives, as it continues further away from zero, it continues displaying time string Jan 01 1601 00:00:00 for a large range of negatives below the N belonging to that time string. However, it crashed when the N became too far below zero. The next line displayed for me, but changing -29228 to 29229 generated a crash.
//var -s %a $calc(-11644452000+365.2425*86400* -29228) | echo -a $asctime( %a )
For large positives, the new API supports years up through 9999, but crashes for any timestring displaying later than Dec 31 9999 23:59:59, so crashing the next command would require changing "*0" to another integer which would depend on the timezone.
//var -s %a $calc(253402300800+3600*0 ) | echo -a $asctime( %a )
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
looks like the beta 907 crash was due to $asctime(N) using N which is either too large positive or too large negative. Thanks, I was able to reproduce this. This is due to the strftime() function in the CRT which needs to be used even with "/timeapi on" because there is no API replacement for it. Unfortunately, it has the same issue as other CRT functions; it performs invalid parameter checks and terminates an application if parameters aren't within the range it expects, instead of just returning an error to the caller. One solution would be to disable invalid parameter asserts in the CRT using _set_invalid_parameter_handler(). But this would affect all CRT function calls in the release version. On the one hand, this would prevent mIRC from crashing in such situations. On the other hand, we wouldn't know that there was an error. That said, I am only able to get it to crash if the time value is beyond year 9999. If the time value is below year 1601, no crash occurs here; localtime() adjusts the time value to a minimum of 1601. So even with the invalid parameter handler, it would not be possible to detect if a date less than 1601 was supplied. So the only way to prevent/detect errors with strftime() seems to be check if the tm structure being passed to strftime() contains a date range close to the minimum 1601/maximum 9999 dates and, if so, to not call strftime(). Not a great solution but I can't think of any other options at this point. This will be in the next version.
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
$ctime is translating date strings in the opposite daylight zone to a different N than before Okay, I think we're getting there :-) Added another check to my unit test. Fixed in the next version.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
Doesn't crash now for high or low date values, and I'm not seeing any of my examples above messing up. All examples assume: /!timeapi on
Highest value it now displays is 2 seconds before midnite at the end of year 9999.
//var -s %a $calc(253402300800+3600*05+3598 ) | echo -a $asctime( %a )
(The 05 depends on the timezone offset from GMT, and so will the 06 number below)
Lowest displayed value is 1 second after midnite 1/1/1601
//var -s %a $calc(-11644473600+3600*06+1) | echo -a $asctime( %a )
While there aren't any out of range crashes, there is a recurring pattern of wildly invalid N's which are returning not-null strings as if they're within range:
//var %i -500000 | while (%i < 500000) { var %a $calc(-11644452000+365.2425*86400* %i) , %time $asctime(%a) | if (%time) echo -a %i $asctime( %a ) | inc %i }
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Thanks for testing it out. While there aren't any out of range crashes, there is a recurring pattern of wildly invalid N's which are returning not-null strings as if they're within range: Overflow due to conversions in various Windows APIs. I could add a range check in $asctime() to prevent it from returning a result in the above example. That said, you can reproduce similar overflow issues in pretty much every identifier.
|
|
|
|
Joined: Jan 2004
Posts: 2,127
Hoopy frood
|
OP
Hoopy frood
Joined: Jan 2004
Posts: 2,127 |
The overflows are gone in beta 1211.
Just an observation that, while the new API expanded the range for $asctime(N) from the 2nd second of 1601 thru the last second of 9999, the range for $ctime(date-string) remains the same. For me, valid limits are:
//!timeapi on | var -s %hi_valid $ctime(Jan 01 01:59:59 3001) , %low_valid $ctime(Jan 01 00:00:00 1970)
//!timeapi on | var -s %hi_invalid $ctime(Jan 01 02:00:00 3001) , %low_invalid $ctime(Dec 31 23:59:59 1969)
I'm guessing the higest valid ctime(date) conversion depends on your offset from USA Pacific.
|
|
|
|
Joined: Dec 2002
Posts: 5,473
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 5,473 |
Thanks, this should be fixed in the next beta.
|
|
|
|
|