This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
surferpup's profile picture

Real World Time API (Ver. 1.0)

Started by surferpup, 01 February 2014 - 05:25 PM
surferpup #1
Posted 01 February 2014 - 06:25 PM
Real World Time API (Version 1.0)



This API is in now in its release version.

As promised, I have created an API which allows for obtaining real world time and date from the timeapi.org servers.

The idea for the API came from the suggestions I received after posting my Real World / MinecraftWorld Time Display Program

This API will allow you to retrieve current real world date/time information for use within your ComputerCraft creations. The public functions are as follows:

getTime,printTime

There are two functions which either get or print time based on a time zone parameter (default = UTC), an hours offset parameter (default = 0), a format parameter and a timeout variable (which will abandon the request if it is taking too long. The default timeout is 0 (infinite).

getTime(timeZone,offset,dateTimeFormat,timeOut)
printTime(timeZone,offset,dateTimeFormat,timeOut)

Pre-Defined Date/Time FormatsThe following pre-defined date/time formats exist and can be accessed using API_Name.format.<format name> (ex. API_Name.format.timeShort):
  • timeShort_12 (ex. 02:23 PM)
  • timeLong_12 (ex. 02:23:10 PM)
  • timeShort_24 (ex. 14:23)
  • timeLong_24 (ex. 14:23:10)
  • dateShort = (same as date_mmddyy)
  • dateLong = (same as date_mmddyyyy)
  • date_mmddyy (ex. 01/31/14)
  • date_mmddyyyy (ex. 01/31/2014)
  • date_ddmmyy (ex. 31/01/14)
  • date_ddmmyyyy (ex. 31/01/2014)
  • date_yymmdd (ex. 14/01/31)
  • date_yyyymmdd (ex. 2014/01/31)
  • dateTime12_mmddyy (ex. 01/31/14 02:23 PM)
  • dateTime12_mmddyyyy (ex. 01/31/2014 02:23 PM)
  • dateTime12_ddmmyy (ex. 31/01/14 02:23 PM)
  • dateTime12_ddmmyyyy (ex. 31/01/2014 02:23 PM)
  • dateTime24_mmddyy (ex. 01/31/14 14:23)
  • dateTime24_mmddyyyy (ex. 01/31/2014 14:23)
  • dateTime24_ddmmyy (ex. 31/01/14 14:23)
  • dateTime24_ddmmyyyy (ex. 31/01/2014 14:23)
  • default (same as dateTime12_mmddyyyy)
  • defaultDate (same as date_mmddyyyy)
  • defaultTime (same as timeShort_12)
  • raw = 19 (ex. 2014-01-31T14:23:10+00:00 where +00:00 is time offset)
In addition, you can specify the dateSeparator by using the setSeparator function. For example, API_Name.setSeparator(API_NAme.dateSeparator.comma) will set the separator to the comma character. The separators are actually url-friendly HTML ASCII codes for the characters. Predefined separators include:
  • comma "%2C"
  • dash "%2D"
  • period "%2E"
  • slash "%2F"
  • underscore "%5f"
  • none ""
To use a custom dateSeparator, simply pass in the HTML ASCII code as a string argument to the setSeparator function (ex. API_Name.setSeparator("%2A") will set the date separator to an asterisk – 01*31*2014). You can use multiple characters for a date separator (ex. API_Name.setSeparator("%2A%2B%2A") will set the date separator to "*+*" – 01*+*31*+*2014).

getTimeTable,printTimeTable

The following are two additional functions which either get or print a table of time elements (day, hour, day of week, week of year, year …) using the parameters for time zone and offset and timeOut as above, plus an additional boolean parameter to return numbers instead of strings for certain values (like minutes for example). This would allow a programmer to use individualized elements of date and time in whatever custom format desired. The printTimeTable function will pause to allow for screen scrolling, as there are 22 different date time elements in the table.


getTimeTable(timeZone,offset,makeNumeric,timeOut)
printTimeTable(timeZone,offset,makeNumeric,timeOut)

Date/Time Table Elements
  • dayNameShort – The abbreviated weekday name (“Sun”)
  • dayNameLong – The full weekday name (“Sunday”)
  • monthNameShort – The abbreviated month name (“Jan”)
  • monthNameLong – The full month name (“January”)
  • preferredLocalDateTime – The preferred local date and time representation. Returns Sun Feb 2 03:48:00 2014
  • day – Day of the month (01..31), can be made numeric
  • hour12 – Hour of the day, 12-hour clock (01..12), can be made numeric
  • hour24 – Hour of the day, 24-hour clock (00..23), can be made numeric
  • dayOfYear – Day of the year (001..366), can be made numeric
  • month – Month of the year (01..12), can be made numeric
  • minute – Minute of the hour (00..59), can be made numeric
  • meridian – Meridian indicator (“am” or “pm”)
  • meridianCaps – Meridian indicator (“AM” or “PM”)
  • second – Second of the minute (00..60), can be made numeric
  • weekNumberSunday – Week number of the current year,starting with the first Sunday as the first day of the first week (00..53), can be made numeric
  • weekNumberMonday – Week number of the current year, starting with the first Monday as the first day of the first week (00..53), can be made numeric
  • dayOfWeek – Day of the week (Sunday is 0, 0..6), can be made numeric
  • preferredDate – Preferred representation for the date alone, no time. Returns 02/01/14 for Feb 1, 2014
  • preferredTime – Preferred representation for the time alone, no date. Returns 14:30:01 for 2:30:01 PM.
  • yearShort – Year without a century (00..99), can be made numeric
  • year – Year with century, can be made numeric
  • zone

Finally, there are two utility functions for help with the API: printZones() and printFormats(). These will print the pre-defined zones and time format enumerations for reference. There is a publicly exposed enumeration called format which allows for easily specifying pre-defined formats.

Code

--[[

	Minecraft Real World Time API Version 1.0
	  by surferpup

	Allows for obtaining real world date/time variables
	from www.timeapi.org.

	Numerous time date formats are pre-defined.  You can also return
	all time elements as a table.

	A time out feature exists to return an error value if the website
	times out.

]]

local beforeString = "+hours+before+now"
local afterString = "+hours+after+now"
local now = "now"
local timeZone = "edt"
local modifier = 0
local url="http://www.timeapi.org/"
local httpString =""
local requestTimeOut = 5
local timeResult

--[[
	These are the allowed parameters for formatting on timeapi.org

	In the url, the '%' character is substituted as % and the space is %20

	%a - The abbreviated weekday name (“Sun”)
	%A - The full weekday name (“Sunday”)
	%b - The abbreviated month name (“Jan”)
	%B - The full month name (“January”)
	%c - The preferred local date and time representation
	%d - Day of the month (01..31)
	%H - Hour of the day, 24-hour clock (00..23)
	%I - Hour of the day, 12-hour clock (01..12)
	%j - Day of the year (001..366)
	%m - Month of the year (01..12)
	%M - Minute of the hour (00..59)
	%p - Meridian indicator (“AM” or “PM”)
	%S - Second of the minute (00..60)
	%U - Week number of the current year,
		 starting with the first Sunday as the first day
		 of the first week (00..53)
	%W - Week number of the current year,
		 starting with the first Monday as the first day
		 of the first week (00..53)
	%w - Day of the week (Sunday is 0, 0..6)
	%x - Preferred representation for the date alone, no time
	%X - Preferred representation for the time alone, no date
	%y - Year without a century (00..99)
	%Y - Year with century
	%Z - Time zone name
	%% - Literal “%” character

]]

format={
	timeShort_12 = 1;
	timeLong_12 = 2;

	timeShort_24 = 3;
	timeLong_24 = 4;

	dateShort = 5;
	dateLong = 6;

	date_mmddyy= 5;
	date_mmddyyyy = 6;

	date_ddmmyy = 7;
	date_ddmmyyyy = 8;

	date_yymmdd =9;
	date_yyyymmdd = 10;

	dateTime12_mmddyy = 11;
	dateTime12_mmddyyyy = 12;
	dateTime12_ddmmyy = 13;
	dateTime12_ddmmyyyy = 14;

	dateTime24_mmddyy = 15;
	dateTime24_mmddyyyy = 16;
	dateTime24_ddmmyy = 17;
	dateTime24_ddmmyyyy = 18;

	default=12;
	defaultDate=6;
	defaultTime=1;
	raw = 19;
}

dateSeparator=
{
	comma=",";
	dash="-";
	period=".";
	slash="/";
	underscore="_";
	none="";

}

local separator= separator or dateSeparator.dash

formats ={
	[1]="%l:%M %p";
	[2]="%l:%M:%S %p";
	[3]="%H:%M";
	[4]="%l:5M:%S";

	[5]=("%m"..separator.."%d"..separator.."%y");
	[6]=("%m"..separator.."%d"..separator.."%Y");

	[7]=("%d"..separator.."%m"..separator.."%y");
	[8]=("%d"..separator.."%m"..separator.."%Y");

	[9]=("%y"..separator.."%m"..separator.."%d");
	[10]=("%Y"..separator.."%m"..separator.."%d");

	[11]=("%m"..separator.."%d"..separator.."%y  %l:%M %p");
	[12]=("%m"..separator.."%d"..separator.."%Y  %l:%M %p");
	[13]=("%d"..separator.."%m"..separator.."%y  %l:%M %p");
	[14]=("%d"..separator.."%m"..separator.."%Y  %l:%M %p");

	[15]=("%m"..separator.."%d"..separator.."%y  %H:%M");
	[16]=("%m"..separator.."%d"..separator.."%Y  %H:%M");
	[17]=("%d"..separator.."%m"..separator.."%y  %H:%M");
	[18]=("%d"..separator.."%m"..separator.."%Y  %H:%M");

	[19] = ("");
}

zones={
	utc={zone="utc", name = "Coordinated Universal Time"};
	cst={zone = "cst", name = "Central Standard Time"};
	cdt={zone = "cdt", name = "Central Daylight Time"};
	est={zone = "est", name = "Eastern Standard Time"};
	edt={zone = "edt", name = "Eastern Daylight Time"};
	pst={zone = "pst", name = "Pacific Standard Time"};
	pdt={zone = "pdt", name = "Pacific Daylight Time"};
	mst={zone = "mst", name = "Mountain Standard Time"};
	mdt={zone = "mdt", name = "Mountain Daylight Time"};

}

local timeTableIndex = {
	[1] = "dayNameShort";
	[2] = "dayNameLong";
	[3] = "monthNameShort";
	[4] = "monthNameLong";
	[5] = "preferredLocalDateTime";
	[6] = "day";
	[7] = "hour12";
	[8] = "hour24";
	[9] = "dayOfYear";
	[10] = "month";
	[11] = "minute";
	[12] = "meridian";
	[13] = "meridianCaps";
	[14] = "second";
	[15] = "weekNumberSunday";
	[16] = "weekNumberMonday";
	[17] = "dayOfWeek";
	[18] = "preferredDate";
	[19] = "preferredTime";
	[20] = "yearShort";
	[21] = "year";
	[22] = "zone";
	[23] = "error"  
}

local function resetFormats()
	formats ={
		[1]="%l:%M %p";
		[2]="%l:%M:%S %p";
		[3]="%H:%M";
		[4]="%l:5M:%S";

		[5]=("%m"..separator.."%d"..separator.."%y");
		[6]=("%m"..separator.."%d"..separator.."%Y");

		[7]=("%d"..separator.."%m"..separator.."%y");
		[8]=("%d"..separator.."%m"..separator.."%Y");

		[9]=("%y"..separator.."%m"..separator.."%d");
		[10]=("%Y"..separator.."%m"..separator.."%d");

		[11]=("%m"..separator.."%d"..separator.."%y  %l:%M %p");
		[12]=("%m"..separator.."%d"..separator.."%Y  %l:%M %p");
		[13]=("%d"..separator.."%m"..separator.."%y  %l:%M %p");
		[14]=("%d"..separator.."%m"..separator.."%Y  %l:%M %p");

		[15]=("%m"..separator.."%d"..separator.."%y  %H:%M");
		[16]=("%m"..separator.."%d"..separator.."%Y  %H:%M");
		[17]=("%d"..separator.."%m"..separator.."%y  %H:%M");
		[18]=("%d"..separator.."%m"..separator.."%Y  %H:%M");

		[19] = ("");
	}
end

function setSeparator( separatorString )
	separator = dateSeparator[separatorString] or separatorString or dateSeperator.dash
	resetFormats()
end

function getSeperator()
	return separator
end

local function getZones()
	return zones
end


local function getHelp()
	return help
end

local function printHelp()
end

function string:split(pattern)
	local fields = {}
	local start = 1
	self:gsub("()("..pattern..")",
	   function(c,d)
		  table.insert(fields,self:sub(start,c-1))
		  start = c + #d
	   end
	)
	table.insert(fields, self:sub(start))
	return fields
end

local function split(stringToSplit,pattern)
	local fields = {}
	local start = 1
	string.gsub(stringToSplit,"()("..pattern..")",
	   function(c,d)
		  table.insert(fields,string.sub(stringToSplit,start,c-1))
		  start = c + #d
	   end
	)
	table.insert(fields, string.sub(stringToSplit,start))
	return fields
end

local function getRequest()
	result,timeResult = pcall (function() return (http.get(httpString)).readAll() end)
	if not result then
		return "BadReq"
	else
		return timeResult
	end
end

local function initiateTimer()
	sleep(requestTimeOut)
	timeResult = "timeout"
	return timeResult
end

local function startRequest(request,timeOut)
	requestTimeOut = tonumber(timeOut) or 0
	if requestTimeOut <=0 then requestTimeOut = false end
	request = request or ""
	httpString = request
	if not requestTimeOut then
		return getRequest()
	else
		parallel.waitForAny(getRequest,initiateTimer)
		return timeResult
	end
end


--[[

	PUBLIC API FUNCTIONS


]]

--[[ getTime, printTime

	Arguments

	timeZone:
			A legitimate timezone from the zones table.
			If it is not specified or in error, UTC is chosen.
			You can print the pre-defined zones using
			the printZones() function.

	offset:
			An integer argument (positive or negative) to use
			To offset time by x hours. Ex.  -47 would give
			time/date 47 hours before the present time.

	dateTimeFormat:
			An integer value from the format enumerator.
			If not specified or in error, will use the
			preferred local date/time format specified by
			timeapi.org.  You can print the pre-defined
			formats using the printFormats() function.

]]
function getTime(timeZone,offset,dateTimeFormat,timeOut)
	timeZone = timeZone or "utc"
	offset = offset or 0
	dateTimeFormat = dateTimeFormat or format.raw
	timeOut = timeOut or 0
	if type(timeOut) ~= "number" then timeOut = 0 end
	if not formats[dateTimeFormat]
		then dateTimeFormat = format.default
	end
	offset = tonumber(offset)
	offset = offset or 0
	local modifierString = afterString
	if offset < 0 then modifierString = beforeString offset = math.abs(offset) end
	if not zones[timeZone] then
		timeZone = "utc"
	end
	local formatString = formats[dateTimeFormat]
	if formatString ~= "" then
		formatString = "?format=" .. textutils.urlEncode(formats[dateTimeFormat])
	else
		formatString = ""
	end
	return startRequest((url..timeZone.."/"..tostring(offset)..modifierString..formatString),timeOut)
end


function printTime( ... )
	print (getTime( ... ))
end

--[[ getTimeTable, printTimeTable

	The ability to get the full time table of the current
	date time allows for infinite flexibility in programming
	your own time formats.

	Arguments

	timeZone:
			A legitimate timezone from the zones table.
			If it is not specified or in error, UTC is chosen.
			You can print the pre-defined zones using
			the printZones() function.

	offset:
			An integer argument (positive or negative) to use
			To offset time by x hours. Ex.  -47 would give
			time/date 47 hours before the present time.

	makeNumeric:
			boolean true, false
			true -- will convert leading-zero strings in
				the time table to numeric values.  For example,
				the string value for 3 minutes is "03."  As a
				numeric, it will become the number value 3.
				However, if the value must be a string ("Monday"),
				it will remain a string.
			false or nil -- will leave all values as strings.
]]


function getTimeTable(timeZone,offset,makeNumeric,timeOut) --returns table
	-- check arguments
	timeZone = timeZone or "utc"
	offset = offset or 0
	offset = tonumber(offset)
	timeOut = timeOut or 0
	if type(timeOut) ~= "number" then timeOut = 0 end
	local modifierString = afterString
	if offset < 0 then
		modifierString = beforeString
		offset = math.abs(offset)
	end
	if not zones[timeZone] then
		timeZone = "utc"
	end
	-- Set up timeapi.org format string and get time
	local tableFormat = "?format=%25a,%25A,%25b,%25B,%25c,%25d,%25I,%25H,%25j,%25m,%25M,%25P,%25p,%25S,%25U,%25W,%25w,%25x,%25X,%25y,%25Y,%25z"
	local timeTableAsString = startRequest(url..timeZone.."/"..tostring(offset)..modifierString..tableFormat,timeOut)

	-- create timeTable from string
	local timeTable ={}
	local tempTable = split(timeTableAsString,",")
	if #tempTable > 1 then
		for i = 1,#tempTable do
			timeTable[ timeTableIndex[i] ] =  tempTable[i]
		end

		-- Instead of strings ("01") use numeric values ( 1 )
		if makeNumeric then
			timeTable.day = tonumber(timeTable.day)
			timeTable.hour12 = tonumber(timeTable.hour12)
			timeTable.hour24 = tonumber(timeTable.hour24)
			timeTable.dayOfYear = tonumber(timeTable.dayOfYear)
			timeTable.month = tonumber(timeTable.month)
			timeTable.minute = tonumber(timeTable.minute)
			timeTable.second = tonumber(timeTable.second)
			timeTable.weekNumberSunday = tonumber(timeTable.weekNumberSunday)
			timeTable.dayOfWeek = tonumber(timeTable.dayOfWeek)
			timeTable.year = tonumber(timeTable.year)
		end
	else
		timeTable.error = tempTable[1]
	end
	return timeTable
end

-- Gets time, prints all values in timeTable
function printTimeTable( ... )
	local timeTable = getTimeTable( ...)
	-- use monitor height to pause output
	local width,height = term.getSize()
	local currentRow = 1
	local function pause()
		term.setCursorPos(1,height)
		term.write("... Press any key to continue ...")
		os.pullEvent("key")
		term.setCursorPos(1,height)
		term.clearLine()
		currentRow = 1
	end
	for i,v in ipairs(timeTableIndex) do
		print (v..": "..tostring(timeTable[v]))
		currentRow = currentRow+1
		if currentRow > height - 1 then
			pause()
		end	  
	end
end

--[[ printZones, printFormats

	Utility functions to print what zones
	or formats are pre-defined.

	Arguments

	timeZone:
			A legitimate timezone from the zones table.
			If it is not specified or in error, UTC is chosen.
			You can print the pre-defined zones using
			the printZones() function.

	offset:
]]

function printZones()
	local zoneKeys = {}
	for n in pairs(zones) do table.insert(zoneKeys, n) end
	table.sort(zoneKeys)
	for i,k in ipairs(zoneKeys) do
		print (k.." ("..zones[k].name..")")
	end
end

function printFormats()
	local formatKeys = {}

	-- use monitor height to pause output
	local width,height = term.getSize()
	local currentRow = 1
	local function pause()
		term.setCursorPos(1,height)
		term.write("... Press any key to continue ...")
		os.pullEvent("key")
		term.setCursorPos(1,height)
		term.clearLine()
		currentRow = 1
	end

	for n in pairs(format) do table.insert(formatKeys, n) end
	table.sort(formatKeys)

	for i,k in ipairs(formatKeys) do
		print (k.." ("..format[k]..")")
		currentRow = currentRow+1
		if currentRow > height - 1 then
			pause()
		end	
	end
end


To Do List
  • Implement a timeout mechanism to handle request timeouts. Will use parallel API (waitForAny) on requests with a timeout argument. If request completes before timeout, fine, otherwise, return "err" as date/time return value or {error="timeout"} as table return value. Implemented
  • Derp-A-Lert!!!! – use textutils.urlEncode for creating url-friendly strings rather than doing it myself. This will change the dateSeparator functions and make the format strings a lot easier to create and read. Implemented
  • Create time stamp format (ex. 20140131142310 for 2014-01-31 @ 2:23:10 PM) for stamping use in stamping file changes, entries, logging.
  • Collect user feedback, modify accordingly.

Change Log
  • Finished format table, added formats for all basic formats.
  • Added ability with setSeparator function to change separator used between dates elements.
  • Updated documentation on pre-defined Time/Date formats and pre-defined dateSeparators.
  • Added "none" option in dateSeparator.
  • Utilized textutils.urlEncode to make more sense of timeFormat strings.
  • Added timeout feature (default = no timeout). If timeout occurs, will return "timeout" for time value, or will populate the error element in the table.
  • Fixed error in timeout feature caught by [member='mibac138']

Potential Uses in Your CodeObviously, these are not exhaustive, especially due to the fact that ComputerCraft coders are way more imaginative than I am. But here are a few:
  • Create server chimes which alert users to real world time in chat.
  • Log startup times of your turtles – can help determine when chucks were loaded or servers were restarted).
  • Log entries / exits into your secret lairs. Did the entry occur while you were in world, or did somebody come by at 3:53 am last night?
  • Find out how long it really took to mine that quarry – print out a real world start and end time.
  • Have your computers/turtles perform tasks at certain times during the real world day.


PASTEBIN CODE: TNLjCCKq
Edited on 04 February 2014 - 03:10 PM
SeaLife #2
Posted 02 February 2014 - 04:12 AM
Are i'm allowed to use this API in my SG-Control System? For the Log-System :D/>?

http://www.computercraft.info/forums2/index.php?/topic/16937-sgcraft-sg-control-system-v13/


Nice Api :)/>
oeed #3
Posted 02 February 2014 - 05:22 AM
Nice to see you made this in to an API. I'll take a further look in to it soon.
surferpup #4
Posted 02 February 2014 - 01:41 PM
Are i'm allowed to use this API in my SG-Control System? For the Log-System :D/>?


I don't see why not – let me know how it works for you.
surferpup #5
Posted 02 February 2014 - 04:48 PM
  • Derp-A-Lert!!!! – use textutils.urlEncode for creating url-friendly strings rather than doing it myself. This will change the dateSeparator functions and make the format strings a lot easier to create and read.

Google is my friend. Google is my friend….

Actually, a very handy function. Thanks to whomever thunked it up.
Edited on 02 February 2014 - 03:49 PM
surferpup #6
Posted 03 February 2014 - 01:17 AM
This is now in its release version. I added a timeout feature running in parallel with the http.get function. Whichever finishes first will return the result value. I also changed the code to take advantage of the textutils.urlEncode function.

Let me know if you have any suggestions or if you encounter any bugs.
surferpup #7
Posted 04 February 2014 - 04:08 PM
There was an error in the timeout function. It is now fixed. Thanks to [member='mibac138'] for catching it.
Akirad0e #8
Posted 21 March 2014 - 07:43 AM
I've just tried using the script and the output seems to ignore the Date/Time Formats I select and shows the following (even when using default),

2014-03-21T07:35:24+00:00

The command I used for this test is below however I've tried tayloring it for my timezone and chosen format with the same output,

printTime(default,default,default,default)
printTime(default,10,dateTime12_ddmmyy,15)

I'm sure I'm doing something wrong, got any advice?

Thanks.
Reciprocaterman #9
Posted 29 March 2014 - 05:02 PM
I'm wanting to use this API as part of a sign-in program on my server. I downloaded from pastebin named it "time". But whenever I call the function

time.getTime("UTC",0,time.format.dateLong,0) Or any other combination, even tried just using time.getTime(), I always get an attempt to call or index a nil value.

Help please?
LayZee #10
Posted 13 April 2014 - 11:40 PM
How is this for a use case? :-)

http://pastebin.com/4brRx86j

Modified version of this http://www.computercraft.info/forums2/index.php?/topic/7763-clock-tower-analogue-clock-face/ by Ramdor
lebalusch #11
Posted 08 June 2014 - 09:07 PM
I've just tried using the script and the output seems to ignore the Date/Time Formats I select and shows the following (even when using default),

2014-03-21T07:35:24+00:00

The command I used for this test is below however I've tried tayloring it for my timezone and chosen format with the same output,

printTime(default,default,default,default)
printTime(default,10,dateTime12_ddmmyy,15)

I'm sure I'm doing something wrong, got any advice?

Thanks.

I agree I am also getting this problem. could a code snip it be posted on how to just get and print "dateTime12_ddmmyyyy".
Maybe a little script with how you would get and print each of the different formats. then I could easily cut and paste and also see how they are all done. If this is not too much to ask somebody that's understanding this API to do.

This is a great API and the amount of data you can get from it is overwhelming to say the least but I can see some great uses for it already. Maybe the ability for the API to only go get the data i request would be nice as this might speed it up.(if this is possible).

Once again thank you for making this API :)/>
jfgcf #12
Posted 05 September 2015 - 05:38 PM
I need help, it's my first time working with computercraft so how do I make this run on a monitor so that I can show the timezone, I already tried but with no success.