检测时间旅行


51

如今,无处不在的计算机-汽车,火车,滑板,甚至是核反应堆。您的软件将在时间旅行设备中运行的可能性只是时间问题。你能应付吗?您至少可以检测到吗?

你的任务:

  1. 编写一个循环并不断查询系统时间的程序,以检测时间旅行。
  2. 如果时间在两个连续查询之间向前移动一天或更长时间,则为向前时间旅行。在这种情况下,您的程序应打印:
    TS TS: YYYY? You mean we're in the future?
  3. 如果时间在两个连续查询之间向后移动了一定量,则为倒退时间旅行。在这种情况下,您的程序应打印:
    TS TS: Back in good old YYYY.
  4. TS TS是时间旅行前后的时间戳。YYYY是目标年份。
  5. 时间戳可以采用任何格式,包括至少4位数字的年,月,日,小时,分钟和秒,以非数字分隔。

局限性:

  1. 您必须至少支持19、20和21世纪的日期。
  2. 您必须使用发布此挑战之前使用的语言。
  3. 您必须在发布此挑战后才发布答案。
  4. 您必须使用发布答案之前使用的语言。
  5. 您只能在发布答案后对其进行编辑。
  6. 您的程序不得输出除所需输出以外的任何输出。偶尔出现“伟大的斯科特!” 被允许。

这是代码高尔夫球。最短的答案将获胜。
相关的电影参考可能会使您的答案太长,但可能会使您感到不满意。


31
程序员相信时间的谬误更多,#36:“ 时间总是前进。
门把手

4
您能否更详细地介绍#5?
Mego

4
用数字分开?嘘 YYYYMMDDHHmmSS是我最喜欢的时间戳格式。
Sparr 2015年

3
@Aequitas你怎么知道?也许系统时钟实际上是不可变的,并且“设置”它实际上是在行驶时间
Rune FS

5
限制2、3、4、5确实很苛刻,我不知道我是否能解决。
Surt,2015年

Answers:


4

CJam,118个字节

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

在线解释器不起作用。

两次调整计算机时间后,输出示例:

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.

1
为什么它不能与在线解释器一起使用(除了它不能让您费时间)?
ugoren 2015年

1
因为这是一个无限循环,所以在线解释器仅在程序完成后才显示输出。
丹尼斯

1
那么您如何测试它是否有效?
ugoren 2015年


9

Python 2,210字节

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

时间戳YYYY-MM-DD HH:MM:SS以分号分隔的格式打印。从3切换到Python 2,因为打印时间缩短了2个字符。垃圾邮件与标准输出Great Scott!normies非时间旅行者,因为它更容易,更便宜做比建立一个条件打印。


它期望时间作为输入吗?这不是要问的(也许是含糊的)。同样,当时间表现良好时,它似乎会打印空白行。
ugoren 2015年

我的意思是问操作系统,而不是用户。我会澄清。
ugoren

8

JavaScript(ES6),263个字节

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);}());

这可能需要进行一些重写以使其更高效/更小。

资源:

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);
}());

1
向后旅行的定义是后退任何金额,而不是一天。同样,由于多次now()通话,它可能会错过旅行事件。
ugoren 2015年

尝试打高尔夫球: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 +`?您的意思是我们将来吗?); if(o> n.now())console.log(s +`返回旧的$ {f} .`); o = n.now()“,100);
Stefnotch

我想你可以打高尔夫球的第一部分o=(n=Date).now()
Conor O'Brien 2015年

+ Stefnotch 8.64e+7比的字符长两个字符86400
Florrie

1
@CᴏɴᴏʀO'Bʀɪᴇɴ糟糕!我想知道为什么它不起作用。
Florrie

5

的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)

目前无法打印Great Scott,因为我无法找到仅偶尔打印的好方法。


5

Bash + coreutils,177

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?"
}

3

Ruby,194个字节

我还没有时间真正缩小尺寸。我确定其中有一些优化。

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

取消高尔夫(并且更具可读性):

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

编辑:更正要求操作系统时间,而不是人类。


2
一些建议:使用loop{}代替while 1...end,并尝试将其+用于字符串连接而不是插值。
voikya

3

Lua 5.3,174字节

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

这在很大程度上违反了“时间戳可能采用任何格式”规则……我冒昧地使用“自1970年1月1日以来的秒数”格式,


如果我对打印时间戳的解释不佳,而采用MeepDarknessMeep的结构,我可以(不道德地)将此压缩到...

155字节

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

3
Timestamps may be in any format, that includes at least the 4-digit year, month, day, hour, minute and second, separated by non-digits.-从纪元开始不允许秒数。
Mego

4
好消息是它没有“排除”任何格式
thenumbernine

@ugoren真的有要求应该更具体,以你的意图
美高

我对lua并不十分熟悉,所以我可能错了,但是看起来像这样打印,Back in good ol YYYY但应该打印Back in good old YYYY。(请注意旧的d)
Pokechu22年

不,很好,我想尽一切可能剃掉字节:-p
thenumbernine

2

Lua的5.3 179个 178 173 171 169 168 163字节

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

旁注:如果您需要一个完整的年份数字,则减去六个字节。原因是lua的(或Windows的或某人的!)%c不会输出全年。因此,时间戳看起来可能很奇怪!

这还利用了可以由任何非数字字符分隔的时间戳的优势!

感谢您通知我旧的math.abs参考资料和其他改进@thenumbernine :)

Lua 5.3,151个字节

这是通过仅显示时间戳而不是实际日期来“复制” @thenumbernine的显示时间的方法。这没有竞争力,因为我认为这有点作弊,只需将其张贴在此处以显示我的作品即可:)

::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

1
我们几乎在同一时间发布了两个Lua答案。那不得不说一些关于时空旅行的事情。
thenumbernine

啊,谢谢@thenumbernine!我终于有能力发表评论了:)
MeepDarknessMeep

2

C:363字节

使用此方便的脚本进行精简:

#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);}}

原版的:

#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);
  }
}

示例运行:

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!

我可以通过删除sleep我猜想摆脱10个字节。

顺便说一下,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!

随意放下sleep
ugoren 2015年

2

的JavaScript(ES6)181个 174 170字节

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

注意:尚未使用实时计算机进行测试。

此代码可在Firefox,Chrome,Edge,Node.js Harmony(或与此相关的io.js)中运行。但是,我使用alert,因此必须替换console.logNodeIo Suport:(187字节)

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}.`

解释:

// 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 ?
  // Alert Time Forwand String: 
    (g = alert)
    `${f} ${e}? You mean we're in the future?`:
// else if c is greater than b:
  c > b &&
  // Alert Time Back String: 
    g `${f} Back in good old `+e

我设法写了一篇更短的文章,您可能想看看一下,也许会更好。另外,我认为这很棒!
Stefnotch

您的解决方案有多大,我想看看能否胜任?;)
MayorMonty

向下滚动或单击链接:codegolf.stackexchange.com/a/61544/33160另外,您几乎可以击败它!:D
Stefnotch

2

Python中,170个 165字节

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

这要归功于Morgan Thrapp的回答。这里的主要技巧是timedelta归一化,方便地将timedelta.days设置为负数(即使稍微向过去移动),而为0则表示距未来不到一天的时间。


之后,import*您不需要datetime.前缀。
ugoren 2015年

@ugoren:import*允许datetime.now()代替编写datetime.datetime.now()。从某种意义上说,这是有道理的
2015年

它以一种令人困惑的方式做到了。
ugoren 2015年

1

CachéObjectScript,199字节

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

这个问题在普通的老式MUMPS中可以解决,但由于ANSI MUMPS缺乏$ZD[ATE]T[IME]日期格式化为人类可读的时间戳内在功能,因此将导致不合理的冗长。

这一计划将可能无法检测时间旅行到1841年1月1日之前,也没有时间旅行至12月9999后31,因为这些都是边界$H[OROLOG]报时内在。这个程序也只有二级精度。次秒级的倒退时间故障可能会逃脱其注意。


1

TSQL,355个字节

在工作中,您的SQL Server生产服务器不会有任何花哨的酷语言=)

高尔夫版

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

具有较小更改的可读性更高的版本。

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并不是那么糟糕,因为它是一流的数据类型。

为了高尔夫的缘故,我们使用的精度为3毫秒。循环本身花费的迭代次数要少(取决于服务器)。这里的关键是内部,时间戳是浮点数,整数类型计算经过多少天。它在1753年1月1日至9999年12月31日的日期范围内无法正常工作。


1

VBA,258字节

运行于Windows 7中的Excel 2007

305个字节(如果需要可用性)

警告:如果您在单线程单核计算机上,这可能会最大程度地增加CPU并使Excel / Windows崩溃(最可能在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

如果您希望此代码为“可测试的”,则Application.Wait (Now() + TimeValue("0:00:01"))h=t

输出量

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.

以下是我使用的测试文件。老实说,我对Windows有时具有的很少的安全性感到惊讶。可能无法在所有计算机上正常运行

自行承担风险可能会产生重大的持久副作用!
Sub DOC() t = 31346.6868055556 Date = DateSerial(Year(t), Month(t), Day(t)) Time = TimeSerial(Hour(t), Minute(t), Second(t)) q End Sub


1

Javascript 173169162字节

Javascript非常流行...

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?`))

说明(旧版本代码):

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

0

处理中,270字节

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()+": ");}

展开:

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()+": ");
}

样本输出:

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

0

红宝石,160个 157 155 154字节

这里有很多东西可以打高尔夫球

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}

0

Mathematica,295个字节

该程序每秒向操作系统请求新的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,"."})]];

输出量

通过手动输入日期/时间进行测试。

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.

绝对可以更好地格式化输出。它确实满足了所述要求。


你为什么要捷径LocalTime[]?在以下代码中仅出现一次。
迈克尔·斯特恩

有一次,我使用了两次。虽然好捕获。
迷失知识

删除它,您保存三个字符。
Michael Stern

0

Groovy,244个字节

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}

0

Java,378个字节。

function detect()
{
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) );
if(diffInDays>0) 
System.out.println(olderDate+" "+newerDate+": "+newerDate.getYear()+"? You mean we're in the future?");
else if(diffInDays<0) 
System.out.println(olderDate+" "+newerDate+": "+"Back in good old "+newerDate.getYear());
} 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.