<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Aaron Gadberry &#187; Computers</title>
	<atom:link href="http://www.gadberry.com/aaron/category/computers/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gadberry.com/aaron</link>
	<description>Help - v. helped, helpÂ·ing, helps</description>
	<lastBuildDate>Mon, 16 Jan 2012 22:58:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Update Epic 4G from FROYO.DK28 to Gingerbread.EI22</title>
		<link>http://www.gadberry.com/aaron/2011/12/21/update-epic-4g-from-froyo-dk28-to-gingerbread-ei22/</link>
		<comments>http://www.gadberry.com/aaron/2011/12/21/update-epic-4g-from-froyo-dk28-to-gingerbread-ei22/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 15:29:27 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=403</guid>
		<description><![CDATA[I was one of the unfortunate ones that updated to DK28 in the first days that Froyo was released on the Sprint Epic 4G. The Gingerbread.EI22 update that came out in November did not appear as an available update on my Epic, because I had Froyo.DK28, and it is only an update for Froyo.EC05. Unfortunately, [...]]]></description>
			<content:encoded><![CDATA[<p>I was one of the unfortunate ones that updated to DK28 in the first days that Froyo was released on the Sprint Epic 4G.  The Gingerbread.EI22 update that came out in November did not appear as an available update on my Epic, because I had Froyo.DK28, and it is only an update for Froyo.EC05.  Unfortunately, there is no OTA path from DK28 to EC05, nor one from DK28 to EI22.  I opted to flash from DK28 to EC05 manually, and then follow the OTA updates to EI22.  In the process of the manual update to EC05, unfortunately I would have lost all applications and data, so that added the complication of rooting before the flash, and after the eventual EI22 update, in order to restore the application data.</p>
<ol>
<li>Root the existing Froyo.DK28 using instructions found here: <a href="http://forum.xda-developers.com/showthread.php?t=1076967" title="http://forum.xda-developers.com/showthread.php?t=1076967">http://forum.xda-developers.com/showthread.php?t=1076967</a></li>
<li>Backup applications and data using Titanium backup (I bought the PRO version, although it looks like you could accomplish what is needed with the free one)</li>
<li>Odin back to EC05 using instructions found here (addl instructions below): <a href=" http://forums.androidcentral.com/epic-4g-rooting-roms-hacks/60768-how-factory-restore-fix-bricked-phone.html" title="Flash/Restore to Froyo EC05">Flash/Restore to Froyo EC05</a>
<ul>
<li>Download and Install drivers first (they fail to actually tell you to install them)</li>
<li>Change Odin to compatibility mode for XP SP3 and run it as an administrator</li>
<li>Sometimes it may help to remove the SD Card and/or Battery before entering download mode</li>
<li>If you get stuck, like I did, realize that <a href="http://forum.xda-developers.com/showthread.php?t=1365455">Odin is very picky about USB cables</a></li>
<li>As long as you can get back to the downloading mode, you should be ok</li>
</ul>
</li>
<li>Boot into the stock EC05, and check Settings > About Phone > System Updates > Update Android.  It should be downloading Gingerbread.EI22.  Let the update complete.</li>
<li>Root the new Gingerbread.EI22 using the instructions found here: <a href="http://forums.androidcentral.com/epic-4g-rooting-roms-hacks/132495-rooting-ei22-gingerbread-instructions.html">http://forums.androidcentral.com/epic-4g-rooting-roms-hacks/132495-rooting-ei22-gingerbread-instructions.html</a> or here:<a href="http://forum.xda-developers.com/showthread.php?t=1339478">http://forum.xda-developers.com/showthread.php?t=1339478</a></li>
<ul>
<li>The instructions have a bad link to ACSRecovery1.0.0.5.tar.md5 and su-3.0-efgh-signed.zip but the good link can be found on page 11</li>
<li>Be sure to get the file ending in md5.  For some of these there are .tar and .tar.md5 so be careful.</li>
</ul>
<li>Reinstall Titanium backup from the market and restore applications and data</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2011/12/21/update-epic-4g-from-froyo-dk28-to-gingerbread-ei22/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Application Data Sync / Backup</title>
		<link>http://www.gadberry.com/aaron/2011/06/27/android-application-data-sync-backup/</link>
		<comments>http://www.gadberry.com/aaron/2011/06/27/android-application-data-sync-backup/#comments</comments>
		<pubDate>Tue, 28 Jun 2011 02:14:56 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=395</guid>
		<description><![CDATA[The Android platform is great, when used in isolation, but owning multiple devices is not really supported (as of my Epic running 2.2 and my Transformer running 3.1). Of course you can own them independently, but there is no support for device linking or sharing of information. As Android is maturing, so are the apps [...]]]></description>
			<content:encoded><![CDATA[<p>The Android platform is great, when used in isolation, but owning multiple devices is not really supported (as of my Epic running 2.2 and my Transformer running 3.1).  Of course you can own them independently, but there is no support for device linking or sharing of information.  As Android is maturing, so are the apps that run on it.  What is application data?  Application data isn&#8217;t the spreadsheet or document saved to the SD card.  It is the data specifically associated with each application, such as user settings or saved states.  In Android there is no opportunity to sync, or even backup, application data.  Neither is there an app that can accomplish this, because it is prohibited for apps to access other apps&#8217; data (appropriately so).  The only group that can effectively deploy this functionality within Android is Google.</p>
<p>Of course the difficulty depends on the complexity of the implementation, however the design is fairly simple.  Application data is organized and maintained by Android today.  Users have the opportunity to clear it through the Manage Applications interface.  Would it be so hard as to sync it or back it up as well?  This could be easily implemented for ALL applications.</p>
<p>The versioning could be maintained separately.  Mobile app version 1.1-1.8 and honeycomb versions 1.0-1.5 are compatible with application configuration 1.1, etc.</p>
<p><a href="http://code.google.com/p/android/issues/detail?id=17831">Here is the best feature request for application data sync / backup I could find.</a>  Please go star it if you agree.</p>
<p>The high points of design I agree with are</p>
<ul>
<li>All applications should be supported</li>
<li>Only application data need be supported, not the actual application</li>
<li>Sync to Cloud</li>
<li>Backup to Local or Cloud</li>
<li>On demand or on schedule or triggered syncs/ backups w/connection and/or size based controls</li>
<li>Compression</li>
<li>Block hashing</li>
<li>Encryption</li>
</ul>
<p>With multi-device users, this feature is essential, and only able to be provided by Google.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2011/06/27/android-application-data-sync-backup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wuala for Dropbox Users</title>
		<link>http://www.gadberry.com/aaron/2011/04/29/wuala-for-dropbox-users/</link>
		<comments>http://www.gadberry.com/aaron/2011/04/29/wuala-for-dropbox-users/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 22:36:35 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=361</guid>
		<description><![CDATA[First off, my shameless referral link. Use it to get 2GB instead of 1GB. If you haven&#8217;t checked out Wuala yet, you really should. Dropbox has had several security concerns recently and Wuala is a more functional alternative. Maybe all you want is folder sync, but look at what Wuala can do and you may [...]]]></description>
			<content:encoded><![CDATA[<p>First off, my <a href="http://www.wuala.com/referral/AN4NH3PFCAJMF7CJ6N4M">shameless referral link</a>.  Use it to get 2GB instead of 1GB.</p>
<p>If you haven&#8217;t checked out Wuala yet, you really should.  Dropbox has had several security concerns recently and Wuala is a more functional alternative.  Maybe all you want is folder sync, but look at what Wuala can do and you may change your mind.</p>
<p>How isn&#8217;t Wuala like Dropbox?</p>
<ul>
<li>Wuala is not a sync utility, it is a P2P online storage utility.  <strong>Wuala files are not on your PC, they are in the P2P cloud.</strong></li>
<li>The Wuala client is not a daemon (although you can treat it like one if you want, see Sync below)</li>
<li>You can have access to a 60GB music collection on 3 PCs without using 180GB</li>
<li>Logging off means your files are no longer available on the computer.</li>
<li>The Wuala client is psuedo read only.</li>
<ul>
<li>You create a new local drive during install in order to have full read/write functionality.</li>
</ul>
<li>Wuala encrypts your files client-side with AES 128-bit encryption.</li>
<ul>
<li>The original, unencrypted files are never uploaded.</li>
</ul>
<li>You get 1GB of online space free. (Or 2GB by clicking on <a href="http://www.wuala.com/referral/AN4NH3PFCAJMF7CJ6N4M">this link</a>)</li>
<li>You can go &#8216;pro&#8217; by either paying or trading space.
<ul>
<li>Pro means you can use Sync (like Dropbox), and other benefits like Backup.</li>
</ul>
<li>You can trade space to get more online storage.
<ul>
<li>You store their encrypted files and they store yours.</li>
<li>The more you share the more you get up to 100GB.</li>
</ul>
<li>Logged off you stay connected to the P2P network and continue to gain uptime (relevant to trading space).</li>
</ul>
<p>How is Wuala like Dropbox?</p>
<ul>
<li>Sync will keep a Wuala online folder in sync with a local PC folder.
<ul>
<li>Do this on multiple computers to emulate Dropbox.</li>
<li>Or this can just keep an up to date offline copy.</li>
</ul>
<li>There are Android and iPhone clients</li>
<li>There is a web client (Java applet to support client side decryption)</li>
</ul>
<p><a href="http://www.wuala.com/referral/AN4NH3PFCAJMF7CJ6N4M">Sign up here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2011/04/29/wuala-for-dropbox-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing a OCZ Vertex 2 SSD in a Lenovo T60p</title>
		<link>http://www.gadberry.com/aaron/2011/03/14/installing-a-ocz-vertex-2-ssd-in-a-lenovo-t60p/</link>
		<comments>http://www.gadberry.com/aaron/2011/03/14/installing-a-ocz-vertex-2-ssd-in-a-lenovo-t60p/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 01:10:07 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=352</guid>
		<description><![CDATA[Well I was very pleased to receive my 120GB OCZ Vertex SSD today, but disappointed when it didn&#8217;t fit in my Lenovo T60p. After doing some google searches I didn&#8217;t find anyone else with the problem. Isn&#8217;t it strange that when google has no results we assume we are doing something wrong?!? Anyways I tried [...]]]></description>
			<content:encoded><![CDATA[<p>Well I was very pleased to receive my <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820227395">120GB OCZ Vertex SSD</a> today, but disappointed when it didn&#8217;t fit in my Lenovo T60p.  After doing some google searches I didn&#8217;t find anyone else with the problem.  Isn&#8217;t it strange that when google has no results we assume we are doing something wrong?!?</p>
<p>Anyways I tried seating it about 20 times, and was finally able to get it to go all the way in.  Don&#8217;t force it, just jiggle it.  It will go.  It may help to remove the bumpers and get it in with just the tray, and then try again with the bumpers.</p>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2011/03/14/installing-a-ocz-vertex-2-ssd-in-a-lenovo-t60p/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Phonebook</title>
		<link>http://www.gadberry.com/aaron/2010/07/09/facebook-phonebook/</link>
		<comments>http://www.gadberry.com/aaron/2010/07/09/facebook-phonebook/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 14:39:17 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=211</guid>
		<description><![CDATA[Yesterday I saw a status message set to: *WARNING**Go to the top right of your screen, click Account &#38; then click Edit Friends. Go to the left side of your screen and click Phonebook. Everyone’s phone # is being published. Please repost (sic) to let your friends know of this change in security, so that [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I saw a status message set to:</p>
<blockquote><p>*WARNING**Go to the top right of your screen, click Account &amp; then click Edit Friends. Go to the left side of your screen and click Phonebook. Everyone’s phone # is being published. Please repost (sic) to let your friends know of this change in security, so that they can remove their phone numbers or change their privacy settings…</p></blockquote>
<p>I went and checked out my <a href="http://www.facebook.com/friends/?phonebook">Phonebook</a> and noticed that all the phone numbers in there were from Facebook friends that had them listed in their profiles.  I think it&#8217;s not so bad for Facebook to organize the information that people have made available to me already.  Apparently this is a pretty old feature I had just never seen.  False alarm.  Nothing to see here.</p>
<p>Then I saw this message at the top of the screen.</p>
<blockquote><p>To learn more about Phonebook or to delete any contacts imported from your phone, click here.</p></blockquote>
<p><span id="more-211"></span><br />
From my phone?!?  Click&#8230;</p>
<blockquote><p>Facebook Phonebook displays contacts you have imported from your phone, as well as your Facebook friends. If you would like to remove your mobile contacts from Facebook, you need to disable the feature on your mobile phone and visit this page.</p></blockquote>
<blockquote><p>Remove Imported Contacts</p>
<p>When you import contacts into Facebook from your email, mobile, or instant messaging service, we may use this information to create friend suggestions for you and your friends. We also display these contacts in your Facebook Phonebook.</p>
<p>If you choose to remove your imported contacts, they will no longer appear in your Phonebook and friend suggestions may be less relevant to you and your friends.</p>
<p>To remove all imported contacts, please make sure to disable the Facebook synchronization feature on your phone first, if you have ever enabled it. Then, click the &#8216;Remove&#8217; button below.</p></blockquote>
<p>It turns out that Facebook is uploading contact information from your phone and storing the phone numbers.  I can&#8217;t find any official information about this beyond what I posted above.  Within Phonebook though, it looks to me as if imported numbers have a phone icon, while profile numbers list MOBILE or HOME, etc.</p>
<p>This information is not being formally added to profiles, but it is obviously associated with accounts.  Why is this upsetting?  Because Facebook has my phone number, you know that one I intentionally left off Facebook.  I see no options to view or remove this information.  I can&#8217;t even see what they have on me.  It wouldn&#8217;t surprise me if Facebook is collecting other contact data from phones, such as email address, physical address, birthday, messenger screennames, and other contact information that most phones store.</p>
<p>I checked a friend&#8217;s Phonebook and Blackberry®, and several phone numbers had been imported.  In the Blackberry® Facebook app there is a setting under Options to disable the syncing of Contacts.  I do not know if it is enabled by default.</p>
<p>After some more searching it looks like not all phones with a Facebook app are syncing this information.  I have an HTC Hero with an Android Facebook App and a HTC Facebook App and I have Sync Contacts checked, however none of the phone numbers in my Phonebook came from my phone.  They are all listed on profiles.  I&#8217;m sure eventually Facebook will upgrade their android app to sync as well.</p>
<p>If anyone has any information about other phones, or better Facebook apps that can enable a one way only sync, please post in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2010/07/09/facebook-phonebook/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Teather a Laptop to a Sanyo PRO-700 for Internet via Bluetooth</title>
		<link>http://www.gadberry.com/aaron/2008/08/29/teather-a-laptop-to-a-sanyo-pro-700-for-internet-via-bluetooth/</link>
		<comments>http://www.gadberry.com/aaron/2008/08/29/teather-a-laptop-to-a-sanyo-pro-700-for-internet-via-bluetooth/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 14:53:21 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/?p=172</guid>
		<description><![CDATA[Update: This may no longer work without a tethering plan After 7 calls and 2.5 hours on hold with Sprint I have finally done it. It was really not that difficult, I just needed the special number to dial (#777) to make it happen. For the rest of you here is a step by step [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Update: This may no longer work without a tethering plan</em></strong></p>
<p><a href="http://www.gadberry.com/aaron/wp-content/uploads/2008/08/pro700.png"><img src="http://www.gadberry.com/aaron/wp-content/uploads/2008/08/pro700-300x235.png" alt="" title="pro700" width="300" height="235" class="alignright size-medium wp-image-171" /></a></p>
<p>After 7 calls and 2.5 hours on hold with Sprint I have finally done it.<br />
It was really not that difficult, I just needed the special number to dial (#777) to make it happen.<br />
For the rest of you here is a step by step guide.</p>
<ol>
<li>Turn bluetooth on for the PC and the phone (Menu, Settings, Bluetooth, On)</li>
<li>Add the computer as a trusted device on the phone (Shouldn&#8217;t be necessary but it seems to not work without this configured first)</li>
<ol>
<li>On the phone visit Menu, Settings, Bluetooth, Trusted Devices, Add New</li>
<li>Choose search.  Select your PC name from the list and choose &#8220;Add to Trusted&#8221;</li>
<li>Enter a NUMERIC pin on the phone. Press Done</li>
<li>The System Tray on the PC will pop up with a pair request.  Click on it and enter the code you just entered on the phone.  Press OK.</li>
<li>Name the device on the phone (or leave it the same) and press OK</li>
</ol>
<li>Make the phone visible (Menu, Settings, Bluetooth, Visibility, Visible for 3 min.)</li>
<li>Open My Bluetooth Places on the PC (Right click on Bluetooth System Tray Icon)</li>
<li>Choose Bluetooth Setup Wizard link on the left of My Bluetooth Places.</li>
<li>Choose &#8220;I know the service I want to use and I want to find a Bluetooth device that provides that service&#8221; and press Next.</li>
<li>Choose &#8220;Dial Up Networking&#8221; and press next.</li>
<li>Choose the icon representing your phone and press next.</li>
<li>Press &#8220;Configure&#8221;</li>
<li>Press &#8220;Configure&#8221; again</li>
<li>Put in the phone number #777 and press Ok twice.  Press Finish</li>
<li>Bubble will appear from System Tray asking about pairing.  Click on it.</li>
<li>Enter an security code using NUMBERS and press Ok</li>
<li>Phone will alert you of an attempted pairing.  Choose Yes, enter the security code you just made up and then choose ok.</li>
<li>Connection will succeed and Dial Up Networking dialog will appear on the computer.</li>
<li>Username and password should be empty and phone number should be #777.  Press Dial</li>
<li>It should connect.  Your phone will ask you if you want to accept the connection.  Say yes</li>
<li>The phone screen will change to read Data Connection.</li>
<li>Your computer is online!</li>
</ol>
<p>Other things you can do to improve your experience&#8230;</p>
<ul>
<li>Turn on auto-accept on the phone for the trusted device</li>
<li>Stop the PC from asking you the username, password and phone number by&#8230;
<ol>
<li>Right click on the phone in the My Bluetooth Places screen and choose properties</li>
<li>Choose Configure, then the options tab</li>
<li>Uncheck prompt for name and password and prompt for phone number</li>
<li>Choose OK and then OK again</li>
</ol>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2008/08/29/teather-a-laptop-to-a-sanyo-pro-700-for-internet-via-bluetooth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use NULLS FIRST in TOPLink Expression API Ordering</title>
		<link>http://www.gadberry.com/aaron/2008/01/22/use-nulls-first-in-toplink-expression-api-ordering/</link>
		<comments>http://www.gadberry.com/aaron/2008/01/22/use-nulls-first-in-toplink-expression-api-ordering/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 01:37:36 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/2008/01/22/use-nulls-first-in-toplink-expression-api-ordering/</guid>
		<description><![CDATA[There is no specific method for NULLS FIRST (default is NULLS LAST), but you can still accomplish this through the expression api. You can simply append some sql to the end of your ordering field expression and it will take care of it for you. For example, if you are ordering by the name then [...]]]></description>
			<content:encoded><![CDATA[<p>There is no specific method for NULLS FIRST (default is NULLS LAST), but you can still accomplish this through the expression api.</p>
<p>You can simply append some sql to the end of your ordering field expression and it will take care of it for you.</p>
<p>For example, if you are ordering by the name then this would put the nulls last (default):</p>
<div class="code_box"><code>query.addOrdering(builder.get("name"));
</code></div>
<p>This code could be ammended into the following to put nulls first:</p>
<div class="code_box"><code>query.addOrdering(builder.get("name").postfixSQL("NULLS FIRST"));
</code></div>
<p>It&#8217;s that easy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2008/01/22/use-nulls-first-in-toplink-expression-api-ordering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find the Difference Between two Java Dates (Calendars)</title>
		<link>http://www.gadberry.com/aaron/2007/08/17/find-the-difference-between-two-java-dates-calendars/</link>
		<comments>http://www.gadberry.com/aaron/2007/08/17/find-the-difference-between-two-java-dates-calendars/#comments</comments>
		<pubDate>Fri, 17 Aug 2007 20:40:58 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/2007/08/17/find-the-difference-between-two-java-dates-calendars/</guid>
		<description><![CDATA[Well the first question to ask is what unit do you want the difference in. This is one of the reasons many people stick to incremental date math instead of math returning an int. Lets say you want to do a basic age calculation. How old is Joe? His birthday is 7/29/1981. Well you could [...]]]></description>
			<content:encoded><![CDATA[<p>Well the first question to ask is what unit do you want the difference in.  This is one of the reasons many people stick to incremental date math instead of math returning an int.</p>
<p>Lets say you want to do a basic age calculation.  How old is Joe?  His birthday is 7/29/1981.  Well you could subtract 1981 from today, then determine if he had a birthday this year, which could mean comparing everything up to the milliseconds.  The problem is, such a calculation is not as accurate as it would seem.  This style method fails to preserve the validity of the passing of leap years, leap seconds, etc.  If you asked how many days old Joe is then your answer would be something like 365 * (current &#8211; 1981) + number of days this year &#8211; number of days between Jan 1 and July 29.  Well you forgot a few leap days in there, at least 5.<br />
<span id="more-106"></span><br />
I don&#8217;t know about you, but inaccurate results bug me.  So I went about researching the correct way to solve this problem.  Turns out that adding through the Calendar add method preserves these little nuances.  The way to solve this is to increment one date until it passes the second date, counting the times it is incremented.</p>
<p>What?!?  But it will take forever to count the number of days that passed between Joe&#8217;s birthday and today!  What if I needed to know the number of hours, seconds, or even worse, milliseconds?  Well we can build in some optimization just for that.</p>
<p>The method I wrote has the following signature <span class="code_line"><code>CalendarUtils.difference(Calendar c1, Calendar c2, int unit);</code></span>.  To figure out Joe&#8217;s age we would call it with something like <span class="code_line"><code>CalendarUtils.difference(birthday, today, Calendar.YEAR);</code></span>.</p>
<p>Enough with the small talk.  Here&#8217;s the code.  It happens to be part of an open source project I work on, <a href="http://code.google.com/p/jexel/">JExel</a>.  Here is the most recent, complete <a href="http://jexel.googlecode.com/svn/Expression/src/com/gadberry/utility/CalendarUtils.java">CalendarUtils.java</a>.</p>
<div class="code_box"><code>
public static long difference(Calendar c1, Calendar c2, int unit) {

	differenceCheckUnit(unit);

	Map&lt;Integer, Long&gt; unitEstimates = differenceGetUnitEstimates();

	Calendar first = (Calendar) c1.clone();
	Calendar last = (Calendar) c2.clone();

	long difference = c2.getTimeInMillis() - c1.getTimeInMillis();

	long unitEstimate = unitEstimates.get(unit).longValue();
	long increment = (long) Math.floor((double) difference / (double) unitEstimate);
	increment = Math.max(increment, 1);

	long total = 0;

	while (increment &gt; 0) {
		add(first, unit, increment);
		if (first.after(last)) {
			add(first, unit, increment * -1);
			increment = (long) Math.floor(increment / 2);
		} else {
			total += increment;
		}
	}

	return total;

}

private static Map&lt;Integer, Long&gt; differenceGetUnitEstimates() {
	Map&lt;Integer, Long&gt; unitEstimates = new HashMap&lt;Integer, Long&gt;();
	unitEstimates.put(Calendar.YEAR, 1000l * 60 * 60 * 24 * 365);
	unitEstimates.put(Calendar.MONTH, 1000l * 60 * 60 * 24 * 30);
	unitEstimates.put(Calendar.DAY_OF_MONTH, 1000l * 60 * 60 * 24);
	unitEstimates.put(Calendar.HOUR_OF_DAY, 1000l * 60 * 60);
	unitEstimates.put(Calendar.MINUTE, 1000l * 60);
	unitEstimates.put(Calendar.SECOND, 1000l);
	unitEstimates.put(Calendar.MILLISECOND, 1l);
	return unitEstimates;
}

private static void differenceCheckUnit(int unit) {
	List&lt;Integer&gt; validUnits = new ArrayList&lt;Integer&gt;();
	validUnits.add(Calendar.YEAR);
	validUnits.add(Calendar.MONTH);
	validUnits.add(Calendar.DAY_OF_MONTH);
	validUnits.add(Calendar.HOUR_OF_DAY);
	validUnits.add(Calendar.MINUTE);
	validUnits.add(Calendar.SECOND);
	validUnits.add(Calendar.MILLISECOND);

	if (!validUnits.contains(unit)) {
		throw new RuntimeException(
				"CalendarUtils.difference one of these units 
				Calendar.YEAR,
				Calendar.MONTH,
				Calendar.DAY_OF_MONTH,
				Calendar.HOUR_OF_DAY,
				Calendar.MINUTE,
				Calendar.SECOND,
				Calendar.MILLISECOND."
				);
	}
}

public static void add(Calendar c, int unit, long increment) {
	while (increment &gt; Integer.MAX_VALUE) {
		c.add(unit, Integer.MAX_VALUE);
		increment -= Integer.MAX_VALUE;
	}
	c.add(unit, (int) increment);
}

</code></div>
<p>You can find the JUnit test cases I run this method through <a href="http://jexel.googlecode.com/svn/Expression/tests/com/gadberry/utility/CalendarUtilsTests.java">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2007/08/17/find-the-difference-between-two-java-dates-calendars/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JExel &#8211; Java Based Expression Language Parser</title>
		<link>http://www.gadberry.com/aaron/2007/07/26/jexel-java-based-expression-language-parser/</link>
		<comments>http://www.gadberry.com/aaron/2007/07/26/jexel-java-based-expression-language-parser/#comments</comments>
		<pubDate>Fri, 27 Jul 2007 03:35:02 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/2007/07/26/jexel-java-based-expression-language-parser/</guid>
		<description><![CDATA[I have published a pet project of mine online recently. After looking at many different project hosting sites I resolved on google code. It seems to have a great interface and amount of space available. The project is called JExel, and is a Java based expression language parser. It&#8217;s not complex to utilize, and can [...]]]></description>
			<content:encoded><![CDATA[<p>I have published a pet project of mine online recently.  After looking at many different project hosting sites I resolved on google code.  It seems to have a great interface and amount of space available.</p>
<p>The project is called JExel, and is a Java based expression language parser.  It&#8217;s not complex to utilize, and can be the perfect plugin library for usage in your larger Java application.  JExel parses string expressions to an object result.  It comes with native boolean, math, string and date functionality.</p>
<p>A boolean expression utilization would look something like <span class="code_line"><code>Expression.evaluateToBoolean("true AND false");</code></span> and, in this case, would return a <span class="code_line"><code>new Boolean(false);</code></span>.</p>
<p>Of course there are also included methods <span class="code_line"><code>evaluateToDouble(String)</code></span> and <span class="code_line"><code>evaluateToString(String)</code></span>.</p>
<p>Additionally there is a plain <span class="code_line"><code>evaluate(String)</code></span> method that returns an Argument.  You can then call getObject() on the resulting Argument and get the actual Object result.</p>
<p>You can expand on the included operators, and write your own to accomplish your own task.  You can provide a Resolver which can resolve string variables found in the expression via your own needs.  Say you had an expression like <span class="code_line"><code>Expression.evaluateToDouble("path/to/variable + otherVariable");</code></span>.  This means if you provide a resolver then you can gain variable resolution relevant to your own project.  Maybe path/to/variable is translated into &#8220;6&#8243; and otherVariable is translated into &#8220;4&#8243;.  Then the result would be 10.</p>
<p>Have fun!  <a href="http://code.google.com/p/jexel/">Start Exploring JExel</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2007/07/26/jexel-java-based-expression-language-parser/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Inject Build Time (timestamp) Property Using Maven</title>
		<link>http://www.gadberry.com/aaron/2007/05/28/inject-build-time-timestamp-property-using-maven/</link>
		<comments>http://www.gadberry.com/aaron/2007/05/28/inject-build-time-timestamp-property-using-maven/#comments</comments>
		<pubDate>Mon, 28 May 2007 19:49:04 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.gadberry.com/aaron/2007/05/28/inject-build-time-timestamp-property-using-maven/</guid>
		<description><![CDATA[In your pom.xml you have the ability to turn on resource filtering that replaces variables in resource files with actual values. These are useful for things like ${pom.name} and ${pom.version}. Your pom.xml section would look something like this&#8230; &#60;build&#62; &#60;resources&#62; &#60;resource&#62; &#60;directory&#62;src/main/resources&#60;/directory&#62; &#60;filtering&#62;true&#60;/filtering&#62; &#60;/resource&#62; &#60;/resources&#62; &#60;/build&#62; And your properties file could contain something like these [...]]]></description>
			<content:encoded><![CDATA[<p>In your pom.xml you have the ability to turn on resource filtering that replaces variables in resource files with actual values.  These are useful for things like ${pom.name} and ${pom.version}.  Your pom.xml section would look something like this&#8230;</p>
<div class="code_box"><code>&lt;build&gt;
  &lt;resources&gt;
    &lt;resource&gt;
      &lt;directory&gt;src/main/resources&lt;/directory&gt;
      &lt;filtering&gt;true&lt;/filtering&gt;
    &lt;/resource&gt;
  &lt;/resources&gt;
&lt;/build&gt;
</code></div>
<p>And your properties file could contain something like these</p>
<div class="code_box"><code># Build Time Information
APPLICATION.NAME=${pom.name}
APPLICATION.VERSION=${pom.version}</code></div>
<p><span id="more-103"></span><br />
There is a list of available properties that you can use here <a href="http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide">http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide</a></p>
<p>Onto the difficult part.  There is no automatic variable that references a current timestamp for use as a buildtime property.  I want a buildtime property available to my webapp so I can see very easily when the currently deployed version was built.</p>
<p>Here is how I accomplished it (it wasn&#8217;t that hard).<br />
There are a few steps to this.</p>
<ol>
<li>Put a placeholder in the properties file.</li>
<li>Replace the placeholder with a timestamp at build time</li>
<li>Remove the updated file to allow the file to be refreshed at the next build time</li>
</ol>
<p>Step 1: Add a property such as <span class="code_line"><code>APPLICATION.BUILDTIME=HOLDER</code></span></p>
<p>Step 2: Include an ant execution in your build.  This is not extremely difficult.  Place a plugin in the plugins tag in the POM.</p>
<div class="code_box"><code>
&lt;plugin&gt;
  &lt;artifactId&gt;maven-antrun-plugin&lt;/artifactId&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;id&gt;set-build-time&lt;/id&gt;
      &lt;phase&gt;process-sources&lt;/phase&gt;
      &lt;configuration&gt;
        &lt;tasks&gt;
          &lt;tstamp&gt;
            &lt;format property="timestamp" pattern="yyyy/MM/dd HH:mm:ss z"/&gt;
          &lt;/tstamp&gt;
          &lt;replaceregexp byline="true"&gt;
            &lt;regexp pattern="APPLICATION\.BUILDTIME=HOLDER" /&gt;
            &lt;substitution expression="APPLICATION.BUILDTIME=${timestamp}" /&gt;
            &lt;fileset dir="src/main/resources/pathToPropertyFileDirectory" includes="*.properties" /&gt;
          &lt;/replaceregexp&gt;
        &lt;/tasks&gt;
      &lt;/configuration&gt;
      &lt;goals&gt;
        &lt;goal&gt;run&lt;/goal&gt;
      &lt;/goals&gt;
    &lt;/execution&gt;
  &lt;/executions&gt;
&lt;/plugin&gt;
</code></div>
<p>This will do a regular expression find and replace on HOLDER with the timestamp.</p>
<p>Step 3: I am using continuum so I must clean up my files before continuing.  I use a post cleanup method, and it looks something like this.  I put this under the profiles tag.</p>
<div class="code_box"><code>&lt;profile&gt;
  &lt;id&gt;cleanProperties&lt;/id&gt;
  &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-antrun-plugin&lt;/artifactId&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;cleanProperties&lt;/id&gt;
            &lt;phase&gt;package&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;run&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
              &lt;tasks&gt;
                &lt;delete dir="./src/main/resources/pathToPropertyFileDirectory" /&gt;
              &lt;/tasks&gt;
            &lt;/configuration&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
&lt;/profile&gt;</code></div>
<p>As a final note, do not forget to include the profile when you build your project.  The flag is -P.</p>
<p>And there you have it.  Since it is a POST cleanup you may have to build twice for it to operator properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gadberry.com/aaron/2007/05/28/inject-build-time-timestamp-property-using-maven/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  www.gadberry.com/aaron/category/computers/feed/ ) in 0.35174 seconds, on Feb 5th, 2012 at 9:17 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 10:17 pm UTC -->
