# Detect Time Travel

Computers are everywhere nowadays - in cars, trains, skateboards, even nuclear reactors. The possibility that your software will run in a time travelling device is just a matter of time. Can you deal with it? Can you at least detect it?

1. Write a program that loops and keeps querying the system time, in order to detect time travel.
2. If time moves forward a day or more between two consecutive queries, it's forward time travel. In this case, your program should print:
TS TS: YYYY? You mean we're in the future?
3. If time moves back, by any amount, between two consecutive queries, it's backward time travel. In this case, your program should print:
TS TS: Back in good old YYYY.
4. TS TS are the timestamps before and after the time travel. YYYY is the destination year.
5. Timestamps may be in any format, that includes at least the 4-digit year, month, day, hour, minute and second, separated by non-digits.

Limitations:

1. You must support dates in the 19th, 20th and 21st centuries, at least.
2. You must use a language that existed before this challenge was posted.
3. You must post your answers only after this challenge was posted.
4. You must use a language that existed before your answer was posted.
6. Your program must not print any output other than the required output. An occasional "Great Scott!" is allowed.

This is code-golf. The shortest answer wins.

• More falsehoods programmers believe about time, #36: "Time always goes forwards."
– Doorknob
Oct 21 '15 at 11:40
• Could you be a bit more specific about #5?
– user45941
Oct 21 '15 at 13:27
• separated by nondigits? boo. YYYYMMDDHHmmSS is my favorite timestamp format. Oct 21 '15 at 17:13
• @Aequitas how do you know? maybe the system clock is actually immutable and "setting" it is actuallly time traveling Oct 22 '15 at 5:42
• Limitation 2,3,4,5 are really harsh, I don't know if I can handle that.
– Surt
Oct 23 '15 at 0:10

## Python 2, 210 bytes

from datetime import*
o=0
while 1:n=datetime.now();o=o or n;print"%s;%s: %s? You mean we're in the future?"%(o,n,n.year)if(n-o).days>=1else"%s;%s: Back in good old %s."%(n,o,n.year)if(n<o)else"Great Scott!";o=n


Timestamps are printed in in YYYY-MM-DD HH:MM:SS format, separated with semicolons. Switched to Python 2 from 3 since it's 2 chars shorter to print. Spams stdout with Great Scott! for normies non-time-travellers, since it's easier and cheaper to do that than set up a conditional print.

• Does it expect the time as input? This is not what's asked (maybe it's vague). Also, it seems to print blank lines when time behaves well. Oct 21 '15 at 12:18
• I meant asking the OS, not the user. I'll clarify. Oct 21 '15 at 12:21

# JavaScript (ES6), 263 bytes

n=Date;o=n.now();(function g(){k=new n;j=new n(o);s=${k}${o} ;if(n.now()-o>86400)console.log(${s}${k.getFullYear()}? You mean we're in the future?);if(o-n.now()>84600){console.log(${s}Back in good old${k.getFullYear()}.);}o=n.now();setTimeout(g,100);}());


This could probably do with some rewriting to make it more efficient/small.

Source:

n=Date;
o=n.now();

(function go() {
k=new n;
j=new n(o);
s=${k}${o} ;
if (n.now() - o > 86400) {
console.log(${s}${k.getFullYear()}? You mean we're in the future?);
}
if (o - n.now() > 84600) {
console.log(${s}Back in good old${k.getFullYear()}.);
}
o=n.now()
setTimeout(go,100);
}());

• Backwards travel is defined as moving back by any amount, not one day. Also, due to the multiple now() calls it may miss a travel event. Oct 21 '15 at 12:21
• An attempt at golfing this: n=Date,o=n.now();setInterval("d=new n,s=d+ ${new n(o)} ;f=d.getFullYear();if(n.now()-o>8.64e+7)console.log(s+f+? You mean we're in the future?);if(o>n.now())console.log(s+Back in good old${f}.);o=n.now()",100); Oct 21 '15 at 13:49
• I think you can golf the first part to o=(n=Date).now(). Oct 21 '15 at 17:22
• +Stefnotch 8.64e+7 is two characters longer than 86400. Oct 21 '15 at 17:28
• @CᴏɴᴏʀO'Bʀɪᴇɴ Oops! I was wondering why it didn't work. Oct 21 '15 at 19:24

# Python 3, 195

from datetime import*
n=datetime.now
p=n()
while 1:
c=n();f=(p,c,p.year);s=(0,("%s %s: %s? You mean we're in the future?"%f,"%s %s: Back in good old %s."%f)[p.day>c.day])[p>c];p=c
if s:print(s)


Currently doesn't print Great Scott because I can't find a good way of only making it occasional.

d()(date -d@"$@") for((b=date +%s;a=date +%s;b=a)){ t=d$a\ d $b ((a<b))&&d$b "+$t: Back in good old %Y." ((a>b+86400))&&d$b "+$t: %Y? You mean we're in the future?" }  # CJam, 118 bytes et:Tes{es_@-[TS*Set:TS*':S]\_864e5<{[1$et0="? You mean we're in the future?"N]o}|0<{[_"Back in good old "et0='.N]o}&}g


This does not work with the online interpreter.

Sample output after adjusting my computer's time twice:

2015 10 21 11 2 45 1 3 -10800000 2015 10 23 11 2 45 0 5 -10800000: 2015? You mean we're in the future?
2015 10 23 11 2 53 448 5 -10800000 2015 10 21 11 2 52 0 3 -10800000: Back in good old 2015.

• Why doesn't it work with the online interpreter (except that it doesn't let you fiddle with the time)? Oct 25 '15 at 7:51
• Because this is an infinite loop, and the online interpreter shows output only after the program has finished. Oct 25 '15 at 13:12
• So how do you test that it works? Oct 25 '15 at 16:16
• Using the Java interpreter. Oct 25 '15 at 16:20

# Ruby, 194 bytes

I haven't had the time to really cut this down to size yet. I'm sure there are a few optimizations hiding in there.

require 'time';t=nil;while 1;n=Time.now;if t;s="#{t} #{n}: ";y=n.year;puts t>n ? "#{s}Back in good old #{y}" : (n>t+86400 ? "#{s}#{y}? You mean we're in the future?": "Great Scott!");end;t=n;end


Ungolfed (and a lot more readable):

require 'time'
t=nil
while 1
n=Time.now
if t                                             # on second or later pass
s="#{t} #{n}: "                                # prepare the timestamp
y=n.year
puts t>n ?                                     # if we go back
"#{s}Back in good old #{y}" :                # timestamp + phrase
(n>t+86400 ?                                 # else, more than one day forward
"#{s}#{y}? You mean we're in the future?": # timestamp + future
"Great Scott!")                            # Great Scott!
end
t=n                                              # set a new jump point
end


Edit: corrected to ask OS for time, rather than a human.

• A few recommendations: Use loop{} instead of while 1...end, and try using + for string concatenation instead of interpolation. Oct 22 '15 at 0:25

# Lua 5.3, 174 bytes

T=os.time P=print l=T()::a::t=T()b=l.." "..t..": "y=os.date('%Y',t)_=t<l and
P(b.."Back in good old "..y)or t>l+86399 and
P(b..y.."? You mean we're in the future?")l=t goto a


This is playing heavily off of the "Timestamps may be in any format" rule ... which I took the liberty of using the format of "seconds since Jan 1, 1970"

If I keep my shoddy interpretation of printing timestamps, and adopt the structure of MeepDarknessMeep, I can (unethically) squeeze this down to ...

# 155 bytes

T=os.time::G::l=t or T()t=T()_=(t>l+86399or t<l)and
print(l.." "..t..": "..os.date(t<l
and"Back in good old %Y"or"%Y? You mean we're in the future?"))goto G

• Timestamps may be in any format, that includes at least the 4-digit year, month, day, hour, minute and second, separated by non-digits. - that doesn't allow seconds since epoch.
– user45941
Oct 21 '15 at 13:15
• good thing it didn't "exclude" any formats Oct 21 '15 at 13:19
• @ugoren Really that requirement should be more specific as to your intention
– user45941
Oct 21 '15 at 13:21
• I'm not fully familiar with lua so I may be wrong, but it looks like this prints Back in good ol YYYY but it should print Back in good old YYYY. (Note the d in old) Oct 21 '15 at 15:39
• nope good catch, I was trying to shave bytes wherever I could :-p Oct 21 '15 at 16:31

# Lua 5.3, 179178173171169168 163 bytes

q="%Y %c: "c=os.date::a::d=f f=os.time()_=d and(f-d>86399or f<d)and print(c(q,d)..c(q..(f<d and"Back in good old %Y."or"%Y? You mean we're in the future?")))goto a


Side note: If you take out the need for a full year number then subtract six bytes. The reason is that lua's (or windows' or someone's!) %c doesn't output the full year. Because of this, the timestamps may look weird!

This also takes advantage of timestamps being able to be seperated by any non digit characters!

Thanks for notifying me of my old math.abs reference and other improvements @thenumbernine :)

# Lua 5.3, 151 bytes

This is 'copying' off of @thenumbernine's method of displaying time by just showing the timestamp instead of the actual date. This isn't competitive since I think it is a bit of cheating, just posting it here to display my work :)

::a::d=f f=os.time()_=d and(f-d>86399or f<d)and print(d.." "..f..os.date(f<d and": Back in good old %Y."or": %Y? You mean we're in the future?"))goto a

• We posted both our Lua answers at nearly the exact same time. That has to say something about time travel. Oct 21 '15 at 13:13
• Ahah, Thanks @thenumbernine! I finally got my ability to comment :) Oct 21 '15 at 13:43

# Python, 170 165 bytes

from datetime import*
n=datetime.now
c=n()
while 1:
p=c;c=n()
if(c-p).days:print p,"%s:"%c,["%s? You mean we're in the future?","Back in good old %s."][c<p]%c.year


This owes a lot to Morgan Thrapp's answer. The main trick here is timedelta normalization, which conveniently makes timedelta.days negative when moving even slightly towards the past, and 0 when moving less than a day to the future.

• After import* you don't need the datetime. prefix. Oct 25 '15 at 10:21
• @ugoren: import* allows one to write datetime.now() instead of datetime.datetime.now(). It kind of makes sense, in a way...
– han
Oct 25 '15 at 11:44
• In a confusing way, it does. Oct 25 '15 at 16:16

# Caché ObjectScript, 199 bytes

l s k=86400 f  s e=+$H,t=$P($H,",",2) s:'d d=e,s=t s z=$ZDT(h)_" "_$ZDT($H)_": ",y=h\365+1841 w:e>d !,z,y,"? You mean we're in the future?" w:(k*t+e)<(k*s+d) !,z,"Back in good old ",y s h=$H,d=e,s=t  This problem is solvable in plain old MUMPS, but would be unreasonably lengthy, since ANSI MUMPS lacks the $ZD[ATE]T[IME] intrinsic function for formatting dates into human-readable timestamps.

This program will probably not detect time-travel to before 1 Jan 1841, nor time-travel to after 31 Dec 9999, since these are the bounds of the $H[OROLOG] timekeeping intrinsic. This program also only has second-level precision; sub-second-level backwards time glitches will likely escape its notice. ## TSQL, 355 bytes At the work so no fancy cool languges stick with your SQL Server production server =) Golfed version declare @a datetime=getdate(),@b datetime,@d float,@ char(99),@y char(4)while 0=0begin select @b=getdate(),@d=cast(@b as float)-cast(@a as float),@y=' '+DATEPART(y,@b),@=cast(@a as char(20))+' '+cast(@a as char(20))+': 'if @d>=1set @=@+@y+'? You mean we''re in the future?'if @d<0set @=@+'Back in good old '+@y+'.'print @ set @a=@b end  More readable version with minor changes. declare @t0 datetime = getdate(), @t1 datetime, @d float, @m varchar(99), @y char(4) while 0=0 begin set @t1 = getdate() set @d = cast(@t1 as float) - cast(@t0 as float) set @y = ' ' + DATEPART(yy, @t1) set @m = cast(@t0 as varchar(30)) + ' ' + cast(@t0 as varchar(30)) + ': ' if @d >= 1 set @m = @m + @y + '? You mean we''re in the future?' if @d < 0 set @m = @m + 'Back in good old ' + @y + '.' print @m set @t0 = @t1 end  SQL is not that bad in respect to timestamps since it's a first class data type. For the golf's sake we are using a type with 3 milliseconds precision. The loop itself takes less that that to iterate (depending of your server). The key here is internaly that time stamp is a float and the integer type counts how many days passed. It ill work fine in January 1, 1753, through December 31, 9999 date range. # VBA, 258 Bytes ### Ran with:Excel 2007 in Windows 7 305 bytes if Usability is required WARNING This MAY Max your CPU and Crash Excel/Windows if you are on a Single Threaded single core computer (Most likely found in 1985) Sub q() h=CDbl(Now()) While 1 t=CDbl(Now()) If t>h+1 Then Debug.Print (CDate(t) & " " & CDate(h) & ":" & Year(t) & "? You mean we're in the future?") If t<h Then Debug.Print (CDate(t) & " " & CDate(h) & ": Back in good old " & Year(t) & ".") h=t Wend End Sub  If you want this Code to be "Testable" then add Application.Wait (Now() + TimeValue("0:00:01")) after h=t ### Output 10/22/2015 3:04:45 PM 10/22/2015 3:04:43 PM:2015?You mean we're in the future? 10/22/2015 3:06:48 PM 10/22/2015 3:06:46 PM: Back in good old 2015.  Below is the test file I used. I'm Honestly Amazed at how little security Windows has sometimes. May not run as expected on all computers Run at Own Risk Could Have Major lasting Side Effects!!!! Sub DOC() t = 31346.6868055556 Date = DateSerial(Year(t), Month(t), Day(t)) Time = TimeSerial(Hour(t), Minute(t), Second(t)) q End Sub  # C: 363 bytes Minified using this handy script: #include<stdio.h> #include<time.h> void p(time_t*t){char b[64];strftime(b,64,"%FT%T",localtime(t));printf("%s ",b);}int main(void){time_t a,b,d=60*60*24;int y;time(&a);while(1){time(&b);y=localtime(&b)->tm_year+1900;if(b<a){p(&a);p(&b);printf("Back in good old %d\n",y);}else if(b>a+d){p(&a);p(&b);printf("%d? You mean we're in the future?\n",y);}a=b;sleep(1);}}  Original: #include <stdio.h> #include <time.h> void p(time_t * t) { char b[64]; strftime(b, 64, "%FT%T", localtime(t)); printf("%s ", b); } int main(void) { time_t a, b, d = 60*60*24; int y; time(&a); while(1) { time(&b); y = localtime(&b)->tm_year+1900; if (b < a) { p(&a); p(&b); printf("Back in good old %d\n", y); } else if (b > a + d) { p(&a); p(&b); printf("%d? You mean we're in the future?\n", y); } a = b; sleep(1); } }  Example run: 2015-10-23T23:30:03 1985-06-14T16:27:00 Back in good old 1985 1985-06-14T16:27:07 1999-02-09T14:15:00 1999? You mean we're in the future? 1999-02-09T14:15:09 2015-02-09T14:15:00 2015? You mean we're in the future? 2015-02-09T14:15:36 2015-10-21T07:28:00 2015? You mean we're in the future? 2015-10-21T07:29:06 1985-10-26T09:00:00 Back in good old 1985 1985-10-26T09:00:28 2055-11-12T06:38:00 2055? You mean we're in the future? 2055-11-12T06:38:12 1919-10-07T00:09:57 Back in good old 1919 1919-10-07T00:09:57 2055-11-12T06:38:14 2055? You mean we're in the future? # tried to go to 1955 - fail. 2055-11-12T06:39:09 2015-10-23T23:32:03 Back in good old 2015 # auto-time back to 2015 because my laptop didn't like the jump to 2055!  I could get rid of 10 bytes by removing the sleep I guess. By the way, some time-jumping handiness for Mac/Linux: sudo date 1026090085 # Sat 26 Oct 1985 09:00:00 sudo date 1021072815 # Wed 21 Oct 2015 07:28:00 sudo date 1112063855 # Intended to be 1955 but is 2055. Don't use!  • Feel free to drop the sleep. Oct 25 '15 at 7:49 # JavaScript (ES6) 181174 170 Bytes for(a=Date;c=b||a.now(),b=d();e=new a(b).getFullYear(),f=${a(c)} ${a(b):})b>c+864e5?(g=alert)${f} ${e}? You mean we're in the future?:c>b&&g${f} Back in good old +e


Note: Has not been tested with a real time machine.

This code runs in Firefox, Chrome, Edge, Node.js Harmony (or io.js for that matter). But, I use alert, so that will have to be replaced by console.log for Node and Io Suport: (187 Bytes)

for(a=Date,b=0;c=b||(d=a.now)(),b=d();e=new a(b).getFullYear(),f=${a(c)}${a(b):})b>c+864e5?(g=console.log)${f}${e}? You mean we're in the future?:c>b&&g${f} Back in good old${e}.


Explained:

// Using for like a while loop, defining relevant variables:
for (a = Date, b = 0;
// Defing b and c: c becomes b, b becomes now. Also defining a shorthand for Date.now:
c = b || a.now(),
b = d();
// Defining Variables Relevant to this loop: e is the year according to b, f is the "TS TS:" string:
e = new a(b).getFullYear(),
f = ${a(c)}${a(b):
)
// If b is greater than c plus a day (in milliseconds):
b > c + 864e5 ?
${f}${e}? You mean we're in the future?:
// else if c is greater than b:
c > b &&
g ${f} Back in good old +e  • I managed to write an even shorter one, you might want to have a look at it and possibly make yours better. Also, I think it is great! Oct 23 '15 at 13:34 • How big was your solution, I want to see if I can beat it? ;) – bren Oct 24 '15 at 3:57 • Scroll down or click on the link: codegolf.stackexchange.com/a/61544/33160 Also, you are pretty close to beating it! :D Oct 24 '15 at 7:40 ## Processing, 270 bytes int p;long x=System.currentTimeMillis();void draw(){int q=millis(),y=year();if(q<p){t(p);print("Back in good old "+y+".");}if(q>p+86400000){t(p);print(y+"? You mean we're in the future?");}p=q;}void t(int m){print(new java.util.Date(x+m)+" "+new java.util.Date()+": ");}  Expanded: int p; long x=System.currentTimeMillis(); void draw() { int q=millis(), y=year(); if (q<p) { t(p); print("Back in good old "+y+"."); } if (q>p+86400000) { t(p); print(y+"? You mean we're in the future?"); } p=q; } void t(int m) { print(new java.util.Date(x+m)+" "+new java.util.Date()+": "); }  Sample output: Wed Oct 21 13:21:59 EDT 2015 Mon Oct 19 13:21:59 EDT 2015: Back in good old 2015. Mon Oct 19 13:22:08 EDT 2015 Wed Oct 21 13:22:08 EDT 2015: 2015? You mean we're in the future  # Ruby, 160157155 154 bytes A lot of things to golf here a=Time.new;loop{b,s,y=Time.new,"#{a} #{b}: ",b.year;$><<(a>b ? s+"Back in good old #{y}.\n":b>a+86400 ? s+"#{y}? You mean we're in the future?\n":"");a=b}


# Mathematica, 295 bytes

The program asks the OS every second for new TS.

f:=LocalTime[]
p=Print;
y:=DateString[#,"Year"]&
s:=ToString[#]<>" "&
d:=QuantityMagnitude@DateDifference[a,b]
j=StringJoin;
While[True,
a=b;
b=f;
Pause@1;
Which[d>=0,
p@(j@@{s@a,s@b,": ",y@b,
"? You mean we are in the future?"}),
d<0,
p@(j@@{s@a,s@b," Back in good old ",y@b,"."})]];


# Output

Tested by manually feeding in date/time.

DateObject[{2015, 10, 23}, TimeObject[{18, 36, 17.9618}], TimeZone -> \
-4.] DateObject[{2015, 10, 25}, TimeObject[{18, 42, 0.264913}], \
TimeZone -> -4.] : 2015? You mean we are in the future?

DateObject[{2015, 10, 23}, TimeObject[{18, 43, 0.141572}], TimeZone -> -4.] DateObject[{2015, 10, 23}, TimeObject[{18, 42, 3.30681}], TimeZone -> -4.]  Back in good old 2015.


Definitely could have format the output better. It does fulfill the requirements as stated.

• why do you shortcut LocalTime[]? It appears only once in the following code. Oct 30 '15 at 15:18
• At one point, I was using it twice. Good catch though. Oct 30 '15 at 16:45
• Remove it and you save three characters. Oct 30 '15 at 16:54

# Javascript 173 169 162 bytes

Javascript is pretty popular...

for(e=Date,n=e.now;o=n(a=alert);)d=new e,f=d.getFullYear(n(o>n(s=d+ ${e(o)}:)&&a(s+Back in good old${f}.))-o>864e5&&a(s+f+? You mean we're in the future?))


Explanation (Older version of the code):

for(e=Date,n=e.now,a=alert,o=n();;o=n()) //Set up the variables and update o, the previous time

d=new e,s=d+ ${e(o)} ,f=d.getFullYear(), //d is the date, s is a string with the 2 timestamps, f is the year n()-o>8.64e7&&a(s+f+? You mean we're in the future?), //Future check o>n()&&a(s+Back in good old${f}.) //Past check


# Groovy, 244 bytes

def s=9999,d={new Date()},y={it.year+1900},f={t,n->"$t$n: ${y(n)}? You mean we're in the future?"},p={t,n->"$t $n: Back in good old${y(n)}."},t=d()
while(!sleep(s)){n=d()
c=n.time-t.time
println c<0?p(t,n):c>s*2?f(t,n):'Great Scott!'
t=n}