Formatting Date in Thread safe Manner throws java.text.ParseException: - java

I am trying to convert the date from one format to Another
Input String - 2012-11-07-121603 (yyyy-MM-dd-HH-mm-ss)
Output String - 2012-11-07-12:16:03:000 (yyyy-MM-dd-HH:mm:ss:SSS)
ThreadSafeSimpleDateFormatUtil simpleDateFormat = new ThreadSafeSimpleDateFormatUtil(GenericConstants.DATE_FORMAT.YYYY_MM_DD_HH_MM_SS.toString());
final Date parsedDate = simpleDateFormat.parse(bulkCollectionTime);
simpleDateFormat = new ThreadSafeSimpleDateFormatUtil(GenericConstants.DATE_FORMAT.YYYY_MM_DD_HH_MM_SS_SSS.toString());
writeBean.setTimestamp(simpleDateFormat.format(parsedDate));
But it's throwing below error:
java.text.ParseException: Unparseable date: "2012-11-07-121603"
at java.text.DateFormat.parse(DateFormat.java:337)
at com.belgacom.rosy.rebecca.utils.ThreadSafeSimpleDateFormatUtil.parse(ThreadSafeSimpleDateFormatUtil.java:39)

Looks like the input format should be without the "-" between hours, minutes and seconds:
2012-11-07-121603 (yyyy-MM-dd-HHmmss)

Input String - 2012-11-07-121603 (yyyy-MM-dd-HH-mm-ss)
wrong pattern it would match with yyyy-MM-dd-HHmmss.

tl;dr
LocalDateTime.parse(
"2012-11-07-121603" ,
DateTimeFormatter.ofPattern( "uuu-MM-dd-HHmmss" )
).toString()
2012-11-07T12:16:03
java.time
The modern approach uses the java.time classes built into Java 8 and later. These classes are inherently thread-safe. These classes supplant the troublesome old legacy date-time classes that are un-thread-safe.
String input = "2012-11-07-121603" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuu-MM-dd-HHmmss" ) ;
Parse as a LocalDateTime because your input lacks info about time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString(): 2012-11-07T12:16:03
Thread-safety
The java.time classes are designed to be thread-safe. The classes use immutable objects. You may cache objects such as DateTimeFormatter for re-use throughout your code and across threads.
ISO 8601
When serializing date-time values to text, use standard ISO 8601 formats only. Do not invent your own formats such as that shown in your Question. The standard formats are practical and sensible. They are designed to be easy to parse by machine yet easy to read by humans across cultures.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. Example shown above.
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Related

Set random days on users with Date in Java?

I have for example 30 users and for everyone i want to set vacation with random start_day and random end_day of vacation. I want to use Date, not LocalDate. If i must do with LocalDate this is the answer.
LocalDate date = LocalDate.now();
List<VacationUser> collectVacationUser = allVacationUsers.stream()
.map(user -> {
if (inVacation()) {
return new VacationUser(date.minusDays(ThreadLocalRandom.current().nextInt(1, 5)),
date.plusDays(ThreadLocalRandom.current().nextInt(1, 5)));
} else {
return new VacationUser(user.getPrimaryEmail());
}
}).collect(toList());
return collectVacationUser;
}
I want to do this with Date, because in JSON date format with 'Date' is this "yyyy/mm/dd", in the other hand if I use LocalDate a format in JSON is something like this
"year":2018,"month":"AUGUST","era":"CE","dayOfMonth":16,"dayOfWeek":"THURSDAY","dayOfYear":228,"leapYear":false,"monthValue":8,"chronology":{"id":"ISO","calendarType":"iso8601"
tl;dr
Use types appropriate to your values: LocalDate
Never use the terrible legacy class java.util.Date
Learn to use converters/adapters in your Java⇔JSON serialization framework
Use standard ISO 8601 formats for date-time values whenever possible
Details
Use appropriate types to represent your data values. For a date-only value, without a time-of-day and without a time zone, the appropriate type is LocalDate.
Never use java.util.Date. That terrible class was supplanted years ago by the java.time classes.
As for generating textual representations in JSON, that is an entirely separate issue.
JSON has very few data types and none of them are date-time related. So whatever JSON output you are getting for your LocalDate input is a function of your particular Java-to-JSON library you are using. You do not divulge what library, so we cannot provide further assistance.
I can tell you that there is an established practical international standard for representing date-time values: ISO 8601. I strongly suggest always using these standard formats when serializing your date-time values to text.
For a date-only value, the standard format is YYYY-MM-DD such as 2018-01-23.
The java.time classes use these standard formats by default when parsing/generating strings.
LocalDate.parse( "2018-01-23" ) ;
And:
myLocalDate.toString()
2018-01-23
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?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

How do I print a millisecond count from epoch as a date-time in UTC using Java?

I am trying to use Java to format a time in milliseconds into a date in UTC. I have the following code:
long ms = 1427590800000;
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
cal.setTimeInMillis(ms);
Date date = cal.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss");
System.out.println(dateFormat.format(date)); // 2015-03-29 02:00:00
This is printing a time in BST (i.e. using the default time-zone) rather than UTC. It seems like the time-zone being set on the calendar has no bearing on the date being printed.
The actual time in UTC is shown by the following python snippet:
import datetime
ms = 1427590800000
print datetime.datetime.utcfromtimestamp(ms/1000.0) # 2015-03-29 01:00:00
Setting the default JVM time-zone to "UTC" results in the correct date being printed, but this doesn't seem like a safe solution.
java.time
The modern approach uses the industry-leading java.time classes.
Parse as an Instant, a moment in UTC with a resolution of nanoseconds.
long input = 1_427_590_800_000L ;
Instant instant = Instant.ofEpochMilli( input ) ;
ISO 8601
Generate a string in standard ISO 8601 format.
String output = instant.toString() ;
2015-03-29T01:00:00Z
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
You need to set the timezone to the formatter before formatting if you want a desired timezone.
Use dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); and then call dateFormat.format(date)

Parsing timestamp Soap fied to Java Date

I received from a SOAP message the follow date:
2012-11-16T02:02:05Z
How to parse to Date? What means this T and the Z in the date according with the SOAP specification?
I can parse correctly doing this way:
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(paymentDate);
Thanks #vikdor!
tl;dr
Instant.parse( "2012-11-16T02:02:05Z" )
ISO 8601
Your input string is in standard ISO 8601 format. That standard defines many useful, practical, unambiguous textual formats for representing date-time values.
The ISO 8601 formats are commonly adopted by modern protocols, such as XML schema, SOAP, etc., supplanting the clumsy outmoded formats such as RFC 1123 / RFC 822.
Your particular format from ISO 8601 uses:
T to separate the year-month-day portion from the hour-minute-second portion.
Z, short for Zulu, to indicate UTC time (an offset-from-UTC of +00:00).
Using java.time
Use the modern classes in the java.time package. They use ISO 8601 formats by default when parsing/generating strings.
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).
Instant instant = Instant.parse( "2012-11-16T02:02:05Z" ) ;
Capture the current moment in UTC.
Instant instant = Instant.now() ;
Generate a string in standard format by simply calling toString.
String output = instant.toString() ;
2017-07-26T01:23:45.704781401Z
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?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

SimpleDateFormat fails to reject input missing century on the year of the input, despite "yyyy" in the formatting pattern

I have a SimpleDateFormat with the pattern yyyy-M-d", and the following scenario:
String str = "02-03-04";
SimpleDateFormat f = new SimpleDateFormat("yyyy-M-d");
f.setLenient(false);
System.out.println(f.parse(str));
The output is Sat Mar 04 00:00:00 EST 2
My goal was to only catch dates in the format like 2004-02-03 and to ignore 02-03-04. I thought the yyyy in the pattern would require a 4 digit year, but clearly this is not the case. Can anyone explain why this is not throwing a parse exception? I would like it to...
Well, I can explain it from the docs:
For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
It's possible that Joda Time would be stricter - and it's a better API in general, IMO...
You could always throw an exception if the year is less than 1000 after parsing...
tl;dr
Using java.time, that input with that formatting pattern fails, just as you expected.
LocalDate
.parse(
"02-03-04" ,
DateTimeFormatter.ofPattern ( "uuuu-M-d" )
)
…throws java.time.format.DateTimeParseException
java.time
The classes you were using are now supplanted by the modern java.time classes defined in JSR 310 and built into Java 8 and later.
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
Define a custom formatting pattern as you asked. Use the DateTimeFormatter class.
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuu-M-d" );
Try to parse your input.
String input = "02-03-04";
LocalDate localDate = LocalDate.parse ( input , f );
We encounter a DateTimeParseException, failing on the missing century of the year of the input. Just as you expected.
Exception in thread "main" java.time.format.DateTimeParseException: Text '02-03-04' could not be parsed at index 0
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

how to convert timestamp string to java.util.Date

I need to convert a timestamp string to java.util.Date. E.g.:
MMDDYYHHMMSS to MM-DD-YY HH-MM-SS
Where MM is month, DD is date, YY is year, HH is hours, MM is minutes and SS is seconds.
You can do it like this:
DateFormat format = new SimpleDateFormat("MMddyyHHmmss");
Date date = format.parse("022310141505");
but I would strongly recommend that you use Joda Time instead. It's a better date/time library by a long, long way. In particular, the formatters/parsers in Joda Time are thread-safe, so you can reuse them freely and statically; java.text.SimpleDateFormat isn't thread-safe, so you either need to create one per thread or serialize access to it with a synchronized block.
tl;dr
java.time.LocalDateTime.parse(
"012318123456" ,
DateTimeFormatter.ofPattern( "MMdduuHHmmss" )
).format(
DateTimeFormatter.ofPattern( "MM-dd-uu HH-mm-ss" )
)
01-23-18 12-34-56
java.time
The modern approach uses the java.time classes.
Define a formatting pattern to match your input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMdduuHHmmss" ) ;
Your two-digit year will be interpreted as being 21st century ( 20xx ).
Parse as a LocalDateTime because your input string lacks any indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( "012318123456" , f ) ;
ldt.toString(): 2018-01-23T12:34:56
Generate a string in your desired format.
DateTimeFormatter fOut = DateTimeFormatter.ofPattern( "MM-dd-uu HH-mm-ss" ) ;
String output = ldt.format( fOut );
01-23-18 12-34-56
ISO 8601
Both of your formats are terrible, for multiple reasons.
When serializing date-time values, use the standard ISO 8601 formats whenever possible. They are designed to be practical, easy to parse by machine, easy to read by humans across cultures.
For a date-time time such as yours, the T in the middle separates the date portion from the time-of-day portion.
2018-01-23T12:34:56
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
use a SimpleDateFormat with an appropriate format string (be careful to use the correct format letters, uppercase and lowercase have different meanings!).

Categories

Resources