如何通过Java找到午夜过去的秒数?

我需要一个函数,它给我从午夜过了几秒钟。 我目前正在使用System.currentTimeMillis()但它给我像UNIX一样的时间戳。

如果我能得到毫秒,对我来说将是一个奖励。

如果你使用Java> = 8,这很容易做到:

 ZonedDateTime now = ZonedDateTime.now(); ZonedDateTime midnight = now.atStartOfDay() Duration duration = Duration.between(midnight, now); long secondsPassed = duration.getSeconds(); 

如果您使用的是Java 7或更低版​​本,则必须通过日历从午夜获取日期,然后减去。

 Calendar c = Calendar.getInstance(); long now = c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); long passed = now - c.getTimeInMillis(); long secondsPassed = passed / 1000; 

java.time

使用Java 8及更高版本中内置的java.time框架。 请参阅教程 。

 import java.time.LocalTime import java.time.ZoneId LocalTime now = LocalTime.now(ZoneId.systemDefault()) // LocalTime = 14:42:43.062 now.toSecondOfDay() // Int = 52963 

显式指定ZoneId是一种好习惯,即使您需要默认的。

TL;博士

 Duration.between( todayStart , now ) .getSeconds() 

java.time

Java 8及更高版本已经编入了java.time框架。

通过使用ZonedDateTime和时区,我们正在处理夏令时(DST)等exception。 例如,在美国,一天可以是23,24或25小时 。 所以直到明天的时间从一天到另一天可能会有±1小时的变化。

首先得到当前时刻。

 ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime now = ZonedDateTime.now( z ); 

现在提取仅限日期的部分,一个LocalDate ,并使用该日期在我们所需时区的那天开始时询问java.time。 不要假设这一天从00:00:00开始。 夏令时(DST)等exception意味着该日可能会在另一个时间开始,例如01:00:00。

 ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( z ); // Crucial to specify our desired time zone! 

现在我们可以得到当前时刻和今天开始之间的增量。 与时间线无关的这种时间跨度由Duration类表示。

 Duration duration = Duration.between( todayStart , now ); 

Duration对象询问整个Duration的总秒数。

 long secondsSoFarToday = duration.getSeconds(); 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

从哪里获取java.time类?

  • Java SE 8Java SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • ThreeTenABP项目特别适用于Android的ThreeTen-Backport (如上所述)。
    • 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。

获取当前时区午夜以来秒数的最简单,最快捷的方法:

一次性设置:

 static final long utcOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis()); 

如果您使用Apache Commons,则可以使用DateUtils.DAY_IN_MILLIS,否则定义:

 static final long DAY_IN_MILLIS = 24 * 60 * 60 * 1000; 

然后,只要你需要时间……:

 int seconds = (int)((System.currentTimeMillis() + utcOffset) % DateUtils.DAY_IN_MILLIS / 1000); 

请注意,如果您的程序可能运行得足够长,并且夏令时发生变化,则需要重新设置…

如果收到有关受保护日历的错误,请使用getTime()。getTime()而不是getTimeInMillis()。 记住你的import:

 import java.util.*; 

在调试时将包括它们:

  Calendar now = Calendar.getInstance(); Calendar midnight = Calendar.getInstance(); midnight.set(Calendar.HOUR_OF_DAY, 0); midnight.set(Calendar.MINUTE, 0); midnight.set(Calendar.SECOND, 0); midnight.set(Calendar.MILLISECOND, 0); long ms = now.getTime().getTime() - midnight.getTime().getTime(); totalMinutesSinceMidnight = (int) (ms / 1000 / 60); 
 (System.currentTimeMillis()/1000) % (24 * 60 * 60) 

使用JodaTime,您可以致电:

 int seconds = DateTime.now().secondOfDay().get(); int millis = DateTime.now().millisOfDay().get(); 

像@secmask一样,如果你需要自格林威治标准时间午夜以来的毫秒,请尝试

 long millisSinceGMTMidnight = System.currentTimeMillis() % (24*60*60*1000);