how to convert timestamp(in microseconds) string to date in Java/Scala. My goal is to compare two timestamps and find the differences between them. I'm using java 8 and example Timestamp string is 1474457086337977. I would like to convert this into Date or Timestamp instance.
-
Why don't you just get current date and time? – Kaushal28 Sep 24 '16 at 11:35
-
1@NoOne because the current date and time is not going to help you get the difference between two timestamps, like the question clearly explains :/ – Gimby Sep 24 '16 at 11:36
-
Actually I will get tis timestamp from external resource as part of my data and i will need to compare this timestamp and do some logic. – Balaji Reddy Sep 24 '16 at 11:37
-
I really dont understand , why this question is down voted. if you feel the answer is quit simple , pls provide the answer else quote the reason for down voting. – Balaji Reddy Sep 24 '16 at 11:41
-
as far as I remember every date lib has a way to create Dates from milliseconds (as long), so you just need to parse the string to long, and then create the Date (I recommend joda DateTime - it has nice methods to compare dates) – pedrorijo91 Sep 24 '16 at 11:44
-
@pedrorijo91 my timestamp string is in microseconds not in milliseconds – Balaji Reddy Sep 24 '16 at 11:44
-
ok, but 1 microsecond = 0.001 milliseconds...can't you convert it? – pedrorijo91 Sep 24 '16 at 12:42
-
@BDR Down-votes may be due this topic having been asked and answered many many many times before on Stack Overflow but you did not bother to search before posting. – Basil Bourque Sep 24 '16 at 21:47
-
And a duplicate of this and many more: http://stackoverflow.com/q/24168492/642706 – Basil Bourque Sep 24 '16 at 21:49
-
Regarding the microseconds issue, another duplicate: [A Dare object capable of storing microseconds](http://stackoverflow.com/q/7242104/642706) – Basil Bourque Sep 25 '16 at 06:06
-
I re-opened this Question. Upon further research I could not find any Question that directly asked about instantiating date-time values with a count-from-epoch of microseconds. The linked questions discuss various related issues, but do not directly address instantiating from a number of microseconds. And I added an answer to do so with java.time. – Basil Bourque Sep 26 '16 at 05:06
3 Answers
tl;dr
Instant.EPOCH.plus(
Duration.ofNanos(
TimeUnit.MICROSECONDS.toNanos(
Long.parse( "1474457086337977" ) ) ) )
java.time
The java.time classes support a resolution of nanoseconds, more than enough for your microseconds.
Parsing a string of a number
Parse the string as a long
to get a count of microseconds from the epoch.
long micros = Long.parse( "1474457086337977" );
And of course you can always use an integer literal. Note the L
appended to integer literal.
long micros = 1_474_457_086_337_977L ;
Converting a long into Instant
We want to transform that count of microseconds from the epoch of beginning of 1970 in UTC (1970-01-01T00:00:00Z
) into an Instant
. The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds. That means up to nine digits of a decimal fraction.
The Instant
class has handy static methods for converting from a count of whole seconds, from a count of whole seconds plus a fractional second in nanoseconds, or from a count of milliseconds. But unfortunately no such methods for a count of microseconds or nanoseconds.
As a workaround, we can define a Duration
and add it to the epoch reference date already defined as a constant. We can instantiate a Duration
as a number of nanoseconds. To get nanoseconds, we multiply your microseconds by a thousand. Note the use of 64-bit long
rather than 32-bit int
.
Duration duration = Duration.ofNanos( micros * 1_000L );
Instant instant = Instant.EPOCH.plus( duration );
instant.toString(): 2016-09-21T11:24:46.337977Z
Alternatively, you can use the TimeUnit
enum to convert microseconds to nanoseconds without hard-coding a “magic number”.
Duration duration = Duration.ofNanos( TimeUnit.MICROSECONDS.toNanos( micros ) );
To adjust into other offsets or time zones, search StackOverflow for Java classes OffsetDateTime
or ZonedDateTime
.
Converting to legacy date-time types
You should avoid the old date-time types bundled with the earliest versions of Java. They have proven to be poorly-designed, confusing, and troublesome. Now supplanted by the java.time types.
But if you must interact with old code not yet updated to the java.time types, you may convert to/from java.time. Look to new methods added to the old classes.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
Beware of data loss when converting from a java.time type to java.util.Date
or java.util.Calendar
. These types resolve to only milliseconds. A truncation from nanoseconds to milliseconds is performed silently, lopping off those last six (of nine) possible digits of a fractional second.
java.util.Date utilDate = java.util.Date.from( instant ); // Caution: Data loss in truncating nanoseconds to milliseconds.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old 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.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

- 1
- 1

- 303,325
- 100
- 852
- 1,154
-
Interestingly, in your answer the `TimeUnit.MICROSECONDS.toNanos` is subject to the same problems that `TimeUnit.MICROSECONDS.toMillis` is. Just in the opposite direction. The `toMillis` conversion may suffer underflow, and in your answer the `toNanos` conversion may suffer overflow. For example if you had `microsecs = Long.MAX_VALUE`. – Edwin Dalorzo Sep 26 '16 at 12:35
-
@EdwinDalorzo Why would anyone have a date-time value as a count-from-epoch of `Long.MAX_VALUE` microseconds? – Basil Bourque Sep 26 '16 at 15:01
-
You left a comment in my answer about possible data loss in my use of `TimeUnit.convert`. I thought it was only fair to highlight that this solution does not solve the problem either. I used `Long.MAX_VALUE` as an example, but you don't need to reach that number to get an overflow. In which scenarios would that make sense? Does it matter? I could ask the same question about the loss of precision in my answer when you highlighted it. But to mention just an example, celestial calculations could easily exceed that number. – Edwin Dalorzo Sep 26 '16 at 15:41
-
@EdwinDalorzo [Your Answer](http://stackoverflow.com/a/39676134/642706) involved truncating nanoseconds to milliseconds. I pointed out the practical issue that that *always* means data-loss (except in the happenstance of zeros). I also pointed out a solution to resolve that problem and improve you example code. Your points about `Long.MAX_VALUE` and celestial calculations are out of bounds of the intentions of the java.time classes, and are delving into the absurd. – Basil Bourque Sep 26 '16 at 16:12
Well, what about converting those microseconds to milliseconds and then just create a timestamp object?
long microsecs = 1474457086337977L;
long millis = TimeUnit.MILLISECONDS.convert(microsecs, TimeUnit.MICROSECONDS);
Timestamp time = new Timestamp(millis);
Wouldn't that work?
--Edit
To address the comments left in the answer:
About Java 8's new Date Time API
First, since you mention that you're using Java 8 I totally agree that a better approach would be to use the new Java 8 Date/Time API. However, this is a luxury you don't always have even when working with Java 8 because you may still be interacting with an old API still using the old Java Date/Time classes, or simply because the rest of your API still uses them and you don't want to start mixing things.
It is not clear in your question if you already know this, you seem to be sure that you want to use either java.util.Date
or java.sql.Timestamp
and I didn't question that, I just worked around the parameters of your question.
Clearly the new Java date/time APIs are much better than the old ones, but there are millions of lines of code out there still using the old APIs and they work. Yet again I thought that was out of the scope of the answer and it seems you already have other good answers here to address that.
About Possible Data Loss
One comment mentions that the answer might run into data loss. I think in Java all integer arithmetic is subject to potential underflow or overflow. My mistake is probably not have mentioned it.
It is true that TimeUnit.convert
method might end up causing overflows or underflows in certain scenarios. It is documented in the method.
- A nanosecond is one billionth of a second (1/1000000000)
- A microsecond is one millionth of a second (1/1000000).
- A millisecond is one thousandth of a second (1/1000)
Which means that, once expressed as a long, a millisecond number should be a much smaller number than a microsecond one, right?
The formula used by TimeUnit.convert
is as follows
final long MICROS = 1000000L;
final long MILLIS = 1000L;
long microsecs = 1474457086337977L;
long millisecs = microsecs / (MICROS / MILLIS)
Which means you would run into data loss only if your microseconds are really small numbers e.g. if you had less than 1,000 microseconds. You should validate your code never goes into a scenario like this.
One comment left in this answer argues that the right answer should probably use nanoseconds, but then again a nanosecond long value would be a much bigger number than your microseconds and so, during conversions to nanoseconds you might still run into overflows.
For example, think what would happen if you had Long.MAX_VALUE
microseconds, how could you convert that to nanoseconds using just Java long arithmetic without an overflow given that nanoseconds are supposed to be a much bigger number than your Long.MAX_VALUE
microseconds?
My point being that regardless of you using Java 8 Date Time or legacy Java Date Time APIs you need a long
value representing an instant in the time line, but that long
has limitations in regards to how far in the past or how far in the future you can go, and when you do conversions between units, that arithmetic is subject to underflow and overflow and there's no way around it and you should be aware of that to avoid very nasty bugs.
Once more, I thought that was a given and outside the scope of the question and I bring it up only because I got some downvotes for this omission.

- 76,803
- 25
- 144
- 205
-
Know that [`java.sql.Timestamp`](https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html) is a bad hack of a class, extending `java.util.Date` but pretending not to. Recommended for use where necessary to transit data in/out of database, but not recommended for business logic. This class is part of the troublesome old date-time classes now supplanted by the java.time classes. The java.time classes can handle [nanoseconds](https://en.wikipedia.org/wiki/Nanosecond) (even finer than microseconds). – Basil Bourque Sep 25 '16 at 22:39
-
1This Answer's code **results in data loss**, truncating microseconds to milliseconds. While using java.time is a better route, if you insist on this approach, then you may want to do the additional math to set this `Timestamp` object's nano field by calling [`setNanos`](http://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html#setNanos(int)). – Basil Bourque Sep 26 '16 at 05:53
-
@BasilBourque I doubt that there is way to do integer/long arithmetic in Java without running in overflow or underflow at some point. My mistake was probably not mentioning it. As far as I can tell nanoseconds conversions would be subject to the same precision problems. – Edwin Dalorzo Sep 26 '16 at 12:30
You can try following code, which will take time stamp as a string:
BigInteger b = new BigInteger("1474457086337977");
b=b.divide(new BigInteger("1000"));
String x =b.toString();
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
long milliSeconds= Long.parseLong(x);
System.out.println(milliSeconds);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
System.out.println(formatter.format(calendar.getTime()));
Or for more accuracy, you can use BigDecimal:
BigDecimal b = new BigDecimal("1474457086337977");
b=b.divide(new BigDecimal("1000"));
String x =b.toString();

- 5,377
- 5
- 41
- 72
-
-
-
-
@No One, my timestamp string is not in milliseconds but microseconds. – Balaji Reddy Sep 24 '16 at 11:46