I have a string with the format: String dateString = "2014-03-17T20:05:49.2300963Z"
Trying this:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.SSSX");
Date date = df.parse(dateString);
Results in an Unparsable date exceptioon.
The docs: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html indicate that X is used with ISO 8601 when a single letter is used for the TimeZone.
EDIT
Re-reading the docs, I've switched up the SimpleDateFormat a little:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
dateString = dateString.replace("Z", "");
I take out the Z because I know the timezone, use H instead of k and add a couple more S for giggles.
Now the time is parsing, but incorrectly. Date is accurate, Time seems to be random.
EDIT 2
The problem is that java only allows millisecond accuracy, so 2300963 is being interpreted as 2300 seconds and 963 milliseconds. I'll need to format my string a little differently to get this to work.
EDIT 3
Turns out you can't have a fractional part of a second in Java. It has to be truncated to milliseconds. I ended up using a type made available to me by my database, but the general solution is to truncate the fractional part of the second to millisecond. I'll post example code of how to do that as an answer.
You need to provide as many S as you have in your date String. In this case, 7
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.SSSSSSSX");
This is required because, otherwise, the DateFormat doesn't know where the milliseconds end and where the time zone starts.
Note also, that
2300963
as a millisecond value means 2300 seconds and 963 milliseconds. Why do you have it that way? Why aren't those seconds part of the value in their corresponding position? When the DateFormat parses it, they will be added.
This works: SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.SSSSSSS'Z'");
It's safer to specify exactly how much precision you expect (say, for milliseconds in this case). It's odd to have 7 digits but if all your dates look like this, put 7 S.
The X will parse a timezone of the sort -0800. So your string would have to look like 2014-03-17T20:05:49.2300963-0800 (or something similar). Treat the Z as a literal, like T.
EDIT: Relevant to your partial seconds issue.
How to truncate the fractional seconds to milliseconds (because Java can't handle fractional seconds):
public String truncate(String dateString){
int numberOfDigits = dateString.substring(dateString.indexOf("."), dateString.length() - 1).length();
String justMilliSecondsDate = null;
if (numberOfDigits == 3) {
justMicrosDate = dateString;
}
else if (numberOfDigits > 3) {
justMilliSecondsDate = dateString.substring(0, dateString.length() - numberOfDigits + 3);
}
else {
justMilliSecondsDate = dateString;
for (int i = numberOfDigits ; i < 3 ; i++) justMilliSecondsDate += "0";
}
return justMilliSecondsDate;
}
tl;dr
Instant.parse( "2014-03-17T20:05:49.2300963Z" )
java.time
You are using the troublesome old date-time classes, now legacy, supplanted by the java.time classes.
Resolution
MillisecondsThe old date-time classes were limited to milliseconds resolution, for up to three digits of decimal fraction.
MicrosecondsYour input has six digits of fractional second for microseconds.
NanosecondsThe java.time classes have a resolution of nanoseconds for up to nine digits of fractional seconds. More than enough for your microseconds.
ISO 8601
The ISO 8601 standard defines string formats to represent date-time values. You input complies with ISO 8601.
The java.time classes use ISO 8601 formats by default when parsing and generating strings. So no need to specify a formatting pattern.
Instant instant =
Instant.parse( "2014-03-17T20:05:49.2300963Z" );
Related
I'm experiencing a problem where a displayed date has the millisecond component multiplied by 10.
Specifically, the time 52.050 is being shown as 52.50 when a .S format is used, but 52.050 when a .SSS format is used.
Take the following code example:
// Some arbitrary point with 50 milliseconds
final Date date = new Date(1620946852050 l);
final LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
final String format = "%-40s%-20s%-20s%n";
System.out.format(format, "Date Formatter", "Date Format", "Formatted Output");
Stream.of("HH:mm:ss", "HH:mm:ss.S", "HH:mm:ss.SS", "HH:mm:ss.SSS").forEach(dateFormat - > {
System.out.println();
System.out.format(format, SimpleDateFormat.class.getName(), dateFormat,
new SimpleDateFormat(dateFormat).format(date));
System.out.format(format, DateTimeFormatter.class.getName(), dateFormat,
DateTimeFormatter.ofPattern(dateFormat).format(localDateTime));
});
This produces an output of:
Date Formatter Date Format Formatted Output
java.text.SimpleDateFormat HH:mm:ss 00:00:52
java.time.format.DateTimeFormatter HH:mm:ss 00:00:52
java.text.SimpleDateFormat HH:mm:ss.S 00:00:52.50
java.time.format.DateTimeFormatter HH:mm:ss.S 00:00:52.0
java.text.SimpleDateFormat HH:mm:ss.SS 00:00:52.50
java.time.format.DateTimeFormatter HH:mm:ss.SS 00:00:52.05
java.text.SimpleDateFormat HH:mm:ss.SSS 00:00:52.050
java.time.format.DateTimeFormatter HH:mm:ss.SSS 00:00:52.050
I've used both java.util.Date and java.time to illustrate the unexpected behaviour, and I'm aware that java.time is better, but I'd still like to understand the SimpleDateFormat behaviour.
I'm running Java 14.0.2.12, but can reproduce in 11.0.10.9.
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Let's understand how the result produced by SimpleDateFormat is confusing (and hence error-prone).
1620946852050 milliseconds = 1620946852000 milliseconds + 50 milliseconds
With 1620946852000, System.out.println(localDateTime) will produce the result, 2021-05-14T00:00:52.
50 milliseconds = (50 / 1000) seconds = 0.05 seconds. This is how DateTimeFormatter also presents it. The documentation describes S clearly as: fraction-of-second. In other words, it presents it as a mathematical floating point number of 0.05 up to 9 places of decimal (nanosecond).
You can understand it this way: Pad zeros to the right side of the String.valueOf(0.05) to turn the precision up to 9 places of decimal. Thus, it becomes "0.050000000". Now, based on the number of S, get the substring of "0.050000000". Note that you can do so only up to 9 places i.e. SSSSSSSSSS will throw an exception.
S: .0
SS: .05
SSS: .050
SSSS: .0500 and so on up to
SSSSSSSSS: .050000000
This is the representation we learned in our childhood when we learnt fraction in Mathematics.
On the other hand, SimpleDateFormat does not present it as a fraction-of-second; rather, it presents the number after . as the number of milliseconds. The documentation describes S as: Millisecond. So, it presents it as a mathematical decimal integer number of 50. This makes it confusing because as soon as we see ., we think of fraction whereas SimpleDateFormat considers it just a separator for seconds and milliseconds.
The following example illustrates these different ways of presentation:
public class Main {
public static void main(String[] args) {
int sdf = 50;
String dtf = String.format("%.9f", 0.05);
System.out.format("sdf: %01d, dtf: %s%n", sdf, dtf.substring(0, 3));// Including two places for "0."
System.out.format("sdf: %02d, dtf: %s%n", sdf, dtf.substring(0, 4));// Including two places for "0."
System.out.format("sdf: %03d, dtf: %s%n", sdf, dtf.substring(0, 5));// Including two places for "0."
System.out.format("sdf: %04d, dtf: %s%n", sdf, dtf.substring(0, 6));// Including two places for "0."
}
}
Output:
sdf: 50, dtf: 0.0
sdf: 50, dtf: 0.05
sdf: 050, dtf: 0.050
sdf: 0050, dtf: 0.0500
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project. Learn more about the modern date-time API from Trail: Date Time.
Using java I try to format the current date with the timezone using SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
sdf.format(new Date());
This give me as results :
2021-04-28T13:45:52:308+0300
I want to get the timezone format with the "Z" instead of "+"
wanted results : "2021-04-28T13:45:52:308Z03:00"
I writed the date output in a file log that will be parsed by telegraf plugin writed in Go language that expect date with time zone with the following format : json_time_format = "2006-01-02T15:04:05Z07:00"
Is there a pattern allows that ?
You misunderstood. 2006-01-02T15:04:05Z07:00 does not mean that you should have a Z instead of a plus (what would you put instead of a minus, then?) This way of specifying a date and time format approximates how the fixed example date and time of Mon Jan 2 15:04:05 MST 2006 would be formatted, but it’s only an approximation. Specifically when it comes to the offset from UTC, the format requires Z when the offset is zero and +hh:mm or -hh:mm when it is non-zero. In accordance with ISO 8601 and RFC-3339. You see immediately that just giving the correct formatting of the example date and time, 2006-01-02T15:04:05-07:00, would not tell the reader that offset 0 should be given as Z. Therefore this particular requirement is specified as Z07:00 in the format. According to Format a time or date [complete guide] (link at the bottom), your particular format, 2006-01-02T15:04:05-0700, denotes ISO 8601 or RFC-3339.
So all you need to do is use DateTimeFormat.ISO_OFFSET_DATE_TIME or OffsetDateTime.toString().
A couple of examples follow.
String result = OffsetDateTime.now().toString();
System.out.println(result);
Output when running on Java 8 in my time zone just now:
2021-04-29T17:00:55.716+02:00
If the fraction of second is not allowed — well, according to ISO 8601 it is optional, so it should be, but if not:
String result = OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS)
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55+02:00
If you have got an old-fashioned Date object from legacy code, convert it before formatting:
Date oldfashionedDate = new Date();
String result = oldfashionedDate.toInstant()
.atZone(ZoneId.systemDefault())
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55.739+02:00
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Format a time or date [complete guide]
Z is for "Zulu time" or zero hour offset, i.e. UTC +0:00
It's not correct to use it if you're not in that timezone. How would you know whether you're before or after the meridian if you replace it with Z? Given Z03:00 do you parse it as +03:00 or -03:00?
Since Z means Zulu time offset you can't use it as part of the format string but you can of course add Z as a hardcoded character
ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'Z");
System.out.println(formatter.format(now));
2021-04-29T15:34:17.661Z+0200
Then if you don't want the '+' you can remove it afterwards but it is not clear on what to do whit a '-' so I left it out of the answer.
Semantically as mentioned above its quite wrong.But you can achieve this with some custom parsing logic.
I will assume 2 things:
The date will not contain timezones with negative differences
The date format will not change
In any other cases, this is not safe!!
But here you go:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
String originalDateString = sdf.format(new Date());
String[] parts = originalDateString.split("\\+");
StringBuilder sb = new StringBuilder(parts[1]);
sb.insert(2, ':');
parts[1] = sb.toString();
String result = String.join("Z",parts);
System.out.println(result);
This will create from this:
2021-04-29T14:12:21:376+0000
This:
2021-04-29T14:12:21:376Z00:00
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SZ");//2018-02-05T18:00:51.001+0000
String text = dateFormat.format(date);
Date test = dateFormat.parse(text);
The first three lines work fine. When I try to parse the string into a date again I get an error. How can I solve this?
The error looks like this:
Caused by: java.text.ParseException: Unparseable date: "2018-02-07T15:32:13.214+0100"
at java.text.DateFormat.parse(DateFormat.java:366) ~[na:1.8.0_151]
at TimeRange.parseDateFromIsoString(TimeRange.java:33) ~[classes/:na]
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");//2018-02-05T18:00:51.001+0000
String text = dateFormat.format(date);
try {
Date test = dateFormat.parse(text);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
worked for me. With "SSSZ" instead of "SZ" at the end of the pattern.
I should like to contribute the modern answer. Because I discourage the use of SimpleDateFormat, more about that later.
java.time
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("Europe/Rome"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
String text = dateTime.format(formatter);
OffsetDateTime test = OffsetDateTime.parse(text, formatter);
This produces a string like 2018-02-07T17:51:21.087+0100, pretty close to what I think you were after in the question, and parses it back nicely. With SSS in the format pattern string it always produces 3 decimals on the seconds and also requires exactly 3 decimals by parsing. You may use S or SSSSSS to get 1 or 6 decimals, for example. On my Java 9, OffsetDateTime.now() has a precision of 6 decimals (microseconds), so if I specify fewer, I lose precision in the formatting.
EDIT: For backward compatibility you cannot use the following, but for anyone reading along I should like to present a variant without an explicit formatter:
String text = dateTime.toString();
OffsetDateTime test = OffsetDateTime.parse(text);
The two differences in the produced string are:
It produces as many groups of 3 decimals as are necessary to render the precision. Usually 3 decimals on my Java 8 and 6 decimals on my Java 9, but occassionally it hits a round number of milliseconds and produces fewer decimals. It parses a string with everything from 0 through 9 decimals, so this doesn’t present a problem in parsing. And I always preserve the full presicion of the original OffsetDateTime object.
The offset from UTC is rendered with a colon, for example +01:00.
What went wrong in your code?
The SimpleDateFormat class is long outdated and notoriously troublesome, so even if you hadn’t had a problem with it at present, I would still recommend you drop it and use java.time, the modern Java date and time API, instead, as I do above.
One difference between the old SimpleDateFormat and the modern DateTimeFormatter is that while S in the modern formatter means fraction of second, in SimpleDateFormat it means milliseconds, so any other number than three is meaningless. However, it accepts other numbers. When formatting, your formatter produced enough digits for the milliseconds, for example 89 if there were 21.089 seconds or 214 when you had 13.214 as in the question.The former is incorrect, the 21.089 seconds were rendered as 21.89. I strongly believe that three-digit milliseconds caused your parsing to fail when you had only one S. On my Java 8 and 9 it works and also parses 21.89 as 21 seconds 89 milliseconds so the error evens out.
This behaviour agrees with the Java 9 documentation, which states: “For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.”
Link
Oracle tutorial: Date Time explaining how to use java.time.
SimpleDateFormat documentation for Java 9
I Removed Z in the simple date format which relates to time zone Which gives Correct out Put Below is the snippet.
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");//2018-02-05T18:00:51.001+0000
String text = dateFormat.format(date);
try {
Date test = dateFormat.parse(text);
} catch (ParseException e) {
e.printStackTrace();
}
I have the following date
2017-08-23-11.19.02.234850
it has the following date format
yyyy-MM-dd-HH.mm.ss.SSSSSS
What I want to do is to convert the date to format yyyy-MM-dd'T'HH:mm:ss.SSSSSS
I have the following code
public static void main(String[] args) {
String strDate = "2017-08-23-11.19.02.234850";
String dateFmt = "yyyy-MM-dd-HH.mm.ss.SSSSSS";
System.out.println("converted Date: " + convertDate(strDate, dateFmt));
}
public static String convertDate(String strDate, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
sdf.setLenient(true);
try {
Date dateIn = sdf.parse(strDate);
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS").format(dateIn);
}catch(ParseException e) {
e.printStackTrace();
}
return "";
}
the result is
converted Date: 2017-08-23T11:22:56.000850
input date 2017-08-23-11.19.02.234850
converted date 2017-08-23T11:22:56.000850
doesn't look the same, it seems java is rounding the milliseconds besides if I turn lenient off for date validation
sdf.setLenient(false);
I get the following
java.text.ParseException: Unparseable date: "2017-08-23-11.19.02.234850"
at java.text.DateFormat.parse(Unknown Source)
at mx.santander.canonical.datamodel.enums.Main.convertDate(Main.java:74)
at mx.santander.canonical.datamodel.enums.Main.main(Main.java:66)
converted Date:
How to build a function which validates and converts date strings like this in a proper way?
EDIT:
I added a new function to obtain results
/**
* Gets the ISO 8601 date str from string.
*
* #param strDate the str date
* #return the ISO 8601 date str from string
*/
private String getISO8601DateStrFromString (String strDate) {
String responseISO8601Date = "";
if(strDate == null || "".equals(strDate.trim())) {
return responseISO8601Date;
}
try {
String strDtWithoutNanoSec = strDate.substring(0, strDate.lastIndexOf("."));
String strDtNanoSec = strDate.substring(strDate.lastIndexOf(".") + 1, strDate.length());
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");
formatter.setLenient(false);
Date date = formatter.parse(strDtWithoutNanoSec);
Timestamp t = new Timestamp(date.getTime());
t.setNanos(Integer.parseInt(strDtNanoSec));
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'");
NumberFormat nf = new DecimalFormat("000000");
responseISO8601Date = df.format(t.getTime()) + nf.format(t.getNanos());
} catch (ParseException | StringIndexOutOfBoundsException | NumberFormatException e) {
String errorMsg = String.format("The date provided for conversion to ISO 8601 format [%s] is not correct", strDate);
System.out.println(errorMsg);
}
return responseISO8601Date;
}
What I get:
Uptadet date 2017-12-20T11:19:02.234850
As others have already mentioned, your requirement does not fit the use of Date and SimpleDateFormat since these only support milliseconds, that is, three decimals on the seconds, where you have six decimals (microseconds). So we need to find some other way. This is basically a good idea anyway, since Date and SimpleDateFormat are long outdated, and today we have better tools for the job.
I have got two suggestions for you.
java.time
Even in Java 7 I think that it’s a good idea to use the modern Java date and time API that came out with Java 8, AKA JSR-310. Can you do that? Certainly; use the backport for Java 6 and 7, ThreeTen Backport. The modern API supports anything from 0 through 9 decimals on the seconds, and the code is straightforward when you know how:
private static DateTimeFormatter inputParser
= DateTimeFormatter.ofPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS");
private static DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
public static String convertDate(String strDate) {
return LocalDateTime.parse(strDate, inputParser)
.format(outputFormatter);
}
I am using your own two format pattern strings. convertDate("2017-08-23-11.19.02.234850") returns 2017-08-23T11:19:02.234850.
There is a simplification possible: Since the format you want to obtain, conforms with ISO 8601, you don’t need an explicit formatter for it. The modern classes understand and produce ISO 8601 formats natively, so you may use:
return LocalDateTime.parse(strDate, inputParser).toString();
However, if the decimals on the seconds happened to end in 000, this will not print the last three zeroes. So if six decimals are required even in this case, use the formatter.
Regular expression
If you don’t want to rely on an external library, even temporarily until once you upgrade to Java 8 (or 9), your job can be done with a regular expression:
return strDate
.replaceFirst("^(\\d{4}-\\d{2}-\\d{2})-(\\d{2})\\.(\\d{2})\\.(\\d{2}\\.\\d{6})$",
"$1T$2:$3:$4");
It’s less elegant and harder to read, and it doesn’t offer the level of input validation you get from using a proper date and time API. Other than that, it’s a way through.
java.sql.Timestamp?
As others have said, java.sql.Timestamp offers nanosecond precision and thus will hold your date-time. Parsing your string into a Timestamp isn’t straightforward, though, so I don’t think it’s worth the trouble. Usagi Miyanmoto correctly identifies Timestamp.valueOf() as the method to use, but before you could do that, you would have change the format, so you would end up changing the format twice instead of just once. Or maybe three times since Timestamp also doesn’t produce your desired ISO 8601 format readily. Additionally you would need to decide a time zone for the timestamp, but I assume you could do that without any trouble.
If you needed to keep the the date-time around, a Timestamp object might be worth considering, but again, it’s a long outdated class. In any case, for reformatting alone, I certainly would not use it.
What happened in your code?
SimpleDateFormat understood 234850 as milliseconds, that is, 234 seconds 850 milliseconds. So it added 234 seconds to your time, 11:19:02. And then printed the remaining 850 milliseconds in 6 decimal places as you had requested.
Date has precision only till milli seconds. Please use timestamp instead - it has precision till nano seconds, which is expected in your case.
Please refer this answer - precision till nano seconds
TimeStamp API
A thin wrapper around java.util.Date that allows the JDBC API to
identify this as an SQL TIMESTAMP value. It adds the ability to hold
the SQL TIMESTAMP fractional seconds value, by allowing the
specification of fractional seconds to a precision of nanoseconds. A
Timestamp also provides formatting and parsing operations to support
the JDBC escape syntax for timestamp values.
SimpleDateFormat of Java does not support microsecond in pattern.
java.util.Date format SSSSSS: if not microseconds what are the last 3 digits?
You have several choices:
Manually handle the parsing and formatting of the microseconds
Switch to use Java 8 as Time API supports fraction of second in pattern (https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)
If you need to use Java 7, consider using JODA Time for your date-time logics. JODA support fraction of second in its DateTimeFormat (http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html)
That result you got is expected. In your format string S were used. S is for milliseconds, hat is thousandths of seconds, and in this case the number of S's does not matter for parsing.
Your input string ends with 11.19.02.234850, the last part is interpreted as an integer value, and added to the date and time as milliseconds. That is as 234.850 seconds. Now, if you add 234 secs to 11:19:02, it becomes 11:22:56, just as you got in the result...
You cannot make a SimpleDateFormat mask that can parse microseconds into a Date, and Date cannot hold microseconds value either.
You have to choose, whether you want to use Date, or really need the finer then milliseconds resolution?
If you stick with Date, you should truncate the string of the last 3 characters.
Or you could use java.sql.Timestamp, which has a valueOf() method, hat uses SQL timestamp format.
Unfortunately it is not exactly he same as yours (being yyyy-[m]m-[d]d hh:mm:ss[.f...])...
Another way could be to split the string by separators (like [-.]), parse them to integers, and use hese integers with the Timestamp() constructor...
I have to create date string from Java date in the form as given below
2016-02-02T10:40:54.264880
Does SimpleDateFormat class allows formatting date in the above format ?
If it does then what is the format string for this ?
I tried using this "yyyy-MM-dd'T'HH:mm:ss.SSSZ" but cannot generate the required string.
Thanks.
Use yyyy-MM-dd'T'HH:mm:ss.SSS and that will give you precision up to milli seconds. Java 8 time package can provide you nano seconds precision, which is not available in util Date
Finally I did this to maintain the format along with losing precision for microseconds.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
String commentDate = sdf.format(new Date())+"000";
java.time
If Android moves to Java 8 technology (may be in the works), you can use the java.time framework.
Nanoseconds
These classes support finer granularity, nanoseconds rather than the milliseconds of java.util.Date & Joda-Time. That is more than enough for the microseconds in your input string.
ISO 8601
These classes default to the ISO 8601 format used by your input string.
Instant
In java.time, an Instant is a moment on the timeline in UTC. Its default toString implementation prints any fractional second number as 0, 3, 6, or 9 digits as needed by the particular value. In the case of your string that means six digits.
UTC
I will assume your string was intended for UTC rather than some particular time zone.
Example Code
Instant instant = Instant.parse ( "2016-02-02T10:40:54.264880" + "Z" );
2016-02-02T10:40:54.264880Z
Joda-Time
Until Java 8 technology becomes available, use Joda-Time rather than the notoriously troublesome java.util.Date/.Calendar classes.
Like java.time, Joda-Time use ISO 8601 formats by default.
Unlike java.time, Joda-Time has milliseconds resolution. That means a maximum of 3 digits of fractional second. You will need to truncate your six digits to three, thereby losing a bit of data.
String output = Instant.now().toString();
Similar to java.time code above:
Instant instant = Instant.parse ( "2016-02-02T10:40:54.264880" + "Z" );
The fractional second is truncated after three digits, limited to milliseconds. So you will experience loss of data as microseconds are cut to milliseconds. In this example we lose the 880.
System.out.println ( "instant: " + instant );
instant: 2016-02-02T10:40:54.264Z