如何获得当前午夜以来的毫秒数?


124

请注意,我不想从时代开始。我想要当前时钟上的毫秒数。

例如,我有这段代码。

Date date2 = new Date(); 
Long time2 = (long) (((((date2.getHours() * 60) + date2.getMinutes())* 60 ) + date2.getSeconds()) * 1000);

有没有一种方法可以获取毫秒级的日期?还有其他方法吗?

注意: System.currentTimeMillis()从时代开始就给我毫秒,这不是我想要的。


2
您的意思是“毫秒为单位”,因此该值始终在interval内[0, 999],对吗?@thinksteep阅读了最后一句话。
马特·鲍尔

@Lemonio举个例子可以使您的问题更加清楚。
罗勒·布尔克

仅供参考,麻烦的旧日期时间类(例如java.util.Date现在已被遗留的类)已由java.time类取代。
罗勒·布尔克

仅供参考,麻烦的旧日期时间类(例如java.util.Date现在已被遗留的类)已由java.time类取代。请参见Oracle教程
罗勒·布尔克

1
@ChrisNeve JEP 150Brian Goetz认可,JSR 310 一致采用,是Oracle发布的技术文章,并用新的java.time Tutorial替换了旧的日期时间Oracle Tutorial
罗勒·布尔克

Answers:


197

你的意思是?

long millis = System.currentTimeMillis() % 1000;

BTW Windows不允许时间旅行到1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.

8
请注意,如果您时光倒流回到Unix时代之前,这将给出一个负值,而使用c.get(Calendar.MILLISECOND)则不然。永远想一想角落里的箱子!
乔恩·斯基特

并且如果有人定义了不在第二个边界上的时区或添加了一个毫秒级的
间隔,则会

35
Java不支持时间旅行。
R. Martinho Fernandes

1
@MarkusMikkolainen:不,System.currentTimeMillis()不受时区影响。
乔恩·斯基特

1
@PeterLawrey:好吧,可能有也可能没有。这取决于实现。从Date的文档中:“秒用0到61之间的整数表示;值60和61仅在leap秒出现,甚至在实际上正确跟踪leap秒的Java实现中也才出现。因为Because的方式目前已引入了秒数,因此极不可能在同一分钟内发生两个leap秒,但是此规范遵循ISO C的日期和时间约定。”
乔恩·斯基特

24

使用日历

Calendar.getInstance().get(Calendar.MILLISECOND);

要么

Calendar c=Calendar.getInstance();
c.setTime(new Date()); /* whatever*/
//c.setTimeZone(...); if necessary
c.get(Calendar.MILLISECOND);

尽管在实践中,我认为它将几乎始终等于System.currentTimeMillis()%1000; 除非某人的时间跨度为毫秒,或者某个日历的定义不是在第二边界上。


默认情况下,日历已经是当前时间,而MILLISECOND中没有。
kgautron 2012年


13

tl; dr

您要求以毫秒为单位来表示当前时间的秒数(计历元)。

Instant.now()                               // Get current moment in UTC, then…
       .get( ChronoField.MILLI_OF_SECOND )  // interrogate a `TemporalField`.

2017-04-25T03:01:14.113Z→ 113

  1. 获得分数秒,以纳秒为单位(十亿)。
  2. 除以一千以截断毫秒。

看到此代码在IdeOne.com上实时运行

使用java.time

现代的方法是使用java.time类。

在UTC中捕获当前时刻。

Instant.now()

使用该Instant.get方法查询a的值TemporalField。在我们的情况下,TemporalField我们想要的是ChronoField.MILLI_OF_SECOND

int millis = Instant.now().get( ChronoField.MILLI_OF_SECOND ) ;  // Get current moment in UTC, then interrogate a `TemporalField`.

或者自己做数学。

您更有可能要求特定的时区。几分之一秒的时间可能与s相同,Instant但是时区有很多异常,我犹豫做出这个假设。

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

询问小数秒。Question要求毫秒,但是java.time类使用的分辨率更高,只有纳秒。这意味着纳秒数的范围从0到999,999,999。

long nanosFractionOfSecond = zdt.getNano();

如果您确实需要毫秒,请通过除以一百万来截断更精细的数据。例如,半秒是500,000,000纳秒,也是500毫秒。

long millis = ( nanosFractionOfSecond / 1_000_000L ) ;  // Truncate nanoseconds to milliseconds, by a factor of one million.

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

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

要了解更多信息,请参见Oracle教程。。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


12

我在上面尝试了一些,但似乎在@ 1000时会重置

这绝对是可行的,并且还应该考虑年份

long millisStart = Calendar.getInstance().getTimeInMillis();

然后根据需要对结束时间执行相同的操作。


1
回答错误的问题。那是从时代开始的当前毫秒数,而不是当前时间的毫秒数。
肖恩·范·哥德

4
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

2014年4月4日星期五4:27:05 PDT


2

乔达时代

我认为您可以使用Joda-Time来做到这一点。看一看DateTime该类及其getMillisOfSecond方法。就像是

int ms = new DateTime().getMillisOfSecond() ;

编译错误:“ getMillis()已保护访问”;需要使用get()代替。另请注意,这new DateTime(new Date())等效于简单地编写new DateTime()
Jonik

该方法millisOfSecond访问一个对象,并进一步调用以从该对象中get提取基元int。您可以使用便捷的getter方法折叠两个调用getMillisOfSecond。Joda-Time的许多属性都遵循这种模式。
罗勒·布尔克

1
仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。
罗勒·布尔克

0

在Java 8中,您只需

ZonedDateTime.now().toInstant().toEpochMilli()

返回:自1970-01-01T00:00:00Z的纪元以来的毫秒数


1
[A]这不是问题所要的。明确表示他们希望自纪元参考日期起算的毫秒数。[B]您可以通过删除ZonedDateTime来缩短时间:Instant.now().toEpochMilli()
Basil Bourque

0

我使用Java 8进行了测试,构建器始终花费0毫秒的顺序以及26到33毫秒之间的连续时间以及1000次串联的迭代都没关系

希望它可以帮助您的想法

public void count() {

        String result = "";

        StringBuilder builder = new StringBuilder();

        long millis1 = System.currentTimeMillis(),
            millis2;

        for (int i = 0; i < 1000; i++) {
            builder.append("hello world this is the concat vs builder test enjoy");
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));

        millis1 = System.currentTimeMillis();

        for (int i = 0; i < 1000; i++) {
            result += "hello world this is the concat vs builder test enjoy";
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));
    }

0

Java 8:

LocalDateTime toDate = LocalDateTime.now();
LocalDateTime fromDate = LocalDateTime.of(toDate.getYear(), toDate.getMonth(), 
toDate.getDayOfMonth(), 0, 0, 0);
long millis = ChronoUnit.MILLIS.between(fromDate, toDate);

1
在某些时区不起作用。在某些区域中,在某些日期,一天可能不会从00:00:00开始。而且一天可能不会长达24小时,可能会增加或跳过一些小时或几分钟。该LocalDateTime班不能代表一个时刻,缺乏时区的任何概念或偏移从-UTC,因此无法追踪这些时区的问题。
罗勒·布尔克

0

您可以使用java.util.Calendar类获取时间(以毫秒为单位)。例:

Calendar cal = Calendar.getInstance();
int milliSec = cal.get(Calendar.MILLISECOND);
// print milliSec

java.util.Date date = cal.getTime();
System.out.println("Output: " +  new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date));
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.