ID:1565605
 
Keywords: time
(See the best response by Taitz.)
Problem description:

Need to get the time, and to have it as as accurate as possible. The game won't be too graphics intensive, so shouldn't have much of an issue with lag.. Any workarounds will be considered.

World realtime is too inaccurate to be used for anything intensely time related, and world timeofday only goes to 1/10th second (plus, wraps around to 0 at the end of the day.) And world time (server uptime) is the same way, but shuts down when there are no players / inaccurate if the server runs overtime.

I'm fairly sure there is no way to get the current millisecond in byond by itself, much to my dismay.

Is there another way of getting extremely accurate time?

If so, how would I do this? And how accurate would the time be?

Some research (google :P) pointed to using a DLL (like Kernel32.dll) to get the system time.. but I have no clue how I would do this / if it would work.
Well executing from a DLL is just the same as just using batch programming(SHELL() in BYOND).

proc
{
set_timestamp()
{
if(fexists("data.currenttime")){fdel("data.currenttime");};
shell("cmd /C echo %time% > data.currenttime");
if(fexists("data.currenttime")){time_stamp=file2text("data.currenttime");fdel("data.currentime");};
else time_stamp="00:00:00.00"
return time_stamp
}
}

var
{
time_stamp=""
}


mob
{
verb
{
Test()
{
src<<set_timestamp();
}
}
}


If you really want to use this method, here.
Note: if you desire to use the .DLL, you will need to run a Call() statement and I'm unsure if BYOND will communicate with that.

This method will log the system time into a file everytime the set_timestamp() proc is ran and will also return the timestamp.

I hope this helps.
DLL support in BYOND isn't great, you should avoid that, though.
In response to Ssj4justdale
Ssj4justdale wrote:
Well executing from a DLL is just the same as just using batch programming(SHELL() in BYOND).

> proc
> {
> set_timestamp()
> {
> if(fexists("data.currenttime")){fdel("data.currenttime");};
> shell("cmd /C echo %time% > data.currenttime");
> if(fexists("data.currenttime")){time_stamp=file2text("data.currenttime");fdel("data.currentime");};
> else time_stamp="00:00:00.00"
> return time_stamp
> }
> }
>
> var
> {
> time_stamp=""
> }
>
>
> mob
> {
> verb
> {
> Test()
> {
> src<<set_timestamp();
> }
> }
> }
>

If you really want to use this method, here.

This actually works great! Gets the time down to a usable time (Though can't get milliseconds, centiseconds will work for what I need).. but is there a way to do this silently / in the background, without opening a console window every time?
I would hate to say this but there isn't unless you can use Call() to get the timestamp from the .dll.

The console window will appear only on the host computer, so if you have a shell server, you will never see the console window appear.

If you don't but you have a designated computer set just for hosting and no other purposes, then that computer that hosts it will only get the console window.

(You can try posting a suggestion/feature to allow BYOND run console messages without using an actual console window appearing)

Aside from that, I can create an alternative that will require internet usage and it will contact a webserver, log the clients current time(the host computers time, not the server of the website) and it will be parsed to text for you to do whatever you wish.

The only issue with this method is it requires internet connection and if your connection or the server I upload the script too's connection is bad, then you may not get a return value until after a few attempts.

Overall, the quickest method is what you have now unless, I believe, you create your own external .dll to create the timestamp and make it so it can communicate with BYOND.
I think you could also use the SQLite database which was recently added to DM. You could do a
SELECT CURRENT_TIMESTAMP
call to it, no? I might be wrong due to not having access to my computer right now, but you should be able to do something with it.
Alternative:
SELECT datetime('now','localtime')

Might be too inaccurate?
In response to Taitz
I haven't found a reference to SQLite anywhere, but apparently it's here.

This is relevant to my interests and could potentially solve my problem.. if I can figure it out.

Is there a tutorial somewhere on this?
The feature implementation update is here, it also gives the basic insight into it, if you don't know SQL or any of the like. http://www.byond.com/forum/?post=1506010
Haven't tested this myself, but it should work, might need a bit of modification to suit your needs though.
var
database
db=new("test.db")
query
q=new("SELECT datetime(CURRENT_TIMESTAMP,'localtime')")
if(!q.Execute(db))
world<<q.ErrorMsg()
else
world<<q.GetRowData()
... didn't realize I had to download the beta first for this.

But I did try what you wrote, and got an infinite loop error:

proc/spacetime()
var
database
db=new("test.db")
query
q=new("SELECT datetime(CURRENT_TIMESTAMP,'localtime')")
if(!q.Execute(db))
world<<q.ErrorMsg()
else
world<<q.GetRowData()

mob/verb/spacetime()
spacetime()


Error:
runtime error: Maximum recursion level reached (perhaps there is an infinite loop)
To avoid this safety check, set world.loop_checks=0.
verb name: spacetime (/mob/verb/spacetime)
usr: KingCold999 (/mob)
src: KingCold999 (/mob)
call stack:
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
...
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
KingCold999 (/mob): spacetime()
You could try this? I am not at my PC right now so I can't test.
var
database
db=new("test.db")
query
q=new("SELECT datetime('now','localtime')")
if(!q.Execute(db))return
world<<q.GetRowData()
In response to Taitz
Figured out my problem - the verb and proc were named the same. Didn't even know that could be a problem.

Now all I'm getting is /list though. When I go through the list I get this:

"datetime('now','localtime'):"

Current code:
proc/spacetime2()
var
database
db=new("test.db")
query
q=new("SELECT datetime('now','localtime')")
if(!q.Execute(db))return
var/ret=""
for(var/i in q.GetRowData())
ret+="[i]:"
world<<ret

mob/verb/spacetime()
spacetime2()
What kind of result did you get when you used CURRENT_TIMESTAMP instead of 'now'?
('CURRENT_TIMESTAMP','localtime'):


That is what I got.
Best response
var
database
db=new("test.db")
query
q=new("SELECT datetime('now','localtime')")
if(!q.Execute(db))return
while(q.NextRow())
var/row[]=q.GetRowData()
for(var/i in row)
world<<row[i]
Getting somewhere! This has the time on it, down to the second:

2014-05-04 05:34:20

In response to KingCold999
proc/spacetime2()

var
database
db=new("test.db")
query
q=new(" select strftime('%Y-%m-%d %H:%M:%f', 'now')")
if(!q.Execute(db))return
while(q.NextRow())
var/row[]=q.GetRowData()
for(var/i in row)
world<<row[i]


Eureka! Simple google search after Taitz's help and I got it to show milliseconds :D

Thankyou Taitz. You are my hero.

Thankyou Ssj4justdale too. This info on shell will also be useful :)
This should be down to the millisecond or so.
client
verb
testDb()
var
database
db=new("test.db")
query
q=new("SELECT strftime('%Y-%m-%d %H:%M:%f','now')")
if(!q.Execute(db))return
while(q.NextRow())
var/row[]=q.GetRowData()
for(var/i in row)
world<<row[i]
Mind I ask why you need this kind of accuracy in the first place?
Page: 1 2