diff options
Diffstat (limited to 'src/metadata/MetadataDateTime.vala')
-rw-r--r-- | src/metadata/MetadataDateTime.vala | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/metadata/MetadataDateTime.vala b/src/metadata/MetadataDateTime.vala new file mode 100644 index 0000000..9dae99b --- /dev/null +++ b/src/metadata/MetadataDateTime.vala @@ -0,0 +1,78 @@ +public errordomain MetadataDateTimeError { + INVALID_FORMAT, + UNSUPPORTED_FORMAT +} + +public class MetadataDateTime { + + private DateTime timestamp; + + public MetadataDateTime(DateTime timestamp) { + this.timestamp = timestamp; + } + + public MetadataDateTime.from_exif(string label) throws MetadataDateTimeError { + if (!from_exif_date_time(label, out timestamp)) + throw new MetadataDateTimeError.INVALID_FORMAT("%s is not EXIF format date/time", label); + } + + public MetadataDateTime.from_iptc(string date, string time) throws MetadataDateTimeError { + // TODO: Support IPTC date/time format + throw new MetadataDateTimeError.UNSUPPORTED_FORMAT("IPTC date/time format not currently supported"); + } + + public MetadataDateTime.from_xmp(string label) throws MetadataDateTimeError { + var dt = new DateTime.from_iso8601(label, null); + if (dt == null) + throw new MetadataDateTimeError.INVALID_FORMAT("%s is not XMP format date/time", label); + + timestamp = dt; + } + + public DateTime? get_timestamp() { + return timestamp; + } + + public string get_exif_label() { + return to_exif_date_time(timestamp); + } + + // TODO: get_iptc_date() and get_iptc_time() + + public string get_xmp_label() { + return timestamp.format_iso8601(); + } + + public static bool from_exif_date_time(string date_time, out DateTime? timestamp) { + timestamp = null; + + Time tm = Time(); + + // Check standard EXIF format + if (date_time.scanf("%d:%d:%d %d:%d:%d", + &tm.year, &tm.month, &tm.day, &tm.hour, &tm.minute, &tm.second) != 6) { + // Fallback in a more generic format + string tmp = date_time.dup(); + tmp.canon("0123456789", ' '); + if (tmp.scanf("%4d%2d%2d%2d%2d%2d", + &tm.year, &tm.month, &tm.day, &tm.hour, &tm.minute,&tm.second) != 6) + return false; + } + + // watch for bogosity + if (tm.year <= 1900 || tm.month <= 0 || tm.day < 0 || tm.hour < 0 || tm.minute < 0 || tm.second < 0) + return false; + + timestamp = new DateTime.local(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); + + return true; + } + + public static string to_exif_date_time(DateTime timestamp) { + return timestamp.to_local().format("%Y:%m:%d %H:%M:%S"); + } + + public string to_string() { + return to_exif_date_time(timestamp); + } +} |