1

How can I convert incoming long time value in microseconds into milliseconds and then format that to data time stamp as below:

yyyyMMdd-HH:mm:ss.SSS

I am using Java SimpleDateFormat to format the long value to the timestamp. But, converting the microseconds to milliseconds seems problem as I am loosing the value.

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS");

To convert microsecond to millisecond, I am using the TimeUnit:

long micro //microseconds
long milli = TimeUnit.MILLISECONDS.convert(micro, TimeUnit.MICROSECONDS);

What is the right way to convert the value without loosing any data?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Jparak
  • 19
  • 1
  • 3
  • What's you current input value and what's your expected output value? – MadProgrammer Nov 05 '18 at 03:56
  • What does you mean with "I am loosing the value"? Can you provide a runnable [mcve], with appropriate sampel values for the microseconds, that shows what you wanted to happen and what happened instead? – Erwin Bolwidt Nov 05 '18 at 03:59
  • 1
    [Convert microseconds string to date in Java or Scala](https://stackoverflow.com/questions/39675836/convert-microseconds-string-to-date-in-java-or-scala) might help – MadProgrammer Nov 05 '18 at 04:00
  • 1
    You should include sample data, indicating given inputs and expected outputs. – Basil Bourque Nov 05 '18 at 04:48
  • Learn basic Markdown formatting used in Stack Overflow, such as four spaces prefixing lines of code. I fixed it for you this time. – Basil Bourque Nov 05 '18 at 04:53
  • If `yyyyMMdd-HH:mm:ss.SSS` means three decimals on the seconds, you are going to lose the microsecond precision anyway. So what do you mean that you want? And is there any point in converting to milliseconds first if the end goal is a formatted string? – Ole V.V. Nov 05 '18 at 09:48
  • 1
    uh, you are getting microseconds and want milliseconds without loss of precision. You are aware that 1000 microseconds go into a single millisecond and you're treating the number of milliseconds as an integer value. You are ALWAYS going to lose precision. – jwenting Nov 05 '18 at 09:51
  • Well, in theory you could keep your milliseconds in a `double`, @jwenting, and probably keep the precision. But that would only complicate getting from there to a formatted date-time string, so no good solution for sure. – Ole V.V. Nov 05 '18 at 10:23
  • @OleV.V. sure, and he'd need to do just that to retain precision. The code he provides, no matter what he does with his longs, will NEVER retain precision. – jwenting Nov 05 '18 at 10:26

1 Answers1

8

I am using java SimpleDateFormat

Don’t.

Avoid the treacherous old date-time classes bundled with the earliest versions of Java. They were supplanted years ago with the java.time classes when JSR 310 was adopted.

convert incoming long time value in microseconds into milliseconds

Don’t.

The java.time classes use a resolution of nanoseconds, finer than your microseconds. So no need to throw away data.

Instant = ( whole seconds + fractional second as nanos )

Extract the number of whole seconds.

long seconds = TimeUnit.MICROSECONDS.toSeconds( micros ) ;

Get the fractional second, the amount of micros left over after subtracting for the whole seconds.

long microsRemaining = 
    micros 
    -
    TimeUnit.SECONDS.toMicros( seconds ) 
;

Convert the remaining micros to nanos, because the Instant class we use next represents a count of whole seconds plus a count of nanoseconds (for the fractional second).

long nanos = TimeUnit.MICROSECONDS.toNanos( microsRemaining ) ;

Combine the whole seconds with the fractional second in nanos. The Instant class represents a moment in UTC as a count since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z.

Instant instant = Instant.ofEpochSecond( seconds ).plusNanos( nanos ) ;

To generate a string in standard ISO 8601 format, simply call toString.

String output = instant.toString() ;

The Z on the end of the string means UTC (an offset-from-UTC of zero hours-minutes-seconds), and is pronounced Zulu.

You can produce strings in your own custom formats using the DateTimeFormatter class. Search Stack Overflow as this has been covered many many many times already.

Tip: Your desired format is so close to the ISO 8601 format, YYYY-MM-DDTHH:MM:SSZ, that I strongly suggest using the standard format rather than make up your own cousin of that.

If you wish to see this same moment through the lens of the wall-clock time used by people of a certain region (a time zone), apply a ZoneId to get a ZonedDateTime.

ZoneId z = ZoneId.of( "Africa/Tunisia" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

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.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

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