Alternatives to FastDateFormat for efficient date parsing? - java

Well aware of performance and thread issues with SimpleDateFormat, I decided to go with FastDateFormat, until I realized that FastDateFormat is for formatting only, no parsing!
Is there an alternative to FastDateFormat, that is ready to use out of the box and much faster than SimpleDateFormat?
I believe FastDateFormat is one of the faster ones, so anything that is about as fast would do.
Just curious , any idea why FastDateFormat does not support parsing? Doesn't it seriously limit its use?

Note that since commons-lang 3.2, FastDateFormat supports parsing as well as printing.
See: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html

At a best guess, it's to keep FastDateFormat... well... fast, by limiting it to display only.
Apache Commons DateUtils has a parseDate function, but that uses SimpleDateFormat internally.
An alternative is to use the JodaTime library. It's a complete replacement for dealing with DateFormat, Date, and Calendar objects.
JodaTime has a DateTimeFormatter that can be used to create DateTime objects (JodaTime's equivalent of Java's Date objects) from strings.
An example of how to use it is like this:
String strInputDateTime = "2010-12-27"; // An example, this would really come from outside
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dt = fmt.parseDateTime(strInputDateTime);
I don't know if this is really any faster than SimpleDateFormat, though.

Found something interesting here of this case in Android:
http://andmob.wikidot.com/faq-simpletimeformat
SimpleDateFormat, the first time you
try parsing (or, presumably,
formatting) a date, will load in all
the timezone data for your locale.
This will take 2-3 seconds. It is
hoped that this will be fixed in some
future edition of Android.
In the interim, consider using
AsyncTask to "warm up"
SimpleDateFormat in your process
before you need it. Just parse some
date in the AsyncTask doInBackground()
to get it to load the timezones
sometime when it will not impact the
user so much. Once initialized in your
process, SimpleDateFormat will run
quickly until your process is
terminated.

As of Java 8, one can use DateTimeFormatter along with the the Java 8 Time API to both parse and format dates. From the documentation:
This class is immutable and thread-safe.
It's recommended to use this class if possible for new work going forward instead of using SimpleDateFormat.

The 'problem' with SimpleDateFormat is not performance, its thread safety.
If you have thousands of threads and synchronizing is not an issue use synchronized (you can also pool the instances to alleviate this a little)
If you have a reasonable amount of threads the recommended way is to have a separate instance for each SimpleDateFormat.
UPDATE
As of Java 8, just use DateTimeFormatter. It is immutable, thread safe, faster, and more flexible. (It also offers nice features like default patterns for ISO-8601 date/time strings.)

Do you really need to parse dates that quickly? Have you tested SimpleDateFormat and found it too slow for your needs?
Note, there are a variety of ways to cache slow-to-construct, non-thread-safe class instances (e.g. ThreadLocal, pools).

Related

Pattern.format(date) vs Date.fomat(Pattern)?

I came to know that DateTimeFormatter has two implementation for formatting the date.
Pattern.format(date)
Date.format(pattern)
public static void main(String[] args) {
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate date = LocalDate.now();
String dateFormatText = date.format(pattern);
String patternFormatText = pattern.format(date);
System.out.println(dateFormatText);
System.out.println(patternFormatText);
}
Both the SysOut prints the same value.
The Oracle docs examples uses Date.format method, whereas I can see many tech blogs using the Pattern.format method.
Can anyone explain me what is the difference and which is best to use?
Source Code Demo : Here
Though opinion-based I will try an answer.
As Stephen C has already documented, the two forms are equivalent.
Which is best? As so often in programming the answer is: It‘s best to write what will be least surprising to those reading your code.
So what will be least surprising? I am sure that the answer varies. Your organization will — consciously or unconsciously — build a tradition for what you are doing, and the least surprising will be to follow that tradition.
Points of each option
I’d also like to take a look at some thinkable reasons why both options have crept into java.time. This may give us some further thoughts on advantages of one or the other.
And since I don’t do mind reading, it’s guesswork. I think that the form date.format(formatter) was formed with inspiration from at least two sides:
It’s parallel to date.toString(), which with java.time we also often use for formatting a date-time object to a string. In Joda-Time, the predecessor of java.time, we even had the same method name: date.toString(formatter).
It’s somehow parallel to DateType.parse(string, formatter), which is what we use for the opposite operation, converting the string to a date-time object. For example LocalDate.parse("08/04/2021", pattern). This form in turn is necessary with the design of java.time. formatter.parse(string) wouldn’t know whether to parse into a LocalDate, an Instant, a ZonedDateTime or one of the many other date-time types of java.time. (The form pattern.parse("08/04/2021", LocalDate::from) exists as an alternative, though, and is sometimes necessary, but not often used.)
And I may be missing something, but one reason why many tech blogs use formatter.format(date) is inspiration from the now obsolete SimpleDateFormat that consistently used format.format(date). I cannot completely escape the thought that maybe those bloggers have not fully gone into the java.time way of thinking.
Can anyone explain me what is the difference?
There is no significant difference.
The javadoc for LocalDateTime.format says:
public String format(DateTimeFormatter formatter)
Formats this date-time using the specified formatter.
This date-time will be passed to the formatter to produce a string.
In other words, LocalDateTime.format calls DateTimeFormatter.format.
... and which is best to use?
Neither is "best".
It is up to you decide which form expresses your intention more clearly. Do you want to say:
"LocalDateTime: format yourself with this formatter", or
"DateTimeFormatter: format this temporal value".

Easy and fast way to format a timestamp

We have some timestamps represented as long in millis since epoch. Within strings for logging, exceptions, or toString() methods, these timestamps need to be formatted. A simple and clean format is enough.
So, what is the simplest and fastest method for formatting a timestamp in Java?
Requirements:
input timestamps represented as long in millis since epoch
output should be a string
fast
low CG overhead
a simple and clean output is sufficient, since it is only for internal purposes (debugging and logging), e.g. something minimal: 20141220 174522.23
if possible within JDK
the time zone is the system time zone
In particular, did somebody did a benchmark of JDK methods that can be used for this?
Actually I don't want to use SimpleDateFormat, since I believe its flexibility comes with too much overhead.
Easy to use and reasonable fast:
// All Java versions:
new java.sql.Timestamp(millis).toString(); // 2016-10-29 12:28:41.979
// Recommended when using Java 8+ (about +50% faster than Timestamp), standards compliant format
// checked with jmh 1.15
java.time.Instant.ofEpochMilli(millis).toString(); // 2016-10-29T10:28:41.979Z
The fastest implementation is very likely to be:
Long.toString(millis);
If performance is the most important thing, you should use that.
Actually I don't want to use SimpleDateFormat, since I believe its flexibility comes with too much overhead.
According to a quick jmh benchmark, on my laptop, Long.toString gets twelve million ops/second and SimpleDateFormat is two million.
What's your budget? Once you know that you'll be able to decide which of those is most appropriate.
Apache Commons Lang's FastDateFormat class is absolutely a good alternative to SimpleDateFormat. It's fast and also Thread-Safe ( especially usefull in multi-threaded server environments). All patterns are compatible with SimpleDateFormat (except time zones and some year patterns).
The summary of the constructor is :
FastDateFormat(String pattern, TimeZone timeZone, Locale locale)
You could find more info at FastDateFormat
Try:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);
Or:
Date date = new Date(milliseconds);
Not sure which one is faster though.
To format the Date into a string, you can use SimpleDateFormat:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss.SSS"); // should output something like you desired: 20141220 174522.23
String formattedDate = sdf.format(date);

Why has java.util.Date been deprecated? [duplicate]

When you look at the javadoc of the java.util.Date class, most of the methods are deprecated. Why was this done?
Well, for two related reasons. It was a very poor implementation of the concept of Dates and Times and it was replaced by the Calendar class.
The Calendar class, although an improvement, leaves a lot to be desired as well, so for serious Date/Time work, everyone recommends Joda-Time. Java 8 brings the new java.time.* package, inspired by Joda-Time, defined by JSR-310, and intended to supplant the old Date/Calendar classes.
Edit: In response to the specific question of why the implementation is poor, there are many reasons. The JavaDoc sums it up as follows:
Unfortunately, the API for these functions was not amenable to internationalization.
In addition to this general deficiency (which covers issues like the lack of a Time Zone component as well as the date formatting which is better handled in DateFormat and the inability to have a non-Gregorian calendar representation), there are specific issues which really hurt the Date class, including the fact that year is presented in an offset of 1900 from Common Era year.
Calendar has its own problems, but even as early as JDK 1.1 it was obvious that java.util.Date was not going to cut it. Even though Calendar is arguable the worst JDK API, it has taken until version 7 to attempt to address it.
Date is mutable
Date doesn't have support for time zones
The latter led to it being replaced by Calendar. And the former, combined with the ease-of-use, lead to both being replaced by Joda-Time / JSR-310 (java.time.* package)
They're deprecated because Date was written as fast as possible back in the day when they wanted to rush the JDK out the door.
It turns out the Dates and Calendars are Hard. So, they created the Calendar class, which much more thought, in order to handle the Hard Parts of working with calendars.
They deprecated the Date methods and delegated to Calendar because they didn't want to change the behavior of the existing Date methods, and possibly break existing applications.
Here's a good answer straight from Oracle: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html
A long-standing bugbear of Java developers has been the inadequate support for the date and time use cases of ordinary developers.
For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe, leading to potential concurrency issues for users—not something the average developer would expect to deal with when writing date-handling code.
Some of the date and time classes also exhibit quite poor API design. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive.
... java.util.Date represents an instant on the timeline—a wrapper around the number of milli-seconds since the UNIX epoch—but if you call toString(), the result suggests that it has a time zone, causing confusion among developers.
I don't know the official reason why it has been deprecated, but as far as I can tell GregorianCalendarand Joda-Time support operations on dates, meaning that you can add, for instance, a day to a date and have its month and year updated accordingly.
For instance, say you want to compute the day after the current date and today is May 31st; with java.util.Date, you just have getDays() +1, which returns 32, and you have to handle the knowledge that the current month doesn't have 32 days by yourself; with GregorianCalendaror Joda.time, adding a day to May 31st results in an object representing June 1st, hiding the complexity from your sight.

Can I parse relative times with JodaTime?

I'd love to be able to parse relative strings like now and yesterday and get JodaTime DateTimes. Is it possible? DateTimeFormat.forPattern and doesn't seem to support English relative times and I don't know of any other parsing options in JodaTime.
I should add that I'm using scala-time but can easily drop down to the actual JodaTime classes.
You would need to write either a separate library, or a DateTimeParser. DateTimeParser is the interface used internally by Joda-Time to parse text. Anyone can implement it and plug it directly into the Joda-Time parsing system using DateTimeFormatterBuilder.
Let's see here - "now", "yesterday", "today", "tomorrow". Is that about it? :-)
JodaTime won't parse them for you but it should be trivial enough to write your own function (or enum) to do so; you can even throw in stuff like "day after tomorrow" if you feel like it.
"Now" seems to be the only value for which DateTime would be appropriate, though - all others look more like LocalDate (or, possibly, DateMidnight) to me.

Formatting Timestamps in Java

Is there a way to format a UTC time into any arbitrary string format I want in java? Basically I was thinking of having some class take the timestamp and I pass it is string telling it how I want it formated, and it returns the formatted string for me. Is there a way to do this?
The java.text.SimpleDateFormat class provides formatting and parsing for dates in a locale-sensitive manner.
The javadoc header for SimpleDateFormat is a good source of detailed information. There is also a Java Tutorial with example usages.
The DateFormat class or SimpleDateFormat should get you there. For example, http://www.epochconverter.com/ lists the following example to convert a epoch time to human readable timestamp with Java:
String date = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date (epoch*1000));
Date instances are insufficient for some purposes.
Use Joda Time instead.
Joda time integrates with Hibernate and other databases.
One gotcha to be aware of is that SimpleDateFormat is NOT thread-safe. Do not put it in a static field and use it from multiple threads concurrently.

Categories