2017-04-03 728 views
-1

我正在尝试确定时间戳是否超过30秒,但由于某种原因,它的返回时间超过了30秒,甚至还没有过几秒钟。检查时间戳是否超过30秒

例子:https://ideone.com/KLIIBz

public static Boolean cooldown(int id) { 

    Calendar now = Calendar.getInstance(); 
    now.add(Calendar.SECOND, -secondsAgo); 
    long timeAgo = now.getTimeInMillis(); 
    if (cooldown.containsKey(id)) { 

     System.out.println(cooldown.get(id) + " | " + timeAgo); 

     // Stored timestamp always older than timeAgo 
     if (cooldown.get(id) < timeAgo) { 

      cooldown.remove(id); 

     } else { 

      // This code should be executed, as I am running the function one after another from same UUID not even a second or two apart. 
      return false; 

     } 

    } 

    now = Calendar.getInstance(); 
    cooldown.put(id, now.getTimeInMillis()); 

    return true; 

} 
+1

请发布[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)。你的代码并非如此什么是“目标”,你如何称呼“冷却时间()”? – Andreas

+0

所有的代码真的是多余的。唯一的问题是为什么时间戳会比它更早。 – JordanSasquatchMan

+1

如果代码的其余部分非常冗余,那么创建一个最简单的例子应该很简单,对吧? –

回答

2

使用java.time

您正在使用的是现在传统麻烦旧日期,时间类,被java.time类取代。

Instant类表示UTC中的时间轴上的一个时刻,分辨率为nanoseconds(最多九(9)位小数)。

Instant start = Instant.now(); 
… 
Instant stop = Instant.now(); 

捕获开始和结束之间的时间间隔为Duration

Duration duration = Duration.between(start , stop); 

表示您的限制30秒。

Duration limit = Duration.ofSeconds(30); 

通过调用Duration::compareToComparable方法进行比较。

顺便说一句,具有收集和两个命名cooldown的方法是没有帮助的。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore

+0

而不是'compareTo()'我想我只考虑'duration.getSeconds()

+1

@ OleV.V。当然是一个很好的建议。 'compareTo'语法很尴尬且不直观。实际上,'持续时间'应该有比较方法。类似于“isEqual”,“longerThan”,“shortThan”。 –

-2

的currentTimeMillis回报:区别,以毫秒为单位,当前时间和午夜,1970年1月1日,UTC

你能解释为什么你使用它之间。

+0

我不知道。你告诉我。再次。我试图存储,并检查一个时间戳(无论什么类型的时间戳),看它是否超过30秒,或者我定义的任何东西,甚至是几分钟。 许多关于SO的例子都使用System.currentTimeMillis()来表示时间戳。 请发布问题的答案,而不是问题。这可以保存以供评论。 – JordanSasquatchMan

+2

要求澄清应在评论中。这当然不是一个答案。等到你有要求留下评论的50名代表。在此之前,请删除此答案以清除我刚刚给出的负面报告。 – Andreas

2

试试这个:

public class JavaApplication11 
{ 
    public static void main(String[] args) 
    { 
     // TODO code application logic here 
     Calendar now = Calendar.getInstance(); 
     now.add(Calendar.SECOND, -30);//Set Calendar 30 seconds in the past. 

     System.out.println(has30SecsPassed(now)); 
    } 

    static boolean has30SecsPassed(Calendar calendar) 
    { 
     Long numberOfMilliSec = Calendar.getInstance().getTimeInMillis() - calendar.getTimeInMillis(); 
     double numberOfSecondsPassed = numberOfMilliSec/1000.0; 
     System.out.println("seconds passed: " + numberOfSecondsPassed); 
     return numberOfSecondsPassed >= 30; 
    } 

} 
1

此:

Calendar now = Calendar.getInstance(); 
now.add(Calendar.SECOND, -secondsAgo); 
long timeAgo = now.getTimeInMillis(); 

是开销太大或只是让您应用中的实际时间戳......你可以叫

System.currentTimeMillis(); 

并验证cooldown.get(id)和timeAgo之间的这种情况

所以他们满足cooldown.get(ID) - TIMEAGO < 30 * 1000或不...

1

要从the code on Ideone that you link to判断,问题在于secondsAgo是0,而不是30.您在构造函数中将其设置为30,但由于您从不从类创建对象,所以构造函数从不执行。 secondsAgo是一个静态字段,因此您可以在没有对象且未初始化的情况下访问它。你只要得到int字段所有的初始值,即0.

我在Ideone看到的输出结果肯定了我的意思。在形式1491194338577 | 1491194338578的所有行中,数字要么相同,要么相隔1毫秒。即使您已从Calendar对象中减去secondsAgo秒,您从timeAgo开始,timeAgo永远不会比您在毫秒前放入地图的时间戳早30秒。所以不,你没有减去30秒;你正在减去0秒。

不过我还是同意罗勒布尔克的回答是:如果你可以使用Java 8无论如何,你应该抛出的Calendar类拿走并使用InstantDuration。你得到更清晰,更易读的代码。将Instant对象放在您的地图中,而不是Long s,它突然不言自明。