13

Is there any simple way to convert a RFC HTTP date into a timestamp in Lua?

"Sat, 29 Oct 1994 19:43:31 GMT"

into

783467011

kdopen
  • 8,032
  • 7
  • 44
  • 52
BorisTheBlade
  • 201
  • 2
  • 3
  • 5

5 Answers5

22

Correcting lhf's example code to account for timezone since os.time() does not have a way to specify the timezone. Also assume all input ends in GMT since this only works with GMT.

s="Sat, 29 Oct 1994 19:43:31 GMT"
p="%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) GMT"
day,month,year,hour,min,sec=s:match(p)
MON={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12}
month=MON[month]
offset=os.time()-os.time(os.date("!*t"))
print(os.time({day=day,month=month,year=year,hour=hour,min=min,sec=sec})+offset)

Which gives us 783477811. And we will verify with os.date("!%c") because the ! will make the output in UTC instead of local timezone.

print(os.date("!%c",783477811))
--> Sat Oct 29 19:43:31 1994
Arrowmaster
  • 9,143
  • 2
  • 28
  • 25
  • I had to add `isdst=false` (*daylight savings time*) to the final line as my local TZ was observing it, so `os.time` did too. UTC/GMT times are never DST-adjusted. What a nightmare! – markson edwardson Nov 10 '22 at 09:39
10

If you need to convert the value to a unix timestamp, the code to do so would be this:

-- Assuming a date pattern like: yyyy-mm-dd hh:mm:ss
local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)"
local timeToConvert = "2011-01-01 01:30:33"
local runyear, runmonth, runday, runhour, runminute, runseconds = timeToConvert:match(pattern)

local convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})
Community
  • 1
  • 1
Ryan Crowley
  • 167
  • 2
  • 5
  • See my answer and the additional timezone handling it does. Your answer only works if the date is for the current timezone (and daylight savings period) as the system it is running on. – Arrowmaster May 05 '11 at 22:47
9

The code below does this except that it does not handle timezones:

s="Sat, 29 Oct 1994 19:43:31 GMT"
p="%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) (%a+)"
day,month,year,hour,min,sec,tz=s:match(p)
MON={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12}
month=MON[month]
print(os.time({tz=tz,day=day,month=month,year=year,hour=hour,min=min,sec=sec}))

But it prints 783467011. The code below tells us that 1288374211 is a different date:

print(os.date("%c",1288374211))
--> Fri Oct 29 15:43:31 2010
print(os.date("%c",783467011))
--> Sat Oct 29 19:43:31 1994
lhf
  • 70,581
  • 9
  • 108
  • 149
7

use luadate, you can install it with luarocks.

date = require 'date'
local d1 = date('Sat, 29 Oct 1994 19:43:31 GMT')                                                                                               
local seconds = date.diff(d1, date.epoch()):spanseconds()
print(seconds)
mescalin
  • 399
  • 5
  • 3
  • what if my dateformat is '"2021-12-16T12:28:21.190344545Z"' and I want to find the difference between epochtime and this UTC time with millisecond resolution? – mukara Dec 16 '21 at 13:06
1

Arrowmaster's answer above would be perfect if daylight saving time is considered. Also using array seems cleaner.

s="Sat, 29 Oct 1994 19:43:31 GMT"
p="%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) GMT"
date={}
date['day'],date['month'],date['year'],date['hour'],date['min'],date['sec']=s:match(p)
MON={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12}
date['month']=MON[date['month']]
date["isdst"] = false  -- new code
offset=os.time()-os.time(os.date("!*t"))
print(os.time(date)+offset)
D.Liu
  • 96
  • 4