1

我有这个功能:

  function SecondsFormat(X)
   if X <= 0 then return "" end
   local t ={}
   local ndays = string.format("%02.f",math.floor(X / 86400))
   if tonumber(ndays) > 0 then table.insert(t,ndays.."d ") end
   local nHours = string.format("%02.f",math.floor((X/3600) -(ndays*24)))
   if tonumber(nHours) > 0 then table.insert(t,nHours.."h ") end
   local nMins = string.format("%02.f",math.floor((X/60) - (ndays * 1440) - (nHours*60)))
   if tonumber(nMins) > 0 then table.insert(t,nMins.."m ") end
   local nSecs = string.format("%02.f", math.fmod(X, 60));
   if tonumber(nSecs) > 0 then table.insert(t,nSecs.."s") end
   return table.concat(t)
  end

我想增加几周和几个月的时间,但是因为一个月中的日子并不总是一样,所以我无法在月份部分继续前进,所以任何人都可以提供一些帮助吗?

第二个问题是,使用表格来存储结果是处理这个问题的最有效方法吗?给定函数将每 3 秒调用一次,最多可处理 100 个项目(在网格中)?

编辑:

  function ADownload.ETA(Size,Done,Tranrate) --all in bytes
   if Size == nil then return "--" end
   if Done == nil then return "--" end
   if Tranrate == nil then return "--" end
   local RemS = (Size - Done) / Tranrate
   local RemS = tonumber(RemS)
   if RemS <= 0 or RemS == nil or RemS > 63072000 then return "--" end
   local date = os.date("%c",RemS)
   if date == nil then return "--" end
   local month, day, year, hour, minute, second = date:match("(%d+)/(%d+)/(%d+) (%d+): (%d+):(%d+)")
   month = month - 1
   day = day - 1
   year = year - 70
   if tonumber(year) > 0 then
   return string.format("%dy %dm %dd %dh %dm %ds", year, month, day, hour, minute, second)
   elseif tonumber(month) > 0 then
    return string.format("%dm %dd %dh %dm %ds",month, day, hour, minute, second)
   elseif tonumber(day) > 0 then
    return string.format("%dd %dh %dm %ds",day, hour, minute, second)  
   elseif tonumber(hour) > 0 then
    return string.format("%dh %dm %ds",hour, minute, second)   
   elseif tonumber(minute) > 0 then
    return string.format("%dm %ds",minute, second)  
   else
    return string.format("%ds",second)  
   end      
  end

我将该函数合并到主函数中,因为我认为它可能会更快,但我现在有两个问题:

1:我必须添加

  if date == nil then return "--" end

因为它偶尔会在 date:match 尝试与“nil”进行比较时出错,但是 os.date 在文献中没有提到将 nil 作为字符串或表格返回,所以尽管额外的代码行解决了这个问题,但我想知道为什么行为发生是因为我确定我在之前的回报中捕获了所有非事件?

2:有时我会看到像 myfunction(...) 这样编写的函数,我确信它只是取消了参数,如果是这样,是否有一行代码可以取消前 3 个“if”语句?

4

2 回答 2

3

您可以使用os.date函数以可用格式获取日期值。formating'*t'参数使返回的日期变成表格而不是字符串。

local t = os.date('*t')
print(t.year, t.month, t.day, t.hour, t.min, t.sec)
print(t.wday, t.yday)

os.data 默认使用当前时间,如果需要,您可以传递一个明确的时间(有关更多信息,请参阅 os.data 文档)

local t = os.date('*t', x)

至于表性能,我不会担心。不仅您的函数不经常被调用,而且表处理比您可能正在做的其他事情便宜得多(调用 os.date、大量字符串格式化等)

于 2013-03-11T01:54:04.333 回答
2

为什么不让 Lua 的os库为您完成这项艰巨的工作呢?

可能有一种更简单(阅读:更好)的方法来找出与 的区别01/01/70,但这里有一个关于如何使用它的快速想法:

function SecondsFormat(X)
    if X <= 0 then return "" end
    local date = os.date("%c", X) -- will give something like "01/03/70 03:40:00"
    local inPattern = "(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)"
    local outPattern = "%dy %dm %dd %dh %dm %ds"
    local month, day, year, hour, minute, second = date:match(inPattern)
    month = month - 1
    day = day - 1
    year = year - 70
    return string.format(outPattern, year, month, day, hour, minute, second)
end

我认为这也应该比构建表格和string.format多次调用要快得多——但你必须对此进行分析。

编辑:我用两个 concatenate 函数进行了快速测试"abc""def""ghi"使用了这两种方法。将这些字符串插入一个表中,一个连接需要 14 秒(当然是几百万次运行),使用单个string.format()需要 6 秒。这没有考虑到您的代码string.format()无论如何都会调用(多次) - 也没有考虑到您通过除法计算值和通过模式匹配计算值之间的区别。模式匹配肯定会更慢,但我怀疑它是否超过了没有表格的收益——而且能够利用os.time(). 最快的方法可能是手动计算月份和日期,然后使用单个string.format(). 但同样 - 你必须描述它。

EDIT2: missingno 有一个好处,即首先使用"*t"选项 withos.date分别为您提供值。同样,这取决于您是为了方便而想要一个表还是为了存储而使用一个字符串或其他任何原因。结合"*t"和单一string.format

function SecondsFormat(X)
    if X <= 0 then return "" end
    local date = os.date("*t", X) -- will give you a table
    local outPattern = "%dy %dm %dd %dh %dm %ds"
    date.month = date.month - 1
    date.day = date.day - 1
    date.year = date.year - 70
    return string.format(outPattern, date.year, date.month, date.day, date.hour, date.min, date.sec)
end
于 2013-03-11T01:45:30.607 回答