One for Java programmers who work with music files; MP4 files to be precise. MP4 is a popular file format; it's the default choice used by iTunes, so it's extensively used. MP4 is a container format which means it is capable of containing multiple data streams (audio, video etc) as well as metadata about those streams. It's an aspect of that metadata that's the subject of this blog post.
MP4 supports multiple different metadata fields
and a commonly used one is @day
. @day
stores a representation of the time at which
a given surrounding musical release was released. I used my words carefully there. In the world of music file
tagging, such tags normally simply store the year of release, however any timestamp is allowable. As I write the music tagger
bliss, I am exposed to an enormous number of MP4 files which means an
enormous amount of variance in what data I see stored.
I recently received a bug report where bliss's file organisation rule had named folders according to a given album's year of release, but the folder name ended up being:
/2013-05-17T070000Z/[album name...]
It turns out that the @day
field can
store more than just a year, it can store an entire timestamp, down to the second!
To this end I set out to create a
SimpleDateFormat
pattern that could parse these strings and return the actual year of release. Here's my first attempt:
yyyy-MM-dd'T'HHmmss'Z'
This parses the date above correctly, with T
and Z
being literals.
The trouble with this is it doesn't support shorter timestamps. The timestamp above is in
ISO 8601 format which means portions of the timestamp could be removed. SimpleDateFormat
does not support partial matching. However, by using Apache Commons
DateUtils
it was
simple to construct a set of fallbacks:
Date date = DateUtils.parseDate(yearVal, new String[] { "yyyy-MM", "yyyy-MM-dd", "yyyy-MM-dd'T'HHmmss'Z'" });
With a preliminary guard to catch simple four digit year values and a catch of any ParseException
s
to identify future date patterns I should be aware of, that made bliss's file organisation code more tolerant of
differing @day
values (or, indeed, "year" fields in any music file format). Hope that helps you!
Thanks to Gideon Burton who made the the image above available for sharing.