So you've got a FileTime object but it looks like this when you print it out:

2021-03-04T18:50:21.268968Z

And you realize that output isn't suitable for any self-respecting UI. So you need to format the FileTime object to something that looks cool.

In this guide, I'll show you how to make it look cool.

But alas, it's not as easy as it should be. You'll see that if you keep reading.

(I hope you keep reading.)

In an Instant

First up: translate that FileTime object to an Instant.

What the yark is an Instant, you say? It's a single point in time. 

As in: like just a dot on the timeline of infinity that begins at midnight on January 1, 1970.

But you're gonna need that instant in time if you want to get some decent formatting on that thing.

Stay with me here.

Let's say you've got a FileTime object called fileTime. You can easily convert it to an Instant as follows:

Instant ins = fileTime.toInstant()

But that's just gonna get you that little point in time. Not something you want to display on a user-friendly UI.

End Zone

So convert that Instant to a ZonedDateTime. As the name implies, that's going to give you a date-time object for a specific time zone.

Here's how to get a ZonedDateTime object from an Instant:

ZonedDateTime zonedDateTime = fileTime
                                .toInstant()
                                .atZone(ZoneId.systemDefault());

The Instant object gives you access to an atZone() method that instantiates a ZonedDateTime object. You'll need to provide the timezone ID, of course.

The code above uses the timezone ID generated by ZoneId.systemDefault(). That's going to give you the timezone of your development workstation.

Now if you print out the ZonedDateTime object, you'll see something like this:

2021-03-04T13:50:21.268968-05:00[America/New_York]

So you've got the timezone, but that's still not good enough for a decent UI. 

For starters, the date-time output is too long.

Secondly, users don't need to see their own timezones. Hopefully, they already know what timezone they're living in.

Going Local

Convert that ZonedDateTime object into a LocalDateTime object.

LocalDateTime localDateTime = fileTime
                                .toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDateTime();

Note the toLocalDateTime() method at the end. That's going to handle the translation.

Now if you print out that object, you'll see this:

2021-03-04T13:50:21.268968

Okay, you're getting closer. But that's still not a decent format for a UI.

For starters, the fractional seconds after the decimal point are probably unnecessary for even the most punctual of your users.

Secondly, they won't understand the "T" that separates the date from the time. 

(In case, you're unaware, it's an ISO 8601 standard used to separate the date and time. But it still looks ugly to users who don't know about the ISO 8601 standard.)

A Pattern in Time

Now that you have the LocalDateTime object, you need to format it into a presentable String object. Start by using DateTimeFormatter.

final DateTimeFormatter pattern = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");

That's pretty self-explanatory. The code above instantiates the DateTimeFormatter object using a String pattern that follows the typical American style of displaying a date and time together.

If you'd like to futz around with the String in the ofPattern() static method, you're welcome to do so. Feel free to look at the date and time patterns that you can use.

Keep in mind: that code just creates a formatter. It doesn't do anything with it.

Here's how you use it:

String formattedDate = localDateTime.format(pattern);

Now if you print out that String object, you'll get this:

03/04/2021 13:50:21

And that's much more readable for your end users.

Wrapping It Up

Congratulations! You now know how to format a FileTime object with Java NIO.

Now start using what you've learned. And adapt it to your own requirements.

Have fun!

Photo by cottonbro from Pexels