2015-09-25 114 views
4

以毫秒为单位给定UTC的午夜时间的建议方式是什么?我尝试了下面这似乎工作,想知道是否有更好/更干净的做同样的事情。以millis为单位获得午夜纪元时间

public long toUtcMidnight(final Long date) { 
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.of("UTC")) 
      .toLocalDate() 
      .atStartOfDay() 
      .toInstant(ZoneOffset.UTC) 
      .toEpochMilli(); 
    } 

我们可以为此使用Joda时间,但是我只想为此使用java 8日期库。

+0

这对我来说很不错。您也可以使用GregorianCalendar方式,但我怀疑它会更好。 – pmartin8

+0

我不喜欢这样的事实,我必须提供两次“UTC”,一次作为ZoneId,一次作为偏移量:( – u07103

回答

0

你有什么作品,但如果你在寻找更具可读性的东西,怎么样使用日历?

public long toUtcMidnight(long date) { 
     Calendar cal = Calendar.getInstance(); 
     cal.setTimeInMillis(date); 
     cal.setTimeZone(TimeZone.getTimeZone("UTC")); 
     cal.set(Calendar.HOUR_OF_DAY, 0); 
     cal.set(Calendar.MINUTE, 0); 
     cal.set(Calendar.SECOND, 0); 
     cal.set(Calendar.MILLISECOND, 0); 
     return cal.getTimeInMillis(); 
} 
+1

我不觉得这是更可读的'truncatedTo'! – Tunaki

4

你应该能够截断一个Instant的一天。从javadoc

截断的瞬间返回原始的副本领域 比设置为零指定的单位小。

使用ChronoUnit.Days,你会清零时,分,秒,毫秒时间。

例如

Instant.ofEpochMilli(date).truncatedTo(ChronoUnit.DAYS).toEpochMilli(); 
+0

绝对整洁!看起来像truncate在内部使用UTC – u07103

0

因为这一切都UTC只是做millis/86400_000 * 86400_000;

long(int)部分将截断为几天,* msecs/day将返回msecs。

如果需要,您可以截断为几周,几小时或任何你想要的。

+0

想知道这是否会导致代码的可读性降低?Sotirios的解决方案看起来很可读,请让我知道,如果您认为不然, – u07103

+0

这取决于您是否看到“明天见亚”或“看到亚在86400秒“?我认为大多数程序员已经记住了以msecs为单位的常见时间单位,但有时候我会看到一个静态变量'MSECS_PER_DAY',在当天的msec中还会看到'msecs%86400_000' – brian

0

其他答案似乎工作太辛苦。

我使用调用atStartOfDay的方法,因为我会将它用于任何时区。某些地区每天的第一天是而非总是00:00:00.0。而且这种方法也适用于UTC。

ZonedDateTime midnightUtc = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC); 
long millisecondsSinceEpoch = midnightUtc.toInstant().toEpochMilli(); 

转储到控制台。

System.out.println("midnightUtc: " + midnightUtc); 
System.out.println("millisecondsSinceEpoch: " + millisecondsSinceEpoch); 

运行时。

midnightUtc:2015-09-26T00:00Z

millisecondsSinceEpoch:1443225600000

+0

如果需要给定日期而不是'现在',这不会大致转化为最初提出的代码吗?此外,我想避免在代码中重复使用'UTC'(在此使用两次) – u07103

+0

Y我的代码非常接近你的。英雄所见略同。我会说我的更好,因为它分成两行给了我们一个'ZonedDateTime',我们可以在调试,日志记录和断言测试中使用。至于UTC常数的多次使用,这不是重复的。 java.time框架要求我们通过“Local”类来调用start-of-day方法。所以我们需要在离开和重新加入时间轴时应用一个时区。 Joda-Time图书馆在其分区日期时间类(DateTime)上提供了一个'withTimeAtStartOfDay'方法,但是java.time没有(我不知道为什么)。 –

0

这里是一个非常可读的解决办法,我使用:

long fullMsecs = System.currentTimeMillis(); 
long days = TimeUnit.MILLISECONDS.toDays(msecs); 
long truncatedMsecs = TimeUnit.DAYS.toMillis(days); 

或缩写:

long msecs = TimeUnit.DAYS.toMillis(
       TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()));