mirror of
https://github.com/nmap/nmap.git
synced 2026-01-04 05:39:01 +00:00
Move date/time functions from stdnse to datetime. See #517
This commit is contained in:
@@ -10,7 +10,6 @@ local _G = require "_G"
|
||||
local coroutine = require "coroutine"
|
||||
local math = require "math"
|
||||
local nmap = require "nmap"
|
||||
local os = require "os"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
local assert = assert;
|
||||
@@ -30,8 +29,6 @@ local type = type
|
||||
local pcall = pcall
|
||||
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
local fmod = math.fmod
|
||||
local max = math.max
|
||||
local random = math.random
|
||||
|
||||
@@ -50,10 +47,6 @@ local remove = table.remove;
|
||||
local pack = table.pack;
|
||||
local unpack = table.unpack;
|
||||
|
||||
local difftime = os.difftime;
|
||||
local time = os.time;
|
||||
local date = os.date;
|
||||
|
||||
local EMPTY = {}; -- Empty constant table
|
||||
|
||||
_ENV = require "strict" {};
|
||||
@@ -500,194 +493,6 @@ function parse_timespec(timespec)
|
||||
return t * m
|
||||
end
|
||||
|
||||
-- Find the offset in seconds between local time and UTC. That is, if we
|
||||
-- interpret a UTC date table as a local date table by passing it to os.time,
|
||||
-- how much must be added to the resulting integer timestamp to make it
|
||||
-- correct?
|
||||
local function utc_offset(t)
|
||||
-- What does the calendar say locally?
|
||||
local localtime = date("*t", t)
|
||||
-- What does the calendar say in UTC?
|
||||
local gmtime = date("!*t", t)
|
||||
-- Interpret both as local calendar dates and find the difference.
|
||||
return difftime(time(localtime), time(gmtime))
|
||||
end
|
||||
--- Convert a date table into an integer timestamp.
|
||||
--
|
||||
-- Unlike os.time, this does not assume that the date table represents a local
|
||||
-- time. Rather, it takes an optional offset number of seconds representing the
|
||||
-- time zone, and returns the timestamp that would result using that time zone
|
||||
-- as local time. If the offset is omitted or 0, the date table is interpreted
|
||||
-- as a UTC date. For example, 4:00 UTC is the same as 5:00 UTC+1:
|
||||
-- <code>
|
||||
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}) --> 14400
|
||||
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 0) --> 14400
|
||||
-- date_to_timestamp({year=1970,month=1,day=1,hour=5,min=0,sec=0}, 1*60*60) --> 14400
|
||||
-- </code>
|
||||
-- And 4:00 UTC+1 is an earlier time:
|
||||
-- <code>
|
||||
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 1*60*60) --> 10800
|
||||
-- </code>
|
||||
function date_to_timestamp(date, offset)
|
||||
offset = offset or 0
|
||||
return time(date) + utc_offset(time(date)) - offset
|
||||
end
|
||||
|
||||
local function format_tz(offset)
|
||||
local sign, hh, mm
|
||||
|
||||
if not offset then
|
||||
return ""
|
||||
end
|
||||
if offset < 0 then
|
||||
sign = "-"
|
||||
offset = -offset
|
||||
else
|
||||
sign = "+"
|
||||
end
|
||||
-- Truncate to minutes.
|
||||
offset = floor(offset / 60)
|
||||
hh = floor(offset / 60)
|
||||
mm = floor(fmod(offset, 60))
|
||||
|
||||
return format("%s%02d:%02d", sign, hh, mm)
|
||||
end
|
||||
--- Format a date and time (and optional time zone) for structured output.
|
||||
--
|
||||
-- Formatting is done according to RFC 3339 (a profile of ISO 8601), except
|
||||
-- that a time zone may be omitted to signify an unspecified local time zone.
|
||||
-- Time zones are given as an integer number of seconds from UTC. Use
|
||||
-- <code>0</code> to mark UTC itself. Formatted strings with a time zone look
|
||||
-- like this:
|
||||
-- <code>
|
||||
-- format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00"
|
||||
-- format_timestamp(os.time(), 2*60*60) --> "2012-09-07T23:37:42+02:00"
|
||||
-- </code>
|
||||
-- Without a time zone they look like this:
|
||||
-- <code>
|
||||
-- format_timestamp(os.time()) --> "2012-09-07T23:37:42"
|
||||
-- </code>
|
||||
--
|
||||
-- This function should be used for all dates emitted as part of NSE structured
|
||||
-- output.
|
||||
function format_timestamp(t, offset)
|
||||
if type(t) == "table" then
|
||||
return format(
|
||||
"%d-%02d-%02dT%02d:%02d:%02d",
|
||||
t.year, t.month, t.day, t.hour, t.min, t.sec
|
||||
)
|
||||
else
|
||||
local tz_string = format_tz(offset)
|
||||
offset = offset or 0
|
||||
local status, result = pcall(date, "!%Y-%m-%dT%H:%M:%S", floor(t + offset))
|
||||
if not status then
|
||||
local tmp = floor(t + offset)
|
||||
if tmp > 0xffffffff then
|
||||
-- Maybe too far in the future?
|
||||
local seconds_in_year = 31556926
|
||||
local extra_years = (tmp - 0xffffffff) // seconds_in_year + 1
|
||||
tmp = tmp - extra_years * seconds_in_year
|
||||
status, result = pcall(date, "!*t", tmp)
|
||||
if status then
|
||||
-- seconds_in_year is imprecise, so we truncate to date only
|
||||
result = format("%d-%02d-%02d", result.year + extra_years, result.month, result.day)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not status then
|
||||
return ("Invalid timestamp: %s"):format(t)
|
||||
end
|
||||
return result .. tz_string
|
||||
end
|
||||
end
|
||||
|
||||
--- Format a time interval into a string
|
||||
--
|
||||
-- String is in the same format as format_difftime
|
||||
-- @param interval A time interval
|
||||
-- @param unit The time unit division as a number. If <code>interval</code> is
|
||||
-- in milliseconds, this is 1000 for instance. Default: 1 (seconds)
|
||||
-- @return The time interval in string format
|
||||
function format_time(interval, unit)
|
||||
local sign = ""
|
||||
if interval < 0 then
|
||||
sign = "-"
|
||||
interval = math.abs(interval)
|
||||
end
|
||||
unit = unit or 1
|
||||
local precision = floor(math.log(unit, 10))
|
||||
|
||||
local sec = (interval % (60 * unit)) / unit
|
||||
interval = interval // (60 * unit)
|
||||
local min = interval % 60
|
||||
interval = interval // 60
|
||||
local hr = interval % 24
|
||||
interval = interval // 24
|
||||
|
||||
local s = format("%.0fd%02.0fh%02.0fm%02.".. precision .."fs",
|
||||
interval, hr, min, sec)
|
||||
-- trim off leading 0 and "empty" units
|
||||
return sign .. (match(s, "([1-9].*)") or format("%0.".. precision .."fs", 0))
|
||||
end
|
||||
|
||||
--- Format the difference between times <code>t2</code> and <code>t1</code>
|
||||
-- into a string
|
||||
--
|
||||
-- String is in one of the forms (signs may vary):
|
||||
-- * 0s
|
||||
-- * -4s
|
||||
-- * +2m38s
|
||||
-- * -9h12m34s
|
||||
-- * +5d17h05m06s
|
||||
-- * -2y177d10h13m20s
|
||||
-- The string shows <code>t2</code> relative to <code>t1</code>; i.e., the
|
||||
-- calculation is <code>t2</code> minus <code>t1</code>.
|
||||
function format_difftime(t2, t1)
|
||||
local d, s, sign, yeardiff
|
||||
|
||||
d = difftime(time(t2), time(t1))
|
||||
if d > 0 then
|
||||
sign = "+"
|
||||
elseif d < 0 then
|
||||
sign = "-"
|
||||
t2, t1 = t1, t2
|
||||
d = -d
|
||||
else
|
||||
sign = ""
|
||||
end
|
||||
-- t2 is always later than or equal to t1 here.
|
||||
|
||||
-- The year is a tricky case because it's not a fixed number of days
|
||||
-- the way a day is a fixed number of hours or an hour is a fixed
|
||||
-- number of minutes. For example, the difference between 2008-02-10
|
||||
-- and 2009-02-10 is 366 days because 2008 was a leap year, but it
|
||||
-- should be printed as 1y0d0h0m0s, not 1y1d0h0m0s. We advance t1 to be
|
||||
-- the latest year such that it is still before t2, which means that its
|
||||
-- year will be equal to or one less than t2's. The number of years
|
||||
-- skipped is stored in yeardiff.
|
||||
if t2.year > t1.year then
|
||||
local tmpyear = t1.year
|
||||
-- Put t1 in the same year as t2.
|
||||
t1.year = t2.year
|
||||
d = difftime(time(t2), time(t1))
|
||||
if d < 0 then
|
||||
-- Too far. Back off one year.
|
||||
t1.year = t2.year - 1
|
||||
d = difftime(time(t2), time(t1))
|
||||
end
|
||||
yeardiff = t1.year - tmpyear
|
||||
t1.year = tmpyear
|
||||
else
|
||||
yeardiff = 0
|
||||
end
|
||||
|
||||
local s = format_time(d)
|
||||
if yeardiff == 0 then return sign .. s end
|
||||
-- Years.
|
||||
s = format("%dy", yeardiff) .. s
|
||||
return sign .. s
|
||||
end
|
||||
|
||||
--- Returns the current time in milliseconds since the epoch
|
||||
-- @return The current time in milliseconds since the epoch
|
||||
function clock_ms()
|
||||
|
||||
Reference in New Issue
Block a user