I am doing some basic (edit: reading and writing to a txt file), which requires me to store a bunch of expenses, and their attributes (i.e. name, price, date of purchase, etc.) I would like to be able to compare dates of purchases if possible. It occured to me that I had a few options when it came to what type of object the date of purchase should be:
I could make the date a Calendar object, and store it on the .txt this would mean storing lots of Calendar objects at once, and then easily compare the dates
I could make the date a String, store it, transmute it to a Calendar object, and then compare them
I could leave the dates as strings and when I am ready to compare them, create some kind of code to go through individual characters and pick out a certain phrase or set of characters.
Which of these would probably be best for keeping the load on the computer down? Also, how would you go about loading objects as they build up over time? Once a person has a lot of spending, it would get pretty hefty to load every single item.
I would strongly suggest using Joda Time wherever possible, rather than Calendar and Date - it's a much cleaner date/time API.
Beyond that, definitely make your object model match your domain as closely as possible. You're dealing with dates, not strings - so make your object model reflect that. You should be converting between strings and dates as rarely as possible. It not clear what you mean by "store it on the .txt" (given that elsewhere you're talking about a database) but using JDBC you'd use parameters anyway, without string conversions.
As for load - work out your performance requirements beforehand, try the simplest approach that works, and test whether that meets your requirements. Usually when people talk about having to have an efficient solution they haven't actually considered what they need. You talk about it getting "pretty hefty" to load every single item - how many items? Can you load them in a batch? Where will the database be? You'd be amazed how much data can be processed these days - but you need to understand the parameters of your problem before you make too many decisions that are hard to change later.
Related
This sounds pretty simple, but i just cant wrap my head around it.
I have two fields in my DB. availableFromDate and availableToDate.
The user is doing a search to find all entities available within a given range. So my action receives two dates:
searchFromDate and searchToDate.
All i need to do is to return all entities that is available the whole period specified by the user.
Preferably using Criterias.
Anyone?
If I understand you question correctly - That is, that the event availability should lie completely within the search date range - then it should boil down to this:
If you ensure that "availableFromDate.before(availableToDate)" and "searchFromDate.before(searchToDate)" - which you should do anyway in this case - Then both your availableFromDate and your availableToDate have to be in the search date range.
You can use the solution from this answer to make sure both dates are within the range: How to compare dates in hibernate
criteria.add(Restrictions.between("availableFromDate", searchFromDate, searchToDate));
criteria.add(Restrictions.between("availableToDate", searchFromDate, searchToDate));
My reason for doing so is that dates stored as date objects in whatever database tend to be written in a specific format, which may greatly differ from what you need to present to the user on the front-end. I also think it's especially helpful if your application is pulling info from different types of data stores. A good example would be the difference between a MongoDB and SQL date object.
However, I don't know whether this is recommended practice. Should I keep storing dates as longs (time in milliseconds) or as date objects?
I can't speak for it in relation to MongoDB, but in SQL database, no, it's not best practice. That doesn't mean there might not be the occasional use case, but "best practice," no.
Store them as dates, retrieve them as dates. Your best bet is to set up your database to store them as UTC (loosely, "GMT") so that the data is portable and you can use different local times as appropriate (for instance, if the database is used by geographically diverse users), and handle any conversions from UTC to local time in the application layer (e.g., via Calendar or a third-party date library).
Storing dates as numbers means your database is hard to report against, run ad-hoc queries against, etc. I made that mistake once, it's not one I'll repeat without a really good reason. :-)
It very much depends on:
What database you're using and its date/time support
Your client needs (e.g. how happy are you to bank on the idea that you'll always be using Java)
What information you're really trying to represent
Your diagnostic tools
The third point is probably the most important. Think about what the values you're trying to store really mean. Even though you're clearly not using Noda Time, hopefully my user guide page on choosing which Noda Time type to use based on your input data may help you think about this clearly.
If you're only ever using Java, and your database doesn't have terribly good support for date/time types, and you're only trying to represent an "instant in time" (rather than, say, an instant in a particular time zone, or a local date/time with an offset, or just a local date/time, or just a date...), and you're comfortable writing diagnostic tools to convert your data into more human readable forms - then storing a long is reasonable. But that's a pretty long list of "if"s.
If you want to be able to perform date manipulation in the database - e.g. asking for all values which occur on the first day of the month - then you should probably use a date/time type, being careful around time zones. (My experience is that most databases are at least shocking badly documented when it comes to their date/time types.)
In general, you should use whatever type is able to meet all your requirement and is the most natural representation for that particular environment. So in a database which has a date/time type which doesn't give you issues when you interact with it (e.g. performing arbitrary time zone conversions in an unrequested way), use that type. It will make all kinds of things easier.
The advantage of using a more "primitive" representation (e.g. a 64 bit integer) is precisely that the database won't mess around with it. You're effectively hiding the meaning of the data from the databae, with all the normal pros and cons (mostly cons) of that approach.
It depends on various aspects. When using the standard "seconds since epoch", and someone uses only integer precision, their dates are limited to the 1970-2038 year range.
But there also is some precision issue. For example, unix time ignores leap seconds. Every day is defined to have the same number of seconds. So when computing time deltas between unix time, you do get some error.
But the more important thing is that you assume all your dates to be completely known, as your representation does not have the possibility to half only half-specified dates. In reality, there is a lot of events you do not know at a second (or even ms) precision. So it is a feature if a representation allows specifing e.g. only a day precision. Ideally, you would store dates with their precision information.
Furthermore, say you are building a calendar application. There is time, but there also is local time. Quite often, you need both information available. When scheduling overlaps, you of course can do this best in a synchronized time, so longs will be good here. If you however do also want to ensure you are not scheduling events outside of 9-20 h local time, you also always need to preserve timezone information. For anything that does span more than one location, you really need to include the time zone in your date representation. Assuming that you can just convert all dates you see to your current local time is quite naive.
Note that dates in SQL can lead to odd situations. One of my favorites is the following MySQL absurdity:
SELECT * FROM Dates WHERE date IS NULL AND date IS NOT NULL;
may return records that have the date 0000-00-00 00:00:00, although this violates the popular understanding of logic.
Since this question is tagged with MongoDB: MongoDB does not store dates in String or what not, they actually store it as a long ( http://www.mongodb.org/display/DOCS/Dates ):
A BSON Date value stores the number of milliseconds since the Unix epoch (Jan 1, 1970) as a 64-bit integer. v2.0+ : this number is signed so dates before 1970 are stored as a negative numbers.
Since MongoDB has no immediate plans to utilise the complex date handling functions (like getting only year for querying etc) that SQL has within standard querying there is no real downside, it might infact reduce the size of your indexes and storage.
There is one thing to take into consideration here, the aggregation framework: http://docs.mongodb.org/manual/reference/aggregation/#date-operators there are weird and wonderful things you can only with the supported BSON date type in MongoDB, however, as to whether this matters to you depends upon your queries.
Do you see yourself as needing the aggregation frameworks functions? Or would housing the extra object overhead be a pain?
My personal opinion is that the BSON date type is such a small object that to store a document without it would be determental to the entire system and its future compatibility for no apparent reason. So, yes, I would use the BSON date type rather than a long and I would consider it good practice to do so.
I dont think its a best practice to store dates as long because, that would mean that you would not be able to do any of the date specific queries. like :
where date between
We also wont be able to get the date month of year from the table using sql queries easily.
It is better to use a single date format converter in the java layer and convert the date into that and use a single format throughout the application.
IMHO , storing dates in DB will be best if you can use Strings. Hence avoid unnecessary data going up and down to server , if you don't need all the fields in Calendar.
There is a lot of data is in Calendar and each instance of Calender is pretty heavy too.
So store it as String , with only required data and convert it back to Calendar , whenvever you need them and use them.
I work on a graph where I visualize my emails. I want to be able to get the emails from a certain day.
Is this a bad way to store?
HashMap<DateTime, ArrayList<Email>>
Or is it better to convert the date to a string and then use HashMap<String, ArrayList<Email>>
Note, the dates are added without hours, minutes and seconds, so just like 06/07/2010 for example.
DateTime has properly defined equals and hashcode methods, so using those as the key in a HashMap is perfectly OK. There's not much to be gained by converting them to strings first.
I would suggest, however, that if you only want to store the year/month/day components, then you may want to use LocalDate instead of DateTime.
Additionally, you could also consider using TreeMap rather than HashMap, so that your map is automatically sorted by date. Might be handy.
I code a little Console program and now I store the date they joined in a database like.
CreateDate
2011-04-15 17:52:57
Now I want to do a check like this: a function that gets how many days the guy have been registered.
if(player.getDaysSinceRegistration) {
Thanks for any help.
joda-time has an easy way to do this:
Days.daysBetween(new DateTime(registeredDate), new DateTime()).getDays();
Without 3rd party libraries:
(System.currentTimeMillis() - registeredDate.getTime()) / MILLIS_PER_DAY;
First of all, don't store dates in databases in textual form.
You should save them as database dates (a type like numbers or varchars), as this will allow you to both ask the database do date calculations as well - the exact way to do so is database specific - as have it automatically pulled up in a Java date object by the JDBC driver which is much easier to work with than strings. See Bozho's answer for suggestions to do this in the Java layer.
what is the best solution in terms of performance and "readability/good coding style" to represent a (Java) Enumeration (fixed set of constants) on the DB layer in regard to an integer (or any number datatype in general) vs a string representation.
Caveat: There are some database systems that support "Enums" directly but this would require to keept the Database Enum-Definition in sync with the Business-Layer-implementation. Furthermore this kind of datatype might not be available on all Database systems and as well might differ in the syntax => I am looking for an easy solution that is easy to mange and available on all database systems. (So my question only adresses the Number vs String representation.)
The Number representation of a constants seems to me very efficient to store (for example consumes only two bytes as integer) and is most likely very fast in terms of indexing, but hard to read ("0" vs. "1" etc)..
The String representation is more readable (storing "enabled" and "disabled" compared to a "0" and "1" ), but consumes much mor storage space and is most likely also slower in regard to indexing.
My questions is, did I miss some important aspects? What would you suggest to use for an enum representation on the Database layer.
Thank you very much!
In most cases, I prefer to use a short alphanumeric code, and then have a lookup table with the expanded text. When necessary I build the enum table in the program dynamically from the database table.
For example, suppose we have a field that is supposed to contain, say, transaction type, and the possible values are Sale, Return, Service, and Layaway. I'd create a transaction type table with code and description, make the codes maybe "SA", "RE", "SV", and "LY", and use the code field as the primary key. Then in each transaction record I'd post that code. This takes less space than an integer key in the record itself and in the index. Exactly how it is processed depends on the database engine but it shouldn't be dramatically less efficient than an integer key. And because it's mnemonic it's very easy to use. You can dump a record and easily see what the values are and likely remember which is which. You can display the codes without translation in user output and the users can make sense of them. Indeed, this can give you a performance gain over integer keys: In many cases the abbreviation is good for the users -- they often want abbreviations to keep displays compact and avoid scrolling -- so you don't need to join on the transaction table to get a translation.
I would definitely NOT store a long text value in every record. Like in this example, I would not want to dispense with the transaction table and store "Layaway". Not only is this inefficient, but it is quite possible that someday the users will say that they want it changed to "Layaway sale", or even some subtle difference like "Lay-away". Then you not only have to update every record in the database, but you have to search through the program for every place this text occurs and change it. Also, the longer the text, the more likely that somewhere along the line a programmer will mis-spell it and create obscure bugs.
Also, having a transaction type table provides a convenient place to store additional information about the transaction type. Never ever ever write code that says "if whatevercode='A' or whatevercode='C' or whatevercode='X' then ..." Whatever it is that makes those three codes somehow different from all other codes, put a field for it in the transaction table and test that field. If you say, "Well, those are all the tax-related codes" or whatever, then fine, create a field called "tax_related" and set it to true or false for each code value as appropriate. Otherwise when someone creates a new transaction type, they have to look through all those if/or lists and figure out which ones this type should be added to and which it shouldn't. I've read plenty of baffling programs where I had to figure out why some logic applied to these three code values but not others, and when you think a fourth value ought to be included in the list, it's very hard to tell whether it is missing because it is really different in some way, or if the programmer made a mistake.
The only type I don't create the translation table is when the list is very short, there is no additional data to keep, and it is clear from the nature of the universe that it is unlikely to ever change so the values can be safely hard-coded. Like true/false or positive/negative/zero or male/female. (And hey, even that last one, obvious as it seems, there are people insisting we now include "transgendered" and the like.)
Some people dogmatically insist that every table have an auto-generated sequential integer key. Such keys are an excellent choice in many cases, but for code lists, I prefer the short alpha key for the reasons stated above.
I would store the string representation, as this is easy to correlate back to the enum and much more stable. Using ordinal() would be bad because it can change if you add a new enum to the middle of the series, so you would have to implement your own numbering system.
In terms of performance, it all depends on what the enums would be used for, but it is most likely a premature optimization to develop a whole separate representation with conversion rather than just use the natural String representation.