Matrix Games Forums

Forums  Register  Login  Photo Gallery  Member List  Search  Calendars  FAQ 

My Profile  Inbox  Address Book  My Subscription  My Forums  Log Out

[Fixed] Large negative epoch times not handled correctly

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Tech Support >> [Fixed] Large negative epoch times not handled correctly Page: [1]
Login
Message << Older Topic   Newer Topic >>
[Fixed] Large negative epoch times not handled correctly - 3/22/2021 6:04:03 AM   
musurca

 

Posts: 128
Joined: 7/16/2020
Status: offline
Here's a fun one: passing a negative epoch time smaller than -43200 to os.date() in the current CMO build (1147.18) fails with the following error:

ERROR: [string "chunk"]:35: time result cannot be represented in this installation

How to reproduce: open the Lua Script Console, and run the following line:

print( os.date("!%m.%d.%Y", -856181100) )

This SHOULD print "11.14.1942" (the date of the 2nd Battle of Guadalcanal) but instead produces the error above. You can verify the correct behavior by running the same line in the Lua live demo here.

I verified that negative epoch times do work through -43200 (or noon on December 31st, 1969) but fail at -43201 and below.

This is obviously an issue if you want to reset the scenario time in Lua for scenarios that take place before noon on December 31st, 1969, as, e.g., os.date("!%m.%d.%Y", VP_GetScenario().StartTimeNum) will fail with an error.

< Message edited by Rory Noonan -- 4/6/2021 8:08:19 PM >
Post #: 1
RE: Large negative epoch times not handled correctly - 3/22/2021 3:10:48 PM   
PaulTheWolf

 

Posts: 40
Joined: 12/10/2017
Status: offline
Hi musurca, thanks for posting about this issue. This is actually a known constraint within Command, it has issues calling prior to the UNIX Epoch time. However there is an established workaround script. It's a little more complicated, however.


TimeVar = ScenEdit_CurrentTime()
if TimeVar < 0 then
local a = os.date("*t",TimeVar) -- build timestamp table
-- you need to manually format it from the table
msgtime = string.format("%d.%d.%d", a.month, a.day, a.year-52)

end
print (msgtime)

That returns the current date in 1969. To adjust the required date and time, add or subtract from the a.month and a.day values in the same manner as the year in this script. This is also formatted in the same manner as the script you provided. Hopefully this should resolve your issue!

Paul.

< Message edited by PaulTheWolf -- 3/22/2021 7:45:40 PM >

(in reply to musurca)
Post #: 2
RE: Large negative epoch times not handled correctly - 3/22/2021 7:28:59 PM   
musurca

 

Posts: 128
Joined: 7/16/2020
Status: offline
quote:

TimeVar = ScenEdit_CurrentTime()
if TimeVar > 0 then
local a = os.date("*t",TimeVar) -- build timestamp table
-- you need to manually format it from the table
msgtime = string.format("%d.%d.%d", a.month, a.day, a.year-52)

end
print (msgtime)


Hi Paul -- thanks for the reply! I'm not sure I understand the above script you suggested, though--what you posted above only works for values of TimeVar greater than 0, and the issue relates to scenarios in which ScenEdit_CurrentTime() returns values less than 0. I'm probably missing something!

My use case (the PBEM mod) involves doing arithmetic on the current epoch time, and setting the scenario time based on that. For example:
function TimeToUTC(epoch_time)
    local date_str = os.date("!%m.%d.%Y", epoch_time)
    local time_str = os.date("!%H.%M.%S", epoch_time)
    return {Date=date_str, Time=time_str}
end

local scenario_start_time = VP_GetScenario().StartTimeNum
local turn_length = 60*60*30 -- 30 minutes
local next_turn_start_time = scenario_start_time + turn_length

-- set scenario time to next turn start
ScenEdit_SetTime( TimeToUTC(first_turn_start_time) )

In other words, I don't necessarily know anything about the month, day, or year when I do the addition, as any of these could roll over. Is there a workaround that doesn't involve completely reimplementing os.date()?

(in reply to PaulTheWolf)
Post #: 3
RE: Large negative epoch times not handled correctly - 3/22/2021 7:41:28 PM   
PaulTheWolf

 

Posts: 40
Joined: 12/10/2017
Status: offline
Hi musurca. That's a script that can be both forward and back dated, flipping the > to a < as needed. It actually still returns properly in the manner I posted within the LUA Interface within command though I'll correct it in my previous post. Unfortunately the Epoch time is a tough constraint to bypass. Another option would be a LUA Date/Time Library, but given you're looking to utilize the os.date specifically I'm not sure how effective that will be. Let me bring this up with the team with your use case in specific and see if there's anything they can think of that might work.

Paul.

(in reply to musurca)
Post #: 4
RE: Large negative epoch times not handled correctly - 3/22/2021 8:11:49 PM   
musurca

 

Posts: 128
Joined: 7/16/2020
Status: offline
quote:

if TimeVar < 0 then
local a = os.date("*t",TimeVar) -- build timestamp table
-- you need to manually format it from the table
msgtime = string.format("%d.%d.%d", a.month, a.day, a.year-52)

end


Okay, thank you, Paul! FYI, the corrected script you posted also doesn't work (at least on my end) because if you pass a negative TimeVar < -43200 to os.date(), you get no return value--just the same error message that I posted before: ERROR: [string "chunk"]:35: time result cannot be represented in this installation.

I realized it would probably be quicker for me to just partially reimplement os.date() instead of griping about it, so I cooked up a function that should work for Unix epoch times from Jan 1 1900 through Dec 31 2099. But this really seems like overkill, and hopefully there's a simpler solution related to your script suggestion, or else the Lua Date/Time library as you offered. If not, maybe there should be something like this in the CMO API to avoid time-related bugs, if it's not a huge pain to implement?

(apologies for the formatting--using the "code" header seems to break the forum CSS for me)

function EpochTimeToUTC(etime, date_sep, time_sep)
date_sep = date_sep or "."
time_sep = time_sep or "."

function isLeapYear(y)
if y % 4 == 0 then
if y % 100 == 0 then
if y % 400 == 0 then
return true
end
return false
end
return true
end
return false
end

local days_in_month_common = {31,28,31,30,31,30,31,31,30,31,30,31}
local days_in_month_leap = {31,29,31,30,31,30,31,31,30,31,30,31}

--start from midnight Jan 1, 1900, or -2208988800 epoch seconds
--note that 1900 was NOT a leap year due to Gregorian rules.
--However 1904 was--so it's okay to start here.
local EPOCH_20TH_CENTURY = -2208988800
local SECONDS_TO_HOURS = 60*60
local SECONDS_TO_DAYS = SECONDS_TO_HOURS*24
local SECONDS_TO_COMMON_YEAR = SECONDS_TO_DAYS*365
local SECONDS_TO_LEAP_YEAR = SECONDS_TO_DAYS*366
local SECONDS_IN_LEAP_SEQ = SECONDS_TO_COMMON_YEAR*3+SECONDS_TO_LEAP_YEAR

etime = etime - EPOCH_20TH_CENTURY
local leap_seqs = math.floor(etime / SECONDS_IN_LEAP_SEQ)
local remainder_secs = etime % SECONDS_IN_LEAP_SEQ
local remainder_years = math.floor(remainder_secs / SECONDS_TO_COMMON_YEAR)
remainder_secs = remainder_secs % SECONDS_TO_COMMON_YEAR
local remainder_days = math.floor(remainder_secs / SECONDS_TO_DAYS)
remainder_secs = remainder_secs % SECONDS_TO_DAYS

local year = 1900+leap_seqs*4+remainder_years

local month_table
if isLeapYear(year) then
month_table = days_in_month_leap
else
month_table = days_in_month_common
end

local month = 1
local day = 1

while remainder_days > 0 do
if remainder_days > month_table[month] then
remainder_days = remainder_days - month_table[month]
month = month + 1
else
day = day + remainder_days
remainder_days = 0
end
end

local hour = math.floor(remainder_secs / SECONDS_TO_HOURS)
remainder_secs = remainder_secs % SECONDS_TO_HOURS
local minute = math.floor(remainder_secs / 60)
local second = remainder_secs % 60

if hour < 10 then
hour = "0"..tostring(hour)
end
if minute < 10 then
minute = "0"..tostring(minute)
end
if second < 10 then
second = "0"..tostring(second)
end

return {
Date=month..date_sep..day..date_sep..year,
Time=hour..time_sep..minute..time_sep..second
}
end

< Message edited by musurca -- 3/22/2021 8:22:47 PM >

(in reply to PaulTheWolf)
Post #: 5
RE: Large negative epoch times not handled correctly - 3/22/2021 10:15:34 PM   
PaulTheWolf

 

Posts: 40
Joined: 12/10/2017
Status: offline
I think something similar might be happening to my code when I post it. But that's extremely impressive work! The Team is checking out a possible other workaround, but I'll send this their way as well. I'll keep you posted on what they end up with. Thank you again for your great scripting!

Paul.

(in reply to musurca)
Post #: 6
RE: Large negative epoch times not handled correctly - 3/23/2021 2:00:05 PM   
PaulTheWolf

 

Posts: 40
Joined: 12/10/2017
Status: offline
Hi musurca! I'm pleased to say that the team is instituting a fix for the Epoch Time issue altogether in an upcoming update for Command. Thank you again for your impressive scripting!

(in reply to PaulTheWolf)
Post #: 7
RE: Large negative epoch times not handled correctly - 3/23/2021 6:30:06 PM   
musurca

 

Posts: 128
Joined: 7/16/2020
Status: offline
That's great to hear — thanks for responding so quickly!!

(in reply to PaulTheWolf)
Post #: 8
Page:   [1]
All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Tech Support >> [Fixed] Large negative epoch times not handled correctly Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI

0.654