blob: f3a17e7ca4e067c29adf0443f700bf8318cede10 [file] [log] [blame]
// =================================================================================================
// ADOBE SYSTEMS INCORPORATED
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
// of the Adobe license agreement accompanying it.
// =================================================================================================
package com.adobe.xmp.impl;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import com.adobe.xmp.XMPDateTime;
import com.adobe.xmp.XMPException;
/**
* The implementation of <code>XMPDateTime</code>. Internally a <code>calendar</code> is used
* plus an additional nano seconds field, because <code>Calendar</code> supports only milli
* seconds. The <code>nanoSeconds</code> convers only the resolution beyond a milli second.
*
* @since 16.02.2006
*/
public class XMPDateTimeImpl implements XMPDateTime
{
/** */
private int year = 0;
/** */
private int month = 0;
/** */
private int day = 0;
/** */
private int hour = 0;
/** */
private int minute = 0;
/** */
private int second = 0;
/** Use the unversal time as default */
private TimeZone timeZone = TimeZone.getTimeZone("UTC");
/**
* The nano seconds take micro and nano seconds, while the milli seconds are in the calendar.
*/
private int nanoSeconds;
/**
* Creates an <code>XMPDateTime</code>-instance with the current time in the default time
* zone.
*/
public XMPDateTimeImpl()
{
// EMPTY
}
/**
* Creates an <code>XMPDateTime</code>-instance from a calendar.
*
* @param calendar a <code>Calendar</code>
*/
public XMPDateTimeImpl(Calendar calendar)
{
// extract the date and timezone from the calendar provided
Date date = calendar.getTime();
TimeZone zone = calendar.getTimeZone();
// put that date into a calendar the pretty much represents ISO8601
// I use US because it is close to the "locale" for the ISO8601 spec
GregorianCalendar intCalendar =
(GregorianCalendar) Calendar.getInstance(Locale.US);
intCalendar.setGregorianChange(new Date(Long.MIN_VALUE));
intCalendar.setTimeZone(zone);
intCalendar.setTime(date);
this.year = intCalendar.get(Calendar.YEAR);
this.month = intCalendar.get(Calendar.MONTH) + 1; // cal is from 0..12
this.day = intCalendar.get(Calendar.DAY_OF_MONTH);
this.hour = intCalendar.get(Calendar.HOUR_OF_DAY);
this.minute = intCalendar.get(Calendar.MINUTE);
this.second = intCalendar.get(Calendar.SECOND);
this.nanoSeconds = intCalendar.get(Calendar.MILLISECOND) * 1000000;
this.timeZone = intCalendar.getTimeZone();
}
/**
* Creates an <code>XMPDateTime</code>-instance from
* a <code>Date</code> and a <code>TimeZone</code>.
*
* @param date a date describing an absolute point in time
* @param timeZone a TimeZone how to interpret the date
*/
public XMPDateTimeImpl(Date date, TimeZone timeZone)
{
GregorianCalendar calendar = new GregorianCalendar(timeZone);
calendar.setTime(date);
this.year = calendar.get(Calendar.YEAR);
this.month = calendar.get(Calendar.MONTH) + 1; // cal is from 0..12
this.day = calendar.get(Calendar.DAY_OF_MONTH);
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
this.nanoSeconds = calendar.get(Calendar.MILLISECOND) * 1000000;
this.timeZone = timeZone;
}
/**
* Creates an <code>XMPDateTime</code>-instance from an ISO 8601 string.
*
* @param strValue an ISO 8601 string
* @throws XMPException If the string is a non-conform ISO 8601 string, an exception is thrown
*/
public XMPDateTimeImpl(String strValue) throws XMPException
{
ISO8601Converter.parse(strValue, this);
}
/**
* @see XMPDateTime#getYear()
*/
public int getYear()
{
return year;
}
/**
* @see XMPDateTime#setYear(int)
*/
public void setYear(int year)
{
this.year = Math.min(Math.abs(year), 9999);
}
/**
* @see XMPDateTime#getMonth()
*/
public int getMonth()
{
return month;
}
/**
* @see XMPDateTime#setMonth(int)
*/
public void setMonth(int month)
{
if (month < 1)
{
this.month = 1;
}
else if (month > 12)
{
this.month = 12;
}
else
{
this.month = month;
}
}
/**
* @see XMPDateTime#getDay()
*/
public int getDay()
{
return day;
}
/**
* @see XMPDateTime#setDay(int)
*/
public void setDay(int day)
{
if (day < 1)
{
this.day = 1;
}
else if (day > 31)
{
this.day = 31;
}
else
{
this.day = day;
}
}
/**
* @see XMPDateTime#getHour()
*/
public int getHour()
{
return hour;
}
/**
* @see XMPDateTime#setHour(int)
*/
public void setHour(int hour)
{
this.hour = Math.min(Math.abs(hour), 23);
}
/**
* @see XMPDateTime#getMinute()
*/
public int getMinute()
{
return minute;
}
/**
* @see XMPDateTime#setMinute(int)
*/
public void setMinute(int minute)
{
this.minute = Math.min(Math.abs(minute), 59);
}
/**
* @see XMPDateTime#getSecond()
*/
public int getSecond()
{
return second;
}
/**
* @see XMPDateTime#setSecond(int)
*/
public void setSecond(int second)
{
this.second = Math.min(Math.abs(second), 59);
}
/**
* @see XMPDateTime#getNanoSecond()
*/
public int getNanoSecond()
{
return nanoSeconds;
}
/**
* @see XMPDateTime#setNanoSecond(int)
*/
public void setNanoSecond(int nanoSecond)
{
this.nanoSeconds = nanoSecond;
}
/**
* @see Comparable#compareTo(Object)
*/
public int compareTo(Object dt)
{
long d = getCalendar().getTimeInMillis()
- ((XMPDateTime) dt).getCalendar().getTimeInMillis();
if (d != 0)
{
return (int) (d % 2);
}
else
{
// if millis are equal, compare nanoseconds
d = nanoSeconds - ((XMPDateTime) dt).getNanoSecond();
return (int) (d % 2);
}
}
/**
* @see XMPDateTime#getTimeZone()
*/
public TimeZone getTimeZone()
{
return timeZone;
}
/**
* @see XMPDateTime#setTimeZone(TimeZone)
*/
public void setTimeZone(TimeZone timeZone)
{
this.timeZone = timeZone;
}
/**
* @see XMPDateTime#getCalendar()
*/
public Calendar getCalendar()
{
GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance(Locale.US);
calendar.setGregorianChange(new Date(Long.MIN_VALUE));
calendar.setTimeZone(timeZone);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.MILLISECOND, nanoSeconds / 1000000);
return calendar;
}
/**
* @see XMPDateTime#getISO8601String()
*/
public String getISO8601String()
{
return ISO8601Converter.render(this);
}
/**
* @return Returns the ISO string representation.
*/
public String toString()
{
return getISO8601String();
}
}