Learn Java for Android Development: Date and Time Basics
What is a Date or Time, Really?First things first: the date and the time are basically two parts of the same piece of data (a point in time). When it comes to storing dates and times in a computer, it can be helpful to think back to your first computer class and recall that all data on a computer is made up of “ones and zeros”. Computers (and Android devices are no exception) do not really have a sense of time like people do, but instead keep a numeric representation of the current date or time (always ticking forward, one millisecond at a time) and then format this information in different ways to suit specific purposes. After all, a single instant in time is interpreted differently depending upon your time zone or location, whether or not you (or your area) recognize daylight savings, and various other factors.
Add to this fact that dates and times are displayed differently in different cultures and locales. For example, in the United States, we often format our dates like this: April 6th, 1981, or 04/06/1981 whereas in Europe, the day normally precedes the month, like this: 6 April, 1981, or 06/04/1981. Similarly, some countries have the concept of AM and PM with a 12-hour, whereas others simply use a 24-hour clock.
Computers, including Android devices, calculate times and dates as a single number (a long)—which grows as time passes. The number itself equates to the number of milliseconds elapsed since a specific date in the past. In this case, the point in time at which the “time” started ticking is: midnight, January 1, 1970. This mechanism is referred to as Unix time, or POSIX time.
What’s a Developer to Do?Pop quiz! Which of the following strings correctly represents the 4th month of the (Gregorian) calendar year: A, April, APR, Apr, 4, or 04? The answer? All of them. Already, working with dates and times seems a bit complicated, doesn’t it? In fact, we did a quick perusal of all the Java reference books in our office (not insubstantial) and very few cover dates and times in any substantial way. But don’t panic. Just accept the fact that, as a developer, you will have to expend a bit of effort towards satisfying two goals:
1. Your External Goal: To allow the user to work with the date and time formats they are most comfortable with, or at least familiar with.
2. Your Internal Goal: To keep your application code format-independent, so it works everywhere with little hassle.
Now let’s talk a bit about each of these goals.
The External Goal: Be Flexible & Use Standard ControlsHave you ever noticed that few travel websites let the user manually enter date or time information? Instead, they rely upon calendar pickers and fixed day, month and year dropdowns, or, at minimum, enforce a specific date format (usually tied to your language/country, which they ask for in advance). From a user interface perspective, your apps should honor date and time nuances, at least to some extent. However, you should also carefully consider the methods in which the user can enter date and time information. By using standard date and time pickers in your Android apps, such as DatePicker and TimePicker, you effectively limit the data users can input to that which can be easily converted into appropriate date and time structures, without having to parse every known format (not to mention its typos).
The Internal Goal: Keep Your Dates and Times GenericFrom an internal code perspective, your apps should use a generic date/time representation that does not rely on these nuances.
In Java, dates and times are stored in several ways, depending upon your requirements.
- The long type is a primitive data type capable of storing the number of milliseconds elapsed since a specific point in time (Unix time).
- The Date class (java.util.Date) is a utility class for storing date and time in a way that can be reasonably manipulated without having to constantly think about time in terms of milliseconds.
- The Calendar class (java.util.Calendar) is a utility class for working with different calendars, as well as for manipulating date and time information in a variety of ways.
- The GregorianCalendar class (a subclass of java.util.Calendar) is used primarily for date manipulation in the Western hemisphere, were we use a 12-month calendar, with 7 days to a week, and two eras (BC and AD).
Determining the Current Date and TimeThere are a number of ways to determine the current time on an Android device.
You can determine the raw date and time data using the static method provided in the System class (java.lang.System):
- long msTime = System.currentTimeMillis();
- Date curDateTime = new Date(msTime);
long msTime = System.currentTimeMillis(); Date curDateTime = new Date(msTime);This method relies upon the time that the device thinks it is, which may or may not be reliable. Another way to determine the current date and time uses the default constructor for the Date class, which creates a Date object with the current date and time:
- Date anotherCurDate = new Date();
Date anotherCurDate = new Date();There are yet other ways to determine the true exact time—computers frequently check known time-keeping servers to make sure everyone is “in sync”. This process is slightly beyond the scope of this tutorial, but suffice to say, just requesting and receiving the correct time takes some time, which must then be accounted for before synchronization can really be achieved.
(Note: Android devices that connect to cellular services tend to have locale accurate date and time information as this may be used in communications with the radio towers.)
Creating Date and Time Variables from ScratchNow what if you want to create a date or time variable from a specific date, like a birthday. Perhaps you know, just off the top of your head, the number of milliseconds since 1/1/1970 midnight that represents your birthday. In my case, that would be something like 229703700 milliseconds, or the morning of April 12th, 1977 (adjusted for California time). However, as you can see, this is very cumbersome. Really, what you want to do is say: computer, create me a date/time variable representing April 12th, 1977. That’s where the Calendar class comes into play:
- GregorianCalendar bday = new GregorianCalendar(1977, Calendar.APRIL, 12);
GregorianCalendar bday = new GregorianCalendar(1977, Calendar.APRIL, 12);You can use calendar objects to manipulate dates and extract interesting information about them. For example, you could use the get() method to determine the day of the week that I was born upon:
- int dayOfWeek=bday.get(Calendar.DAY_OF_WEEK); // Returns 3, for Tuesday!
int dayOfWeek=bday.get(Calendar.DAY_OF_WEEK); // Returns 3, for Tuesday!Note that the months of the calendar are 0-based, so January is month 0, not month 1, and therefore April is month 3, not 4. Finally, you can extract a Date object from a Calendar date configuration using the getTime() method.
Formatting Date and Time DataYou can use the helper class called DateFormat (java.text.DateFormat) to convert raw date and time information into different String formats (for different locales, etc.) or to parse String information into its appropriate date and time bits for use in code.
For example, you can use the SimpleDateFormat class (a subclass of the DateFormat class) to create a custom string containing date and time information. First, you must specify your format string, using the appropriate codes for the different bits of information (see the SimpleDateFormat documentation for details on individual codes). Then you apply that information to a specific date or time. For example:
- Date anotherCurDate = new Date();
- SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMMM d 'at' hh:mm a 'in the year' yyyy G");
Date anotherCurDate = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMMM d 'at' hh:mm a 'in the year' yyyy G"); String formattedDateString = formatter.format(anotherCurDate);If you were to print the String called formattedDateString, you might see something like: “Monday, December 6 at 08:34 AM in the year 2010 AD”.
Incidentally, you can also use the DateFormat and SimpleDateFormat classes to parse date and time strings into the appropriate Date class. Hopefully, you won’t spend a lot of time parsing user-entered dates (which, generally, is quite annoying), but having a parsing mechanism is useful. For example, you might want to parse timestamps from an XML file, where you control or know the format of the timestamp in advance, and can therefore generate the appropriate format string to parse with.
Displaying Date and Time Information to the UserThere are numerous ways to display date and time information to the user. The way you choose depends upon your requirements.
Perhaps the simplest way is to simply display a specific date or time as a properly formatted string. This method makes the most sense for fixed dates or times, such as birthdays or events. Simply use the DateFormat utility class to create the appropriate string and display it on the screen as you would any other text (such as within a TextView control).
To show the time passing “in real time”, you can use either the AnalogClock (see figure) or DigitalClock controls.