15

I have a value in column which is of type timestamp. Lets say I have a value 2007-05-04 08:48:40.969774

Now, when trying to fetch the value from the database and return this timestamp value to a function, what SimpleDateFormatter pattern should I use so that the fraction part beside the seconds also gets returned.

I have used yyyy-MM-dd hh:mm:ss, but that only returns till the seconds and ignores the fraction present beside the seconds(.969774). I need help in returning this fraction part also, with a 6-digits precision.

woliveirajr
  • 9,433
  • 1
  • 39
  • 49
Surya Chandra
  • 1,561
  • 5
  • 27
  • 42
  • 2
    Take a look at the documentation: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html. There's a list of format specifiers there. – Oliver Charlesworth Apr 09 '12 at 13:23
  • 1
    whoever downvoted care to explain why? There is nothing wrong with the question. Is it possible to get millionth second precision in java. – Surya Chandra Apr 09 '12 at 13:29
  • 2
    +1 I think its a reasonable question. I imagine the downvoter didn't realise that dealing with micro-seconds a) is not trivial or b) quite possible. – Peter Lawrey Apr 09 '12 at 14:05
  • I think Timestamp can deal with nanoseconds from a database, take a look at http://docs.oracle.com/javase/6/docs/api/java/sql/Timestamp.html – woliveirajr Apr 09 '12 at 16:10

4 Answers4

8

The default ways of formatting a java.util.Date (or java.sql.Timestamp) has only millisecond precision. You can use yyyy-MM-dd hh:mm:ss.SSS to get that millisecond precision.

A java.sql.Timestamp actually does have (up to) nanosecond precision (assuming the database server and the driver actually support it). The easiest way to format it in Java 8 is to convert the timestamp to a java.time.LocalDateTime (using Timestamp.toLocalDateTime()) and use the java.time formatting options in java.time.format.DateTimeFormatter which support up to nanoseconds.

If you use Java 7 or earlier it will take some extra effort, as the normal date formatters don't support it. For example you could use a dateformatter with pattern yyyy-MM-dd hh:mm:ss (to only format up to seconds) and append the sub-second nano seconds (with appropriate zero-padding) of Timestamp.getNanos() yourself.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Great answer. In the Java7 case you can save the zero-padding code by calling the `toString()` method of `java.sql.Timestamp` and take the already zero-padded nanos with `substring` as they always start at the same position. Or you can just use `toString()` if the format is okay for you. :) – Zsolt Sky Jul 15 '20 at 08:07
5

You have to have a way of obtaining a micro-second timestamp. I use System.currentTimeMillis() with System.nanoTime() in combination. Then you need a way to display it. You can divide it by 1000 and display milliseconds as normal, then display the last 3 digits of the time. i.e. Have a time which is like

long timeUS = System.currentTimeMillis() * 1000 + micros;

here is a more detailed example

HiresTimer.java and HiresTimerTest.java

The test prints

2012/04/09T14:22:13.656008
2012/04/09T14:22:13.656840
2012/04/09T14:22:13.656958
2012/04/09T14:22:13.657066
 ....
2012/04/09T14:22:13.665249
2012/04/09T14:22:13.665392
2012/04/09T14:22:13.665473
2012/04/09T14:22:13.665581

EDIT: The relevant code is

private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS");
private static final DecimalFormat DF = new DecimalFormat("000");

public static String toString(long timeUS) {
    return SDF.format(timeUS / 1000) + DF.format(timeUS % 1000);
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 7
    `System.nanoTime()` does not return a value that has any correlation to an absolute time. It is only useful for measuring elapsed time between two invocations of `System.nanoTime()`. http://stackoverflow.com/q/1712205/260633 – Dev Apr 09 '12 at 14:26
  • And it can measure the elapse time from currentTimeMillis which means you can have a fair idea what the micro-seconds are. – Peter Lawrey Apr 09 '12 at 14:31
  • `System.nanoTime()` cannot measure anything except elapsed time since the last call to `System.nanoTime()`. The epoch is undefined. So it is only useful in comparison to itself. – Dev Apr 09 '12 at 14:38
  • And so you can determine for example, how many micro-second it has been since you last called currentTimeMillis. Once you determine when the currentTimeMillis last changed, you have a known point in time from which to count micro-seconds, or even nano-seconds. – Peter Lawrey Apr 09 '12 at 15:06
  • I am guessing the downvoter didn't read the code, and hasn't tried to use currentTimeMillis() and nanoTime() together. – Peter Lawrey Apr 09 '12 at 15:06
  • @Dev How does what you have said make any sense given the output of the test quoted? – Peter Lawrey Apr 09 '12 at 15:15
  • For the record, it wasn't my downvote. That being said the question was asking about text formatting, not how to obtain a microsecond timestamp. – Dev Apr 09 '12 at 16:17
  • @Dev, I suspected you weren't the downvoter. You are right to point out the question is about formatting. This partially depends on what data type you are trying to format. I have included my example so you don't have to click on a link. – Peter Lawrey Apr 09 '12 at 17:28
2

Dealing with micro- or nano-seconds in Java is not always straightforward.


import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;


public class Main {

  public static void main(String args[]) throws Exception {
    long time = System.currentTimeMillis();
    Date d = new Date(time);
    Timestamp t = new Timestamp(time);
    /* micro-seconds as OP requested */
    {
      t.setNanos(123456000);
      System.out.println(d);
      System.out.println(t);
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss'.'");
      NumberFormat nf = new DecimalFormat("000000");
      System.out.println(df.format(t.getTime()) + nf.format(t.getNanos() / 1000));
      /* using Java Time API (available since JDK 1.8) */
      DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
      LocalDateTime ldt = t.toLocalDateTime();
      System.out.println(ldt.format(dtf));
    }
    /* nanoseconds just for the sake of completness */
    {
      t.setNanos(123456789);
      System.out.println(t);
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss'.'");
      NumberFormat nf = new DecimalFormat("000000000");
      System.out.println(df.format(t.getTime()) + nf.format(t.getNanos()));
      /* using Java Time API (available since JDK 1.8) */
      DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnnnnn");
      LocalDateTime ldt = t.toLocalDateTime();
      System.out.println(ldt.format(dtf));
    }
  }
}

The output produced is (in my country, my locale):

Tue Aug 31 13:26:08 CEST 2021
2021-08-31 13:26:08.123456
2021-08-31 13:26:08.123456
2021-08-31 13:26:08.123456
2021-08-31 13:26:08.123456789
2021-08-31 13:26:08.123456789
2021-08-31 13:26:08.123456789
Jiri Patera
  • 3,140
  • 1
  • 20
  • 14
2

In Java 8 and later, the java.time package has support for parsing and manipulating date/times to nanosecond precision. That means up to 9 digits in the fraction of a second.

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