129

Note, I do NOT want millis from epoch. I want the number of milliseconds currently on the clock.

So for example, I have this bit of code.

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

Is there a way to get milliseconds with date? Is there another way to do this?

Note: System.currentTimeMillis() gives me millis from epoch which is not what I'm looking for.

PHPirate
  • 7,023
  • 7
  • 48
  • 84
LemonMan
  • 2,963
  • 8
  • 24
  • 34
  • 2
    You mean, "milliseconds in the second," so the value is always in the interval `[0, 999]`, correct? @thinksteep read the last sentence. – Matt Ball Aug 02 '12 at 20:27
  • @Lemonio Giving an example would make your Question more clear. – Basil Bourque Jun 29 '15 at 18:03
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html) are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Feb 18 '17 at 08:23
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html) are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Sep 18 '17 at 04:07
  • @Basil Bourque source? – Chris Neve Jan 18 '18 at 15:54
  • 1
    @ChrisNeve [JEP 150](http://openjdk.java.net/jeps/150) endorsed by [Brian Goetz](https://www.linkedin.com/in/briangoetz), [JSR 310](https://jcp.org/en/jsr/detail?id=310) [adopted unanimously](https://jcp.org/en/jsr/results?id=5639), a [technical article](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html) published by Oracle, and replacement of old date-time Oracle Tutorial with new [java.time Tutorial](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 18 '18 at 20:36

11 Answers11

202

Do you mean?

long millis = System.currentTimeMillis() % 1000;

BTW Windows doesn't allow timetravel to 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 8
    Note that if you travel back in time to before the Unix epoch, this will give a negative value whereas using `c.get(Calendar.MILLISECOND)` shouldn't. Always think of the corner cases! – Jon Skeet Aug 02 '12 at 20:37
  • and if somebody defines a timezone not on second border or adds a leap-millisecond this breaks.=)) – Markus Mikkolainen Aug 02 '12 at 20:40
  • Calendar is relative inefficient for something so simple. – Peter Lawrey Aug 02 '12 at 20:44
  • Java doesn't support leap-seconds. – Peter Lawrey Aug 02 '12 at 20:45
  • 38
    Java doesn't support time travel. – R. Martinho Fernandes Aug 02 '12 at 20:46
  • 1
    @MarkusMikkolainen: Nope, `System.currentTimeMillis()` isn't affected by time zones. – Jon Skeet Aug 02 '12 at 20:47
  • yes. exactly. that is why that %1000 will break if somebody makes a timezone that is not on the second border. If a timezone starts at .001 , then the %1000 calculation will be off by 1 millisecond. – Markus Mikkolainen Aug 02 '12 at 20:48
  • 1
    @PeterLawrey: Well, it might or it might not. It's up to the implementation. From the docs for Date: "A second is represented by an integer from 0 to 61; the values 60 and 61 occur only for leap seconds and even then only in Java implementations that actually track leap seconds correctly. Because of the manner in which leap seconds are currently introduced, it is extremely unlikely that two leap seconds will occur in the same minute, but this specification follows the date and time conventions for ISO C." – Jon Skeet Aug 02 '12 at 20:48
  • @MarkusMikkolainen: Oh, sorry, I see - you mean it will always give the *UTC* milliseconds rather than the local ones. Yes. – Jon Skeet Aug 02 '12 at 20:48
  • and java must support leap-seconds otherwise the date calculations will be off? – Markus Mikkolainen Aug 02 '12 at 20:49
  • ofcourse, an old java implementation will only see the leap seconds that were defined before it was released i guess.unless java is smart enough to use operating system timezone definitions or something.. – Markus Mikkolainen Aug 02 '12 at 20:50
  • So far, Java uses its own TimeZone so its behaviour is the same across platforms. These timezones can have a milli-second offset, but given no TimeZone ever has AFAIK, it seems unlikely it every will. – Peter Lawrey Aug 02 '12 at 21:02
26

Use Calendar

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

or

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

In practise though I think it will nearly always equal System.currentTimeMillis()%1000; unless someone has leap-milliseconds or some calendar is defined with an epoch not on a second-boundary.

Markus Mikkolainen
  • 3,397
  • 18
  • 21
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron
  • 7,915
  • 9
  • 39
  • 60
15

tl;dr

You ask for the fraction of a second of the current time as a number of milliseconds (not count from epoch).

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

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

  1. Get the fractional second in nanoseconds (billions).
  2. Divide by a thousand to truncate to milliseconds (thousands).

See this code run live at IdeOne.com.

Using java.time

The modern way is with the java.time classes.

Capture the current moment in UTC.

Instant.now()

Use the Instant.get method to interrogate for the value of a TemporalField. In our case, the TemporalField we want is ChronoField.MILLI_OF_SECOND.

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

Or do the math yourself.

More likely you are asking this for a specific time zone. The fraction of a second is likely to be the same as with Instant but there are so many anomalies with time zones, I hesitate to make that assumption.

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

Interrogate for the fractional second. The Question asked for milliseconds, but java.time classes use a finer resolution of nanoseconds. That means the number of nanoseconds will range from from 0 to 999,999,999.

long nanosFractionOfSecond = zdt.getNano();

If you truly want milliseconds, truncate the finer data by dividing by one million. For example, a half second is 500,000,000 nanoseconds and also is 500 milliseconds.

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
14

I tried a few ones above but they seem to reset @ 1000

This one definately works, and should also take year into consideration

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

and then do the same for end time if needed.

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

Fri Apr 04 14:27:05 PDT 2014

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
omarflorez
  • 355
  • 4
  • 4
3

Joda-Time

I think you can use Joda-Time to do this. Take a look at the DateTime class and its getMillisOfSecond method. Something like

int ms = new DateTime().getMillisOfSecond() ;
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
RNJ
  • 15,272
  • 18
  • 86
  • 131
  • Compile error: "`getMillis()` has protected access"; need to use `get()` instead. Also note that `new DateTime(new Date())` is equivalent to writing simply `new DateTime()`. – Jonik Apr 30 '15 at 21:11
  • The method `millisOfSecond` access an object and the further call to `get` extracts a primitive `int` from that object. You can collapse the two calls using the convenience getter method, `getMillisOfSecond`. Joda-Time follows this pattern for many of its properties. – Basil Bourque Jun 29 '15 at 18:17
  • 1
    FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Apr 25 '17 at 03:09
1

I did the test using java 8 It wont matter the order the builder always takes 0 milliseconds and the concat between 26 and 33 milliseconds under and iteration of a 1000 concatenation

Hope it helps try it with your ide

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

In Java 8 you can simply do

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

returns : the number of milliseconds since the epoch of 1970-01-01T00:00:00Z

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • 1
    [A] This is *not* what the Question asked for. Expressly says they do *not* want a count of milliseconds since the epoch reference date. [B] You could shorten that by dropping the ZonedDateTime: `Instant.now().toEpochMilli()` – Basil Bourque Feb 18 '17 at 08:04
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
    **Does not work in some time zones.** In some zones, on some dates, the day may not begin at 00:00:00. And the day may not be 24 hours long, may add or skip some hours or minutes. The `LocalDateTime` class cannot represent a moment, lacking any concept of time zone or offset-from-UTC, and therefore cannot track these time zone issues. – Basil Bourque Jan 20 '20 at 16:31
0

You can use java.util.Calendar class to get time in milliseconds. Example:

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));
Rajat
  • 1
  • 2