1

s ="2010年2月29日"

上記の文字列がLuaで有効な日付であることを検証する方法は?

4

5 に答える 5

6

標準のLuaライブラリにはそのようなものはありませんが、自分で簡単に作成できます。

function is_valid_date(str)

  -- perhaps some sanity checks to see if `str` really is a date

  local m, d, y = str:match("(%d+)/(%d+)/(%d+)")

  m, d, y = tonumber(m), tonumber(d), tonumber(y)

  if d < 0 or d > 31 or m < 0 or m > 12 or y < 0 then
    -- Cases that don't make sense
    return false
  elseif m == 4 or m == 6 or m == 9 or m == 11 then 
    -- Apr, Jun, Sep, Nov can have at most 30 days
    return d <= 30
  elseif m == 2 then
    -- Feb
    if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then
      -- if leap year, days can be at most 29
      return d <= 29
    else
      -- else 28 days is the max
      return d <= 28
    end
  else 
    -- all other months can have at most 31 days
    return d <= 31
  end

end

(テストされていません!)

または、「lua date parsing」を検索して、これを実行するサードパーティのライブラリを見つけます。

于 2012-09-22T11:01:03.630 に答える
4
function checkDate(us_mdY) 
    local m, d, Y = us_mdY:match("(%d+)/(%d+)/(%d+)")
    local epoch = os.time{year=Y, month=m, day=d}
    local zeromdy = string.format("%02d/%02d/%04d", m, d, Y)
    return zeromdy == os.date('%m/%d/%Y', epoch)
end
于 2013-11-06T19:50:24.887 に答える
1
function isdate(value)
    --  Check for a UK date pattern dd/mm/yyyy , dd-mm-yyyy, dd.mm.yyyy
    --      My applications needs a textual response
    --      change the return values if you need true / false
    if (string.match(value, "^%d+%p%d+%p%d%d%d%d$")) then
        local d, m, y = string.match(value, "(%d+)%p(%d+)%p(%d+)")
        d, m, y = tonumber(d), tonumber(m), tonumber(y)

        local dm2 = d*m*m
        if  d>31 or m>12 or dm2==0 or dm2==116 or dm2==120 or dm2==124 or dm2==496 or dm2==1116 or dm2==2511 or dm2==3751 then
            -- invalid unless leap year
            if dm2==116 and (y%400 == 0 or (y%100 ~= 0 and y%4 == 0)) then
                return "valid"
            else
                return "invalid"
            end
        else
            return "valid"
        end
    else
        return "invalid"
    end
end
于 2014-02-06T00:05:28.013 に答える
1

Bart Kierの応答は論理的に整理され、提示され、明確ですが、「00/12/2011」や「02/00/2012」などのゼロ値のナンセンスな日付が検証に合格することを許可します。月、日、年の「<」チェックを「<=」に変更して、以下で修正しました。

function is_valid_date(str)

  -- perhaps some sanity checks to see if `str` really is a date

  local m, d, y = str:match("(%d+)/(%d+)/(%d+)")

  m, d, y = tonumber(m), tonumber(d), tonumber(y)

  if d <= 0 or d > 31 or m <= 0 or m > 12 or y <= 0 then
    -- Cases that don't make sense
    return false
  elseif m == 4 or m == 6 or m == 9 or m == 11 then 
    -- Apr, Jun, Sep, Nov can have at most 30 days
    return d <= 30
  elseif m == 2 then
    -- Feb
    if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then
      -- if leap year, days can be at most 29
      return d <= 29
    else
      -- else 28 days is the max
      return d <= 28
    end
  else 
    -- all other months can have at most 31 days
    return d <= 31
  end
end
于 2014-06-09T14:55:29.957 に答える
0

JeffDrummとBartKierの回答は、文字列が日付ではないものである可能性があることを考慮していません。以下のコードでJeffDrummsの回答に年/月/日付が見つからない場合に、falseを返すコードを追加しました。

function IsValidDate(str)
  -- perhaps some sanity checks to see if `str` really is a date
  local y, m, d = str:match("(%d+)/(%d+)/(%d+)")
  if y == nil or m == nil or d == nil
  then
    return false
  end
  m, d, y = tonumber(m), tonumber(d), tonumber(y)

  if d <= 0 or d > 31 or m <= 0 or m > 12 or y <= 0 then
    -- Cases that don't make sense
    return false
  elseif m == 4 or m == 6 or m == 9 or m == 11 then 
    -- Apr, Jun, Sep, Nov can have at most 30 days
    return d <= 30
  elseif m == 2 then
    -- Feb
    if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then
      -- if leap year, days can be at most 29
      return d <= 29
    else
      -- else 28 days is the max
      return d <= 28
    end
  else 
    -- all other months can have at most 31 days
    return d <= 31
  end
end
于 2016-05-01T19:40:55.417 に答える