Which is the right way to compare Time in Java?
I mean java.sql.Time.
Or is there a better way we can compare time in Joda Time?
If you can use Joda Time do so. Convert all sql types to Joda equivalents at the persistence layer and then work with Joda objects in your business logic. You won't regret it, believe me.
LocalTime is probably the object you want to use then you can use compareTo(), isAfter(), isBefore(). Its also really easy to merge this into a full DateTime if necessary.
Related
I'm creating a custom data type that needs to store a set of exact timestamps (to millisecond accuracy) in a way that is both efficient and correct. I'm not particularly famiilar with the intricacies of timestamp handling so thought I would ask here for some wise advice.
I can see many options:
Store a Joda Instant for every timestamp.
Store a Joda DateTime for every timestamp.
Store a single Joda DateTime object once for the data type, and have a long offset for all the other timestamps relative to the main DateTime
Express every timestamp as a long offset to a fixed point (e.g. the Unix epoch of 1970-01-01T00:00:00Z )
.....other combinations.....
Questions:
What is the best way to store a sequence of timestamps?
What are the key tradeoffs?
Any pitfalls to watch out for?
Each of your storage options makes sense, and it's nice to see all of your options are with actual instants and never local datetimes (e.g., without time zones).
Your custom class will really be defined by its interface, so if you choose to store longs (epoch offsets) you can always provide interface methods to get the values from the sequence (and I assume other things like "deltas" -- or intervals, durations, or periods in Joda-speak) in human readable datetimes and periods if you like.
As you asked a number of questions, involving trade-offs, here's what I can offer:
Storing a sequence of longs is the most space-efficient.
Longs are not really as bad as you might think, since if your interface methods want to return datetimes, you just pass the long to the DateTime constructor.
Instants are thin wrappers over longs and provide convenience methods if you need to add durations to them or compute durations from instants; your code might look a little nicer than if you do your own math on longs and then construct a DateTime or Period or Duration around them.
DateTimes are great if you don't have excessive storage requirements and the actual date and time-of-day matter to the clients of your custom data type. Will your users care that a timestamp is on October 10th at 16:22 in the America/Los Angeles time zone? Or is the duration between the timestamps all that matter?
Storing a datetime or instant plus an array of offsets looks like a messy implementation since there are two concepts in play. I would think storing a single sequence of instants/datetimes only, and not mixing in durations, make a lot more sense. If you need to work with durations, just compute them in your interface methods.
I would say the only pitfalls to watch out for involve dealing with time zones if you are storing longs and your clients need to be thinking in datetimes.
In terms of tradeoffs, I only really see that longs, being primitive, save space, and I would guess a miniscule amount of time since DateTimes are objects and there is all that heap allocation and deallocation that takes place. But again, unless you are severely memory-constrained, I would say the best thing is to store DateTimes. Joda-Time can do all the time zone management for you. The parsing and formatting routines are easy and thread-safe. There are tons of convenience methods in place. And you won't have to do any conversion of your own from datetimes to longs. Storing longs only feels like a premature optimzation to me. Strangely enough, FWIW, I would probably do that in Python, since Python's datetime objects are naive, rather than timezone-aware, by default! Jada-Time makes IMHO a very nice and easy to understand distinction between Instants and Local DateTimes, so sticking with DateTimes everywhere will be, I believe, your best bet.
So I have an ISO 8601 date/time stamp like "2011-04-21T17:07:50-07:00", and I would like to convert it to say something like "23 minutes ago" or something of that sort. Is there a small bit of Java code or a library that would be able to do something like that easily?
Thanks!
What you are looking for is known as fuzzy time. A quick Google on this term found jFuzzyDate
First, parse it into a Date object. Then, make a new Date which will have the current date/time. Then, call the .getTime() methods on both of the Date objects, and subtract. Now you have your time in milliseconds.
You can do your own math from there, because until you start worrying about leap years it's all easy division.
Joda is a great time library and should have all the methods you need to do this: http://joda-time.sourceforge.net/.
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).
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.
Is it possible in easy way to convert JRuby Time/DataTime/Data into java.util.Calendar including the timezone?
On #jruby I was given such code cal.set_time_in_millis(time.to_i) but I lost information about timezone in betwean. So the more specific question is how to convert the timezone but I prefered to ask more broad questin in case there is simpler way.
You can use the #to_java method to convert a Ruby time object to a java.util.Date:
require 'java'
Time.now.to_java
Note this coersion happens automatically when passing Ruby objects to Java methods.
I get known that the Time does not store timezone so what is returned by Time.now.zone is local timezone.
Therefore it is simple to convert to java.util.Data:
data = java.util.Date.new(date.to_i*1000)