63

Just tested this code on both my Windows (8) workstation and an AIX:

    public static void main(String[] args) {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()));
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()));
    }

and got something similar to this as a result:

2013-10-07 12:53:26.000905
2013-10-07 12:53:26.000906

Can someone please explain me what are the last digits, if not microseconds?

Note: I interact with a DB2 database in which chronological data is stored using timed columns as TIMESTAMP with 6 digits AFTER the seconds i.e. microseconds (IMO). But all those "timestamps" are created by requesting the following query:

SELECT current timestamp as currenttimestamp FROM Table ( values (1)) temp

I wonder if, given the above results, I couldn't just use in my code new Date() instead of selecting the current timestamp from the database.

Thanks.

PS: I searched but found no relevant (answered) questions, like: Current time in microseconds in java or Get time with hour, minute, second, millisecond, microsecond

Community
  • 1
  • 1
maxxyme
  • 2,164
  • 5
  • 31
  • 48
  • 2
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 02 '18 at 00:32
  • 4
    To expand on the comment by @BasilBourque: While the old-fashioned `SimpleDateFormat` confusingly treats uppercase `S` as *milliseconds* no matter how many and how few, the modern counterpart `DateTimeFormatter` treats `S` as *fraction of second*. So with `DateTimeFormatter.ofPattern` you can meaningfully specify from 1 through 9 `S` and get the result you had expected. – Ole V.V. May 26 '19 at 16:53
  • new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").parse("2019-01-01 00:00:00.001000") returns 00:00:01.000 ! – Hafthor Aug 01 '19 at 15:26

5 Answers5

124

From the documentation of SimpleDateFormat:

Letter     Date or Time Component     Presentation     Examples  
S          Millisecond                Number           978 

So it is milliseconds, or 1/1000th of a second. You just format it with on 6 digits, so you add 3 extra leading zeroes...

You can check it this way:

    Date d =new Date();
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(d));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS").format(d));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(d));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS").format(d));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS").format(d));
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(d));

Output:

2013-10-07 12:13:27.132
2013-10-07 12:13:27.132
2013-10-07 12:13:27.132
2013-10-07 12:13:27.0132
2013-10-07 12:13:27.00132
2013-10-07 12:13:27.000132

(Ideone fiddle)

ppeterka
  • 20,583
  • 6
  • 63
  • 78
  • 1
    OK, thank you, didn't check this so simple solution... feeling awful about that! :( – maxxyme Oct 07 '13 at 13:25
  • 21
    @maxxyme no need to feel awful, we all make mistakes. Sometimes just by looking at a problem for too long makes one sort of blind to the issue itself... (I had that quite a few times.) Sometimes what one needs is just another set of eyes. – ppeterka Oct 07 '13 at 13:29
  • 1
    Warning: Don't ever use SimpleDateFormat .parse with fractional seconds unless you can guarantee its milliseconds and is <= 999. Actually, don't use SimpleDateFormat. – Hafthor Aug 20 '19 at 16:13
  • How would we get microseconds? – CMCDragonkai Dec 16 '20 at 01:47
  • public static void main(String[] args) throws ParseException { System.out.println(new SimpleDateFormat("yyy-MM-dd hh:mm:ss.SSSSSS").parse("2020-10-02 17:17:27.149320")); System.out.println(new SimpleDateFormat("yyy-MM-dd hh:mm:ss.SSSSSS").parse("2020-10-02 17:14:58.986670")); } will give Fri Oct 02 17:19:56 AEST 2020 Fri Oct 02 17:31:24 AEST 2020 which is wrong ... – HoaPhan Jan 21 '21 at 04:48
16

tl;dr

Instant.now()
       .toString() 

2018-02-02T00:28:02.487114Z

Instant.parse(
    "2018-02-02T00:28:02.487114Z"
)

java.time

The accepted Answer by ppeterka is correct. Your abuse of the formatting pattern results in an erroneous display of data, while the internal value is always limited milliseconds.

The troublesome SimpleDateFormat and Date classes you are using are now legacy, supplanted by the java.time classes. The java.time classes handle nanoseconds resolution, much finer than the milliseconds limit of the legacy classes.

The equivalent to java.util.Date is java.time.Instant. You can even convert between them using new methods added to the old classes.

Instant instant = myJavaUtilDate.toInstant() ;

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).

Capture the current moment in UTC. Java 8 captures the current moment in milliseconds, while a new Clock implementation in Java 9 captures the moment in finer granularity, typically microseconds though it depends on the capabilities of your computer hardware clock & OS & JVM implementation.

Instant instant = Instant.now() ;

Generate a String in standard ISO 8601 format.

String output = instant.toString() ;

2018-02-02T00:28:02.487114Z

To generate strings in other formats, search Stack Overflow for DateTimeFormatter, already covered many times.

To adjust into a time zone other than UTC, use ZonedDateTime.

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;

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.

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
  • @maxxyme Questions don't age-out here. Indeed, this site hands out ["badges"](https://stackoverflow.com/help/badges) for new Answers given to old Questions as a noteworthy contribution. Stack Overflow is intended to be more like Wikipedia, less like the endlessly repetitious treadmill of a discussion board or forum. – Basil Bourque Feb 04 '18 at 05:35
  • NOTE: The Android implementation of SimpleDateFormat behaves differently than the Oracle version. The "S" format in Android is actually decimal seconds, whereas Oracle is Number of Milliseconds. So a time in millis ending in, say 048 will display as "0" with a format of "S" on Android, and "48" on regular Oracle implementations. I believe the Android docs are technically wrong. – Dave Hubbard Dec 30 '19 at 16:27
3

I used yet another trick to format date with 6-digit precision (microseconds):

System.out.println(
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.").format(microseconds/1000)
    +String.format("%06d", microseconds%1000000));

This technique can be extended further, to nanoseconds and up.

tutejszy
  • 602
  • 7
  • 22
0

Use java.sql.Timestamp.toString if you want to get fractional seconds in text representation. The difference betwen Timestamp from DB and Java Date is that DB precision is nanoseconds while Java Date precision is milliseconds.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
-4

SSSSSS is microseconds. Let us say the time is 10:30:22 (Seconds 22) and 10:30:22.1 would be 22 seconds and 1/10 of a second . Extending the same logic , 10:32.22.000132 would be 22 seconds and 132/1,000,000 of a second, which is nothing but microseconds.

  • 7
    But the `java.util.Date` object does not carry microseconds, only milliseconds. – Basil Bourque Feb 02 '18 at 00:33
  • While it is true in the real world, it is not true for `SimpleDateFormat`. That class is confusing indeed. It’s so good that it is also long outdated. – Ole V.V. Nov 11 '20 at 07:49