1

I found this code:

long timeStampSeconds = ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now());

but when I converted this back to fetch month and year using the following code, it gives the wrong output.

try {
    epochLong = Long.parseLong(epoch);
} catch (RuntimeException e) {
    //Log exception
    return null;
}

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(epochLong);
String month = String.valueOf(cal.get(Calendar.MONTH));
String year = String.valueOf(cal.get(Calendar.YEAR));
//print month and year

Any pointers as to how I can generate this in microseconds and get the month and year back right? Please help.

YCF_L
  • 51,266
  • 13
  • 85
  • 129
  • 3
    what is "the wrong output"? – f1sh Nov 18 '19 at 10:13
  • I always see epoch getting generated with 3 zeroes at the end, can this be avoided? – Samayra Goyal Nov 18 '19 at 10:16
  • 1
    Give and example of: -your input, -what you get, -what you expect to get – jhamon Nov 18 '19 at 10:17
  • Wrong output is: From epoch like 1574072161043000 expected month is 10 and year 2019 but i get month as 4 and year as 51850 which is absurd – Samayra Goyal Nov 18 '19 at 10:17
  • 1
    `setTimeInMillis` and `ChronoUnit.MICROS.between`, maybe millis and micros mismatch... maybe the is another [ChronoUnit](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#MILLIS) that would get a better fit – jhamon Nov 18 '19 at 10:19
  • I want to generate in micros only. This is the usecase, but how to I get back month and year? Calendar has setTimeInMillis only – Samayra Goyal Nov 18 '19 at 10:20
  • 1
    convert micros to milli? hint: it's a division – jhamon Nov 18 '19 at 10:20
  • 2
    the difference between `ChronoUnit.MICROS` and `setTimeInMillis` should ring a bell. – f1sh Nov 18 '19 at 10:22
  • But the micros also is not generating the precision.. The last 3 digits are zero, first of all how do I get the last 3 precision bits also.. and then how do I set? (If I divide I loose them again) – Samayra Goyal Nov 18 '19 at 10:22
  • What about `ChronoUnit.MILLIS.between(Instant.EPOCH, Instant.now())`? **MILLIS**... I just used that and it gave me the correct month and year... By the way, I was using `java.time` only. – deHaar Nov 18 '19 at 10:26
  • Thanks but My requirement is that I need to first convert to micros only – Samayra Goyal Nov 18 '19 at 10:29
  • 1
    Please don't use `Calendar` it is legacy now – YCF_L Nov 18 '19 at 10:43
  • Possible duplicate of [Java 8 LocalDateTime.now() only giving precision of milliseconds](https://stackoverflow.com/questions/39586311/java-8-localdatetime-now-only-giving-precision-of-milliseconds) – Ole V.V. Nov 19 '19 at 20:56

2 Answers2

2

If you are using java.time from Java-8 you can use :

long timeStampSeconds = ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now());

to back you can convert this to an instant, then the instant to the ZoneDateTime

Instant inst = Instant.EPOCH.plus(timeStampSeconds, TimeUnit.MICROSECONDS.toChronoUnit());
ZonedDateTime zdt = inst.atZone(ZoneId.of("Europe/Paris"));

Then you can get the month, year, day, hour, ...

Month month = zdt.getMonth();
int year = zdt.getYear();

Outputs

MICROS:       1574073141066090
ZoneDateTime: 2019-11-18T11:32:21.066090+01:00[Europe/Paris]
YCF_L
  • 51,266
  • 13
  • 85
  • 129
  • But here again timeStampSeconds will not give the precision digits. – Samayra Goyal Nov 18 '19 at 10:32
  • How did u get this: 1574073141066090? ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now()) always generates last 3 digits 0. – Samayra Goyal Nov 18 '19 at 10:35
  • I need to know what exactly u printed for MICROS? – Samayra Goyal Nov 18 '19 at 10:36
  • @SamayraGoyal I print `System.out.println(timeStampSeconds);` – YCF_L Nov 18 '19 at 10:37
  • @YCF_L thanks but I always get last 3 digits as 000 when I print , donno how u got 090. – Samayra Goyal Nov 18 '19 at 10:38
  • @SamayraGoyal for me I don't get always Zeros in the end, for example now `1574073452060455` – YCF_L Nov 18 '19 at 10:38
  • @SamayraGoyal check this [ideon demo](https://www.ideone.com/vJzDyY) – YCF_L Nov 18 '19 at 10:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202560/discussion-between-samayra-goyal-and-ycf-l). – Samayra Goyal Nov 18 '19 at 10:50
  • 1
    @SamayraGoyal I guess it is a problem with jdk version, I passed with this problem there are few months, and if I can remember the problem come from toString which erase the last part and set it as 000, I'm not sure, but I will search for it and let you in touch – YCF_L Nov 18 '19 at 10:57
  • 3
    https://bugs.openjdk.java.net/browse/JDK-8068730 • [Java 8 LocalDateTime.now() only giving precision of milliseconds](https://stackoverflow.com/q/39586311/2711488)… – Holger Nov 18 '19 at 11:56
  • Thank you @Holger for sharing this links, so as I guessed there are problem with jdk version of the OP – YCF_L Nov 18 '19 at 12:33
2

It depends on the platform and the Java version.

On my Mac example timeStampSeconds values from your code include

  • using jdk-1.8.0_121: 1574193249064000 and 1574193338130000; so always ending in 000
  • using jdk-9.0.4: 1574193430428678 and 1574193438362321; so usually not ending in 000.

On Java 8 the now methods of the java.time classes haven’t got any finer granularity than millisenods, so the microsecond of millisecond will always be 000. On Java 9 a finer granularity is available if the platform supports it, which may not be the case for all platforms.

So if you’re getting 000 always, the solution is to upgrade at least to Java 9 and run your Java program on a computer that supports microsecond precision.

Don’t use Calendar

The Calendar class is poorly designed and long outdated. Also it never supports any unit finer than milliseconds. To convert your microsecond value back to a date and time object, use for example:

    long timeStampSeconds = 1_574_193_438_362_321L;
    Instant convertedBack = Instant.EPOCH.plus(timeStampSeconds, ChronoUnit.MICROS);
    System.out.println(convertedBack);

2019-11-19T19:57:18.362321Z

You will notice that the full microsecond precision is preserved. YCF_L in another answer has already shown how to get the year and month values.

Ole V.V.
  • 76,217
  • 14
  • 120
  • 142