Single pattern for java 8 date time [duplicate] - java

This question already has answers here:
JSR-310 - parsing seconds fraction with variable length
(4 answers)
Java 8 Date equivalent to Joda's DateTimeFormatterBuilder with multiple parser formats?
(5 answers)
Closed 4 years ago.
public static long convertDateTimeToEpochMillis(String eventDate,String eventTime) {
String patternMills = "yyyy-MM-dd HH:mm:ss.SSS";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse(eventDate + " " +
eventTime, dtf);
}
This is giving a parsing exception when I am passing 2018-07-19 23:11:52.3 but parses successfully for 2018-07-19 23:11:52.312. I don't want to specify 3 different patterns for different times like yyyy-MM-dd HH:mm:ss.S,yyyy-MM-dd HH:mm:ss.SS and yyyy-MM-dd HH:mm:ss.SSS.
Can I provide a single pattern which will take up to 1/10th of a sec, 100th of a sec and millisec?

ISO 8601
Actually your pattern is not far from accepted by LocalDateTime.parse default pattern, using standard ISO 8601 format.
So, maybe put not a space but letter T instead will be enough for you?
Then you do not need DateTimeFormatter at all.
LocalDateTime localDateTime = LocalDateTime.parse(eventDate + "T" +
eventTime);
It accepts any number of digits in milliseconds part, from 0 up to 9.

You can just choose a pattern with three SSS as default
String patternMills = "yyyy-MM-dd HH:mm:ss.SSS";
and fulfill right side of your date with zeros when necessary
String eventDate = "2018-07-19 23:11:52.3";
String millis = eventDate.substring(eventDate.lastIndexOf('.')+1);
if(millis.length() < 3)
eventDate += Stream.generate(() -> "0").limit(3 - millis.length()).collect(Collectors.joining(""));
or use nice apache method:
StringUtils.rightPad(eventDate, 23, '0'); // 23 is string length for "yyyy-MM-dd HH:mm:ss.SSS" pattern
Anyway you can also add some validation to check the rest part of the date string

Related

Cannot parse threeten datetime to a specific format [duplicate]

This question already has answers here:
Can’t rid of 'T' in LocalDateTime
(3 answers)
How to prevent auto-generated 'T' letter when parsing String to LocalDateTime using DateTimeFormatterBuilder [duplicate]
(1 answer)
Closed 2 years ago.
I'm trying to format Threeten datetime, from yyyy-MM-dd'T'HH:mm:ss to yyyy-MM-dd HH:mm:ss. Below is the code, I'm using to achieve the task.
public void testChangeFormat() {
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date1 = LocalDateTime.parse("2020-03-10T15:14:05", inputFormatter);
System.out.println(date1); // prints 2020-03-10T15:14:05
String formattedDate = outputFormatter.format(date1);
System.out.println(formattedDate); // prints 2020-03-10 15:14:05
LocalDateTime newFormattedDateTime = LocalDateTime.parse(formattedDate);
System.out.println(newFormattedDateTime);
}
Everything seems to work as expected until I try to parse the formattedDate to LocalDateTime, at LocalDateTime newFormattedDateTime = LocalDateTime.parse(formattedDate);
I even get the datetime formatted as 2020-03-10 15:14:05 using outputFormatter, but when I try to parse that to LocalDateTime, it gives me the following exception:
org.threeten.bp.format.DateTimeParseException: Text '2020-03-10 15:14:05' could not be parsed at index 10
Can somebody help me with this?
LocalDateTime.parse(formattedDate) are using DateTimeFormatter.ISO_LOCAL_DATE_TIME (that is format yyyy-MM-dd'T'HH:mm:ss). That's why you get the exception when trying to parse string that has format yyyy-MM-dd HH:mm:ss. You should use:
LocalDateTime.parse(formattedDate, outputFormatter) if you wnat to do the parse to LocalDateTime again for some reason.
Note:
You have the printed format you at line: outputFormatter.format(date1) right?
You seem to be confused between LocalDateTime and format (which is a string representation).
A LocalDateTime always has T in it when you print its object using System.out.println (which implicitly calls toString as you most likely already know) e.g.
System.out.println(LocalDateTime.now());
will output 2020-04-14T09:36:04.723994.
See below how the toString of LocalDateTime has been implemented:
#Override
public String toString() {
return date.toString() + 'T' + time.toString();
}
and therefore your following statement will always show 'T' in it:
System.out.println(newFormattedDateTime);
It's up to you to format a LocalDateTime into the String representation of your choice. As I have mentioned in the first line, formats are strings i.e. you format a LocalDateTime into a String representation where you can apply all the options provided by DateTimeFormatter.
The correct way of converting the formattedDate to LocalDateTime is by applying the corresponding format which is specified in outputFormatter.
LocalDateTime newFormattedDateTime = LocalDateTime.parse(formattedDate,outputFormatter);
How date and time are stored in a LocalDateTime object shouldn't be a concern. We can always create the string in the required format from it.

Parse timestamp string in Java with variable number of nanoseconds

I have a CSV that contains timestamps in the following formats:
yyyy-MM-dd HH:mm:ssX
yyyy-MM-dd HH:mm:ss.SX
yyyy-MM-dd HH:mm:ss.SSX
yyyy-MM-dd HH:mm:ss.SSSX
yyyy-MM-dd HH:mm:ss.SSSSX
yyyy-MM-dd HH:mm:ss.SSSSSX
yyyy-MM-dd HH:mm:ss.SSSSSSX
How can I parse a string that could contain any one of the above formats?
The following code can parse the timestamp when 3-6 nanoseconds are present, but fails when the nano seconds aren't present or are less than 3:
String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());
I currently have a method that iterates from 0-6 and generates a string with a number of "S" equal to the value of the iterated variable. The method attempts to parse the string within a try/catch until the string is successfully parsed. For example, the string 2018-11-02 11:39:03.0438-04 will attempt to be parsed five times before being successful.
The CSV is an export of a PostgreSQL table that has columns with type TIMESTAMP WITH TIME ZONE and appears to cut off trailing "0" nanosecond places.
I'm using Java 8 and am open to any external libraries (Joda?).
You'd better use Java Time API1, from the package java.time.
Date, SimpleDateFormatter and Calendar classes are flawed and obsolete.
The DateTimeFormatter class provides numerous options, so you can configure all you need. Note that by using the method appendFraction, the nanos are right-padded.
String[] dateStrs = {
"2018-11-02 11:39:03.4-04",
"2018-11-02 11:45:22.71-04",
"2018-11-03 14:59:17.503-04"
};
DateTimeFormatter f = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss.")
.appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, false)
.appendPattern("X")
.toFormatter();
// Single item:
LocalDateTime date = LocalDateTime.parse("2018-11-02 11:39:03.7356562-04", f);
// Multiple items:
List<LocalDateTime> dates = Arrays.asList(dateStrs).stream()
.map(t -> LocalDateTime.parse(t, f))
.collect(Collectors.toList());
1 Java 8 new Date and Time API is heavily influenced by Joda Time. In fact the main author is Stephen Colebourne, the author of Joda Time.
The first 19 characters are identical.
Also, you have different lengths in the different cases. You can use a switch to test the length of the String and handle the separate cases for the different possible values.
I'm not sure but something like this seems to work for me:
String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());
In general, you want to you the longest format possible, with 6x S in this case.

Java: DateTimeFormatter and parsing sub-seconds [duplicate]

With the first release of Java 8 (b132) on Mac OS X (Mavericks), this code using the new java.time package works:
String input = "20111203123456";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Rendering:
2011-12-03T12:34:56
But when I add "SS" for fraction-of-second (and "55" as input), as specified in the DateTimeFormatter class doc, an exception is thrown:
java.time.format.DateTimeParseException: Text '2011120312345655' could not be parsed at index 0
The doc says Strict mode is used by default and requires the same number of format characters as input digits. So I'm confused why this code fails:
String input = "2011120312345655";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Another example using example from documentation ("978") (fails):
String input = "20111203123456978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
This example works, adding a decimal point (but I find no such requirement in the doc):
String input = "20111203123456.978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Renders:
localDateTime: 2011-12-03T12:34:56.978
Omitting the period character from either the input string or the format cause a fail.
Fails:
String input = "20111203123456.978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Fails:
String input = "20111203123456978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Bug – Fixed in Java 9
This issue was already reported in JDK-bug-log. Stephen Colebourne mentions as work-around following solution:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
Note: This workaround does not cover your use-case of only two pattern symbols SS. An adjustment might only be to use other fields like MICRO_OF_SECOND (6 times SSSSSS) or NANO_OF_SECOND (9 times SSSSSSSSS). For two fraction digits see my update below.
#PeterLawrey About the meaning of pattern symbol "S" see this documentation:
Fraction: Outputs the nano-of-second field as a fraction-of-second.
The nano-of-second value has nine digits, thus the count of pattern
letters is from 1 to 9. If it is less than 9, then the nano-of-second
value is truncated, with only the most significant digits being
output. When parsing in strict mode, the number of parsed digits must
match the count of pattern letters. When parsing in lenient mode, the
number of parsed digits must be at least the count of pattern letters,
up to 9 digits.
So we see that S stands for any fraction of second (including nanosecond), not just milliseconds. Furthermore, the fractional part does at the moment not take well in adjacent value parsing, unfortunately.
EDIT:
As background here some remarks about adjacent value parsing. As long as fields are separated by literals like a decimal point or time part separators (colon), the interpretation of fields in a text to be parsed is not difficult because the parser then knows easily when to stop i.e. when the field part is ended and when the next field starts. Therefore the JSR-310 parser can process the text sequence if you specify a decimal point.
But if you have a sequence of adjacent digits spanning over multiple fields then some implementation difficulties arise. In order to let the parser know when a field stops in text it is necessary to instruct the parser in advance that a given field is represented by a fixed-width of digit chars. This works with all appendValue(...)-methods which assume numerical representations.
Unfortunately JSR-310 has not managed well to do this also with the fractional part (appendFraction(...)). If you look for the keyword "adjacent" in the javadoc of class DateTimeFormatterBuilder then you find that this feature is ONLY realized by appendValue(...)-methods. Note that the spec for pattern letter S is slightly different but internally delegates to appendFraction()-method. I assume we will at least have to waint until Java 9 (as reported in JDK-bug-log, or later???) until fraction parts can manage adjacent value parsing as well.
Update from 2015-11-25:
The following code using two fraction digits only does not work and misinterpretes the millisecond part:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 2)
.toFormatter();
String input = "2011120312345655";
LocalDateTime ldt = LocalDateTime.parse(input, dtf);
System.out.println(ldt); // 2011-12-03T12:34:56.055
The workaround
String input = "2011120312345655";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
Date d = sdf.parse(input);
System.out.println(d.toInstant()); // 2011-12-03T12:34:56.055Z
does not work because SimpleDateFormat interpretes the fraction in a wrong way, too, similar to the modern example (see output, 55 ms instead of 550 ms).
What is left as solution is either waiting an undertermined long time until Java 9 (or later?) or writing your own hack or using 3rd-party libraries as solution.
Solution based on a dirty hack:
String input = "2011120312345655";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
int len = input.length();
LocalDateTime ldt = LocalDateTime.parse(input.substring(0, len - 2), dtf);
int millis = Integer.parseInt(input.substring(len - 2)) * 10;
ldt = ldt.plus(millis, ChronoUnit.MILLIS);
System.out.println(ldt); // 2011-12-03T12:34:56.550
Solution using Joda-Time:
String input = "2011120312345655";
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddHHmmssSS");
System.out.println(dtf.parseLocalDateTime(input)); // 2011-12-03T12:34:56.550
Solution using my library Time4J:
String input = "2011120312345655";
ChronoFormatter<PlainTimestamp> f =
ChronoFormatter.ofTimestampPattern("yyyyMMddHHmmssSS", PatternType.CLDR, Locale.ROOT);
System.out.println(f.parse(input)); // 2011-12-03T12:34:56.550
Update from 2016-04-29:
As people can see via the JDK-issue mentioned above, it is now marked as resolved - for Java 9.
DateTimeFormatterBuilder#appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
Something like this helped me
Here's an algorithm which adjusts the order of the trailing zeros that are conventionally returned from the formatted date String.
/**
* Takes a Date and provides the format whilst compensating for the mistaken representation of sub-second values.
* i.e. 2017-04-03-22:46:19.000991 -> 2017-04-03-22:46:19.991000
* #param pDate Defines the Date object to format.
* #param pPrecision Defines number of valid subsecond characters contained in the system's response.
* */
private static final String subFormat(final Date pDate, final SimpleDateFormat pSimpleDateFormat, final int pPrecision) throws ParseException {
// Format as usual.
final String lString = pSimpleDateFormat.format(pDate);
// Count the number of characters.
final String lPattern = pSimpleDateFormat.toLocalizedPattern();
// Find where the SubSeconds are.
final int lStart = lPattern.indexOf('S');
final int lEnd = lPattern.lastIndexOf('S');
// Ensure they're in the expected format.
for(int i = lStart; i <= lEnd; i++) { if(lPattern.charAt(i) != 'S') {
// Throw an Exception; the date has been provided in the wrong format.
throw new ParseException("Unable to process subseconds in the provided form. (" + lPattern + ").", i);
} }
// Calculate the number of Subseconds. (Account for zero indexing.)
final int lNumSubSeconds = (lEnd - lStart) + 1;
// Fetch the original quantity.
String lReplaceString = lString.substring(lStart + (lNumSubSeconds - pPrecision), lStart + lNumSubSeconds);
// Append trailing zeros.
for(int i = 0; i < lNumSubSeconds - pPrecision; i++) { lReplaceString += "0"; }
// Return the String.
return lString.substring(0, lStart) + lReplaceString;
}

Java formatting a date [duplicate]

This question already has answers here:
Java SimpleDateFormat Timezone offset with minute separated by colon
(2 answers)
Closed 5 years ago.
I have a problem formatting a date. I want the following output:
yyyy-MM-ddTHH:mm:ss+02:00
Where +02:00 depends on the timezone where you are, in my case Europe/Amsterdam
I have this function:
public String marshal(Date d) throws Exception
{
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String s = formatter.format(d);
return s;
}
But it gives me:
2017-05-10T14:56:46+0200
How can I have the timezone hour/minute with an extra colon in between?
It's right there in the documentation:
The number of pattern letters designates the format for both formatting and parsing as follows [...]
And from the examples:
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
Meaning that the colon-separated version of the timezone can be expressed using "XXX" in the pattern.
TL;DR: use
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

DateTimeFormatter fails on milliseconds [duplicate]

With the first release of Java 8 (b132) on Mac OS X (Mavericks), this code using the new java.time package works:
String input = "20111203123456";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Rendering:
2011-12-03T12:34:56
But when I add "SS" for fraction-of-second (and "55" as input), as specified in the DateTimeFormatter class doc, an exception is thrown:
java.time.format.DateTimeParseException: Text '2011120312345655' could not be parsed at index 0
The doc says Strict mode is used by default and requires the same number of format characters as input digits. So I'm confused why this code fails:
String input = "2011120312345655";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Another example using example from documentation ("978") (fails):
String input = "20111203123456978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
This example works, adding a decimal point (but I find no such requirement in the doc):
String input = "20111203123456.978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Renders:
localDateTime: 2011-12-03T12:34:56.978
Omitting the period character from either the input string or the format cause a fail.
Fails:
String input = "20111203123456.978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Fails:
String input = "20111203123456978";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );
Bug – Fixed in Java 9
This issue was already reported in JDK-bug-log. Stephen Colebourne mentions as work-around following solution:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
Note: This workaround does not cover your use-case of only two pattern symbols SS. An adjustment might only be to use other fields like MICRO_OF_SECOND (6 times SSSSSS) or NANO_OF_SECOND (9 times SSSSSSSSS). For two fraction digits see my update below.
#PeterLawrey About the meaning of pattern symbol "S" see this documentation:
Fraction: Outputs the nano-of-second field as a fraction-of-second.
The nano-of-second value has nine digits, thus the count of pattern
letters is from 1 to 9. If it is less than 9, then the nano-of-second
value is truncated, with only the most significant digits being
output. When parsing in strict mode, the number of parsed digits must
match the count of pattern letters. When parsing in lenient mode, the
number of parsed digits must be at least the count of pattern letters,
up to 9 digits.
So we see that S stands for any fraction of second (including nanosecond), not just milliseconds. Furthermore, the fractional part does at the moment not take well in adjacent value parsing, unfortunately.
EDIT:
As background here some remarks about adjacent value parsing. As long as fields are separated by literals like a decimal point or time part separators (colon), the interpretation of fields in a text to be parsed is not difficult because the parser then knows easily when to stop i.e. when the field part is ended and when the next field starts. Therefore the JSR-310 parser can process the text sequence if you specify a decimal point.
But if you have a sequence of adjacent digits spanning over multiple fields then some implementation difficulties arise. In order to let the parser know when a field stops in text it is necessary to instruct the parser in advance that a given field is represented by a fixed-width of digit chars. This works with all appendValue(...)-methods which assume numerical representations.
Unfortunately JSR-310 has not managed well to do this also with the fractional part (appendFraction(...)). If you look for the keyword "adjacent" in the javadoc of class DateTimeFormatterBuilder then you find that this feature is ONLY realized by appendValue(...)-methods. Note that the spec for pattern letter S is slightly different but internally delegates to appendFraction()-method. I assume we will at least have to waint until Java 9 (as reported in JDK-bug-log, or later???) until fraction parts can manage adjacent value parsing as well.
Update from 2015-11-25:
The following code using two fraction digits only does not work and misinterpretes the millisecond part:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 2)
.toFormatter();
String input = "2011120312345655";
LocalDateTime ldt = LocalDateTime.parse(input, dtf);
System.out.println(ldt); // 2011-12-03T12:34:56.055
The workaround
String input = "2011120312345655";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
Date d = sdf.parse(input);
System.out.println(d.toInstant()); // 2011-12-03T12:34:56.055Z
does not work because SimpleDateFormat interpretes the fraction in a wrong way, too, similar to the modern example (see output, 55 ms instead of 550 ms).
What is left as solution is either waiting an undertermined long time until Java 9 (or later?) or writing your own hack or using 3rd-party libraries as solution.
Solution based on a dirty hack:
String input = "2011120312345655";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
int len = input.length();
LocalDateTime ldt = LocalDateTime.parse(input.substring(0, len - 2), dtf);
int millis = Integer.parseInt(input.substring(len - 2)) * 10;
ldt = ldt.plus(millis, ChronoUnit.MILLIS);
System.out.println(ldt); // 2011-12-03T12:34:56.550
Solution using Joda-Time:
String input = "2011120312345655";
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddHHmmssSS");
System.out.println(dtf.parseLocalDateTime(input)); // 2011-12-03T12:34:56.550
Solution using my library Time4J:
String input = "2011120312345655";
ChronoFormatter<PlainTimestamp> f =
ChronoFormatter.ofTimestampPattern("yyyyMMddHHmmssSS", PatternType.CLDR, Locale.ROOT);
System.out.println(f.parse(input)); // 2011-12-03T12:34:56.550
Update from 2016-04-29:
As people can see via the JDK-issue mentioned above, it is now marked as resolved - for Java 9.
DateTimeFormatterBuilder#appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
Something like this helped me
Here's an algorithm which adjusts the order of the trailing zeros that are conventionally returned from the formatted date String.
/**
* Takes a Date and provides the format whilst compensating for the mistaken representation of sub-second values.
* i.e. 2017-04-03-22:46:19.000991 -> 2017-04-03-22:46:19.991000
* #param pDate Defines the Date object to format.
* #param pPrecision Defines number of valid subsecond characters contained in the system's response.
* */
private static final String subFormat(final Date pDate, final SimpleDateFormat pSimpleDateFormat, final int pPrecision) throws ParseException {
// Format as usual.
final String lString = pSimpleDateFormat.format(pDate);
// Count the number of characters.
final String lPattern = pSimpleDateFormat.toLocalizedPattern();
// Find where the SubSeconds are.
final int lStart = lPattern.indexOf('S');
final int lEnd = lPattern.lastIndexOf('S');
// Ensure they're in the expected format.
for(int i = lStart; i <= lEnd; i++) { if(lPattern.charAt(i) != 'S') {
// Throw an Exception; the date has been provided in the wrong format.
throw new ParseException("Unable to process subseconds in the provided form. (" + lPattern + ").", i);
} }
// Calculate the number of Subseconds. (Account for zero indexing.)
final int lNumSubSeconds = (lEnd - lStart) + 1;
// Fetch the original quantity.
String lReplaceString = lString.substring(lStart + (lNumSubSeconds - pPrecision), lStart + lNumSubSeconds);
// Append trailing zeros.
for(int i = 0; i < lNumSubSeconds - pPrecision; i++) { lReplaceString += "0"; }
// Return the String.
return lString.substring(0, lStart) + lReplaceString;
}

Categories

Resources