Orléando Dassi
Orléando Dassi

Reputation: 466

What does really the Java time in millis means?

Please need help to understand this small Java program showing two Java date with different values in long.

Date dateOne = new Date();
long dateOnetime = dateOne.getTime();

long dateTwoTime = dateOnetime / 1000;
dateTwoTime *=1000;

Date dateTwo = new Date(dateTwoTime);

When logging these variable with a simple System.out.println(String str); I got:

Why dateOneTime & dateTwoTime are so different but dateTwo is same as dateOne ??

Thanks in advance for clear details.

Upvotes: 2

Views: 980

Answers (4)

bwa
bwa

Reputation: 36

Actually there is a difference at the millisecond level in your dates. And that makes the difference.

dateOne and dateTwo are actually not equal. The fact is you are using the toString to assert the equality, which I believe is not the best way to go, because the toString() doesn't take in account the millisecond difference. I'd rather suggest you make use of the dateOne.equals(dateTwo) to make the comparison, as show in the sample I put for you here.

public class TestDate {

    public static void main (String ...args) {
            Date dateOne = new Date();
            long dateOneTime = dateOne.getTime();
            long dateTwoTime = dateOneTime/1000;

            System.out.println(dateOneTime);
            System.out.println(dateTwoTime);

            long dateThreeTime = dateTwoTime*1000;

            dateTwoTime *= 1000;

            System.out.println(dateThreeTime);
            System.out.println(dateTwoTime);
            Date dateTwo = new Date(dateTwoTime);
            if(dateOne.equals(dateTwo)) {
                    System.out.println("Dates are equal");
            } else {
                    System.out.println("Dates are not equal");
            }
    }

}

Upvotes: 2

Basil Bourque
Basil Bourque

Reputation: 339422

tl;dr

You truncated the fractional second.

Same as doing this…

Instant.now().truncatedTo( ChronoUnit.SECONDS ).toEpochMilli()

Details

You divided by one thousand, and then multiplied by one thousand on a count of milliseconds. You effectively truncated the fractional seconds from a date-time value defined as a count of milliseconds since the epoch reference of the first moment of 1970 in UTC (1970-01-01T00:00:00Z).

You are using a troublesome old date-time class, java.util.Date, now legacy, supplanted by the java.time classes.

The equivalent class in java.time is Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now();  // Current moment in UTC.

To truncate any fractional second, do so by calling methods rather than using your math approach. This makes your code more self-documenting. And date-time work is tricky, so avoid roll-your-own solutions.

Instant instantWholeSeconds = instant.truncatedTo( ChronoUnit.SECONDS );

I strongly advise against tracking date-time values as a count-from-epoch. It makes debugging difficult as humans cannot discern the date-time meaning from a very long integer. Furthermore, epochs vary with at least a couple dozen in use by various systems. And granularities of such counts vary, with various systems using whole seconds, milliseconds, microseconds, nanoseconds, and other amounts as well. So count-from-epoch numbers are commonly ambiguous and prone to misinterpretation.

But if you insist, you can extract a count-from-epoch from an Instant. Remember that going to milliseconds as your count involves data loss as any nanoseconds will be truncated.

// WARNING: Data-loss. Truncating any nanoseconds. 
// CAUTION: Tracking date-time as count-from-epoch is *not* advised.
long millis = instant.toEpochMilli(); 

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, & java.text.SimpleDateFormat.

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

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?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

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.

Upvotes: 1

hariharasudhans
hariharasudhans

Reputation: 15

Millis is milliseconds (1 second is 1000 millis)

Your two dates differ by less than 1 second or 1000 milliseconds

When you print them to hours:minutes:seconds format, they will be displayed as the same time.

Upvotes: 1

Richard Campbell
Richard Campbell

Reputation: 3621

Your two dates differ by less than 1 second or 1000 milliseconds (specifically, they differ by 325 milliseconds).

When you log them to only second precision (hours:minutes:seconds - 16:07:31), they will be displayed the same.

Upvotes: 4

Related Questions