Android working with time

Modern date and time handling in all Android versions (without sugar)

Working with time in Android has always been tricky. People have been using either third party libraries (e.g. Joda-Time, ThreeTenBp) or had to work with the built-in time classes (such as Calendar). The built-in classes, although available in all Android versions, had a not-so-great API, were mutable (so not thread-safe), and timezone handling was a pain (ref).

In the latest Android Gradle plugin release (v.4.0.0+), «Java 8+ API desugaring support» was introduced. In plain language, we can use some Java 8 APIs and the plugin will translate those APIs to Android-compatible Java behind the scenes that can be used in all Android versions without requiring a minimum API level!

In general, Kotlin provides its Collections and Stream API replacements which are superior to Java’s in my opinion. So from the list of Java 8 APIs, I think that only the excellent java.time API is interesting for a Kotlin developer. Finally, a nice date/time API that can be used in Android!

Note that this «desugaring» process might cost a few extra KB in your APK/AAB. But if that’s not a deal-breaker for your case, you should consider using the newer APIs.

Set up

You would need to modify your build.gradle files. More details (and up-to-date version codes) in the official doc.

Meet the classes

The time API is quite comprehensive and the complete exploration of the API is outside of the scope of this post. But, I want to introduce what I believe the main classes you probably going to need most of the time.

Instant

Instant is a point in time. Can be considered equivalent to a timestamp, if you are familiar with that term.

LocalTime, LocalDate, LocalDateTime

Each class represents the time, date, date+time respectively, without a timezone. Most people when thinking about date/time think in these terms anyway.

ZoneOffset, ZoneId

These are used to work with timezones. You would need one of those to convert a Local* to an Instant .

ZonedDateTime

You probably guessed it. This is what you get when combine a LocalDateTime with a ZoneId . This can be converted to an Instant .

Playing with date and time

These APIs provide intuitive and consistent ways to manipulate date and time. Remember that all objects are immutable, so a new object is created every time that a manipulation takes place (which is a good thing). Some useful examples follow.

Multiple ways to initialize time objects. Get the start date+time of a day defined by a LocalDate Get what date+time is now in Los Angeles. Get a point in time in various forms. Get the same day, 1 week earlier. There are available methods for every time unit.

Formatting

Just note that the formatters you are used to in Android, such as SimpleDateFormat , cannot be used with Java Time API. The API comes with its own formatters, such as DateTimeFormatter .

Enjoy a modern date/time API in your Android development life 🙂

Источник

Learn Java for Android Development: Date and Time Basics

In this tutorial, you’ll learn to work with dates and times in Java and within Android applications. Date and time data can be determined, modified, and stored in a variety of ways.

Android applications are written in the Java, a programming language. Java has a number of primitive data types for different kinds of numbers (integers, floats, etc.), Boolean values, and single characters. Java also includes numerous classes for storing, formatting and modifying date and time data for use within your Android applications. In this tutorial, you’ll learn how to determine the current date and time, store date and time data and display it in a number of ways.

What You’ll Need

Technically, you don’t need any tools to complete this tutorial but you will certainly need them to develop Android applications.

To develop Android applications (or any Java applications, for that matter), you need a development environment to write and build applications. Eclipse is a very popular development environment (IDE) for Java and the preferred IDE for Android development. It’s freely available for Windows, Mac, and Linux operating systems.

Читайте также:  Vlc для андроид настройка сети

For complete instructions on how to install Eclipse (including which versions are supported) and the Android SDK, see the Android developer website.

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 Controls

Have 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 Generic

From 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 Time

There 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):

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:

Читайте также:  Как убрать автоблокировку с андроида

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 Scratch

Now 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:

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:

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 Data

You 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:

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 User

There 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.

Tip: Looking for a timer? Check out the Chronometer control.

Wrapping Up

Dates and times are important data types that Java developers inevitably must work with. Internally, devices store date and time information numerically, but users interpret this information in different ways and using different formats. Keep these nuances under control by limiting the ways users can input dates and times using built-in picker controls and ensure your code uses a generic representation of this information, for example using one of the many classes available for storing date and time information.

Источник

Handling dates on Android

Is Core Library Desugaring the holy grail?

As a mobile developer you most probably had to parse dates and maybe even consider different time zones and daylight saving times. Many apps still make use of java.util.Date, java.util.Calendar and java.text.SimpleDateFormat classes. These are legacy classes with a long history in the Java world, which were replaced with the Date and Time API (JSR-310) in Java 8.

Disclaimer: This article is not a tutorial on how to implement different Date / Time libraries. The goal is to compare the current options and give advice on which to choose.

Time to switch

If your minSDK is below 26 (Android 8.0) you can’t simply use Java 8 APIs. Since most apps probably have to support older Android versions for some years, I will show you current alternatives, their impact on dex count, APK size and other pros and cons.

Читайте также:  Качество сотовой связи андроид

Let’s meet the candidates

1. Java 6/7 Date API (e.g. java.util.Date, java.util.Calendar)

This is the legacy Java API available on all Android versions. Here is a short overview of some of the drawbacks and design problems of this API:

  • Date is instant in time, doesn’t represent an actual date (no time zone, no format, no calendar system)
  • Classes are mutable, no thread-safety, Calendar class is not type safe
  • Unintuitive API (month is zero indexed, DayOfWeek != ISO 8601, lenient by default, implicit usage of the system-local)

There are more detailed articles about the issues of java.util.Date.

2. JodaTime (JodaTime Android)

JodaTime is a third-party replacement for the Java date and time classes and was the standard library for Java prior to JSR-310. There is a special Android variant of this library, which improves the timezone db loading. This library is only added to the list, because some apps still use it. You probably don’t want to use JodaTime in new projects.

3. ThreeTenBP (ThreeTenABP)

ThreeTen is a project within the Java Community Process program that integrates JSR-310 into Java and was included in Java 8 as java.time. There is a backport (BP) to allow developers on Java 7 to access an API that is mostly the same as the one in Java 8. There is also a special Android variant of this library which improves handling the timezone db (similar to JodaTime Android). Since the class names and API of ThreeTenBP is basically the same as Java 8 java.time you are able to switch between ThreeTenBP and java.time by just changing the imports.

4. Core Library Desugaring

This is the latest approach of Google to allow developers to access some of the Java 8 features (including the Date and Time API) even when using minSDK 25 or lower. By using Core Library Desugaring, the bytecode that the runtime needs to use certain Java 8 APIs is delivered as part of the APK ( j$ package inside your dex file). If you reach minSDK 26 in the future you can simply remove the library desugaring to use the build-in Java 8 APIs.

5. kotlinx-datetime

The Kotlin team tries to make life easier for Kotlin and especially KMM developers. That’s why they are working on a basic Kotlin date/time library, with a convenient API and features like build in extension functions. We can use this in plain Android projects as well. kotlinx-datetime uses the java.time API internally on the JVM, so we need to enable core library desugaring to use it. The project is currently in an early development state (0.1.0) and doesn‘t comply with all ISO8601 standards. It’s also lacking formatting functionality.

Impact on the artifact

I created a simple open source sample app, using each library, to compare the impact on the final app artifact. The app has some basic use-cases like showing a countdown for next Sunday 19:00:00 Central European Time (CET) and parsing different ISO 8601 date strings.

As you can see from my comparison, core library desugaring has a noticeable footprint. There are several reasons. The desugaring process currently adds the Java 8 util.stream and util.concurrent packages to the APK (

3K methods) even if you don’t make use of it (D8/R8 doesn’t shrink them). There is an issue in the issue tracker about this. Also the desugaring relies on multidex, even if your total dexcount is below 64K. This slightly increases the APK size, so in the end the app is larger than with JodaTime or ThreeTenABP (even though these libraries ship their own timezone db).

Conclusion

Core library desugaring is a big step forward making our life as Android developers easier. We can finally use the Java 8 Date API and no longer need to rely on 3rd party libraries (even though they are really close to the language APIs). This also allows us to use kotlinx-datetime within KMM or Android only projects in the future.

So you should definitely try out core library desugaring. We at NanoGiants already migrated our apps and haven’t run into any issues (you should enable R8 to avoid issues on API 23).

The comparison also shows that the libraries have different impact on the final app size and method count. If you care about minimal size, it’s maybe worth to stick to ThreeTenABP for a little longer. Also migrating from ThreeTenABP to Java 8 later on is absolutely straightforward — as the API is the same and you just need to change your imports.

Источник

Оцените статью