Compare dates in Lua

笑着哭i 提交于 2020-08-24 08:34:32

问题


I have a variable with a date table that looks like this

* table:
 [day]
  * number: 15
 [year]
  * number: 2015
 [month]
  * number: 2

How do I get the days between the current date and the date above? Many thanks!


回答1:


You can use os.time() to convert your table to seconds and get the current time and then use os.difftime() to compute the difference. see Lua Wiki for more details.

reference = os.time{day=15, year=2015, month=2}
daysfrom = os.difftime(os.time(), reference) / (24 * 60 * 60) -- seconds in a day
wholedays = math.floor(daysfrom)
print(wholedays) -- today it prints "1"

as @barnes53 pointed out could be off by one day for a few seconds so it's not ideal, but it may be good enough for your needs.




回答2:


You can use the algorithms gathered here:

chrono-Compatible Low-Level Date Algorithms

The algorithms are shown using C++, but they can be easily implemented in Lua if you like, or you can implement them in C or C++ and then just provide Lua bindings.

The basic idea using these algorithms is to compute a day number for the two dates and then just subtract them to give you the number of days.


--[[
 http://howardhinnant.github.io/date_algorithms.html

 Returns number of days since civil 1970-01-01.  Negative values indicate
    days prior to 1970-01-01.
 Preconditions:  y-m-d represents a date in the civil (Gregorian) calendar
                 m is in [1, 12]
                 d is in [1, last_day_of_month(y, m)]
                 y is "approximately" in
                   [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
                 Exact range of validity is:
                 [civil_from_days(numeric_limits<Int>::min()),
                  civil_from_days(numeric_limits<Int>::max()-719468)]
]]
function days_from_civil(y, m, d)
    if m <= 2 then
      y = y - 1
      m = m + 9
    else
      m = m - 3
    end
    local era = math.floor(y/400)
    local yoe = y - era * 400                                           -- [0, 399]
    local doy = math.modf((153*m + 2)/5) + d-1                          -- [0, 365]
    local doe = yoe * 365 + math.modf(yoe/4) - math.modf(yoe/100) + doy -- [0, 146096]
    return era * 146097 + doe - 719468
end

local reference_date = {year=2001, month = 1, day = 1}
local date = os.date("*t")

local reference_days = days_from_civil(reference_date.year, reference_date.month, reference_date.day)
local days = days_from_civil(date.year, date.month, date.day)

print(string.format("Today is %d days into the 21st century.",days-reference_days))



回答3:


os.time (under Windows, at least) is limited to years from 1970 and up. If, for example, you need a general solution to also find ages in days for people born before 1970, this won't work. You can use a julian date conversion and subtract between the two numbers (today and your target date).

A sample julian date function that will work for practically any date AD is given below (Lua v5.3 because of // but you could adapt to earlier versions):

local
function div(n,d)
  local a, b = 1, 1
  if n < 0 then a = -1 end
  if d < 0 then b = -1 end
  return a * b * (math.abs(n) // math.abs(d))
end

--------------------------------------------------------------------------------
-- Convert a YYMMDD date to Julian since 1/1/1900 (negative answer possible)
--------------------------------------------------------------------------------

function julian(year, month, day)
  local temp

  if (year < 0) or (month < 1) or (month > 12)
                or (day < 1) or (day > 31) then
    return
  end
  temp = div(month - 14, 12)
  return (
         day - 32075 +
         div(1461 * (year + 4800 + temp), 4) +
         div(367 * (month - 2 - temp * 12), 12) -
         div(3 * div(year + 4900 + temp, 100), 4)
         ) - 2415021
end


来源:https://stackoverflow.com/questions/28550413/compare-dates-in-lua

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!