1f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// =================================================================================================
2f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// ADOBE SYSTEMS INCORPORATED
3f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// Copyright 2006 Adobe Systems Incorporated
4f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// All Rights Reserved
5f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//
6f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
7f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// of the Adobe license agreement accompanying it.
8f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// =================================================================================================
9f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
10f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingpackage com.adobe.xmp.impl;
11f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
12f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.util.Calendar;
13f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.util.Date;
14f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.util.GregorianCalendar;
15f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.util.Locale;
16f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.util.TimeZone;
17f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
18f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport com.adobe.xmp.XMPDateTime;
19f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport com.adobe.xmp.XMPException;
20f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
21f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
22f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling/**
23f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * The implementation of <code>XMPDateTime</code>. Internally a <code>calendar</code> is used
24f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * plus an additional nano seconds field, because <code>Calendar</code> supports only milli
25f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * seconds. The <code>nanoSeconds</code> convers only the resolution beyond a milli second.
26f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling *
27f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * @since 16.02.2006
28f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling */
29f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingpublic class XMPDateTimeImpl implements XMPDateTime
30f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling{
31f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
32f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int year = 0;
33f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
34f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int month = 0;
35f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
36f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int day = 0;
37f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
38f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int hour = 0;
39f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
40f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int minute = 0;
41f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
42f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int second = 0;
43f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** Use the unversal time as default */
44f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private TimeZone timeZone = TimeZone.getTimeZone("UTC");
45f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
46f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * The nano seconds take micro and nano seconds, while the milli seconds are in the calendar.
47f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
48f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int nanoSeconds;
49f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
50f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
51f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
52f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Creates an <code>XMPDateTime</code>-instance with the current time in the default time
53f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * zone.
54f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
55f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public XMPDateTimeImpl()
56f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
57f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		// EMPTY
58f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
59f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
60f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
61f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
62f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Creates an <code>XMPDateTime</code>-instance from a calendar.
63f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
64f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param calendar a <code>Calendar</code>
65f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
66f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public XMPDateTimeImpl(Calendar calendar)
67f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
68f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		// extract the date and timezone from the calendar provided
69f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        Date date = calendar.getTime();
70f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        TimeZone zone = calendar.getTimeZone();
71f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
72f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        // put that date into a calendar the pretty much represents ISO8601
73f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        // I use US because it is close to the "locale" for the ISO8601 spec
74f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        GregorianCalendar intCalendar =
75f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        	(GregorianCalendar) Calendar.getInstance(Locale.US);
76f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        intCalendar.setGregorianChange(new Date(Long.MIN_VALUE));
77f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        intCalendar.setTimeZone(zone);
78f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling        intCalendar.setTime(date);
79f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
80f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.year = intCalendar.get(Calendar.YEAR);
81f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.month = intCalendar.get(Calendar.MONTH) + 1; // cal is from 0..12
82f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.day = intCalendar.get(Calendar.DAY_OF_MONTH);
83f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.hour = intCalendar.get(Calendar.HOUR_OF_DAY);
84f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.minute = intCalendar.get(Calendar.MINUTE);
85f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.second = intCalendar.get(Calendar.SECOND);
86f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.nanoSeconds = intCalendar.get(Calendar.MILLISECOND) * 1000000;
87f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.timeZone = intCalendar.getTimeZone();
88f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
89f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
90f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
91f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
92f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Creates an <code>XMPDateTime</code>-instance from
93f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * a <code>Date</code> and a <code>TimeZone</code>.
94f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
95f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param date a date describing an absolute point in time
96f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param timeZone a TimeZone how to interpret the date
97f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
98f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public XMPDateTimeImpl(Date date, TimeZone timeZone)
99f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
100f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		GregorianCalendar calendar = new GregorianCalendar(timeZone);
101f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.setTime(date);
102f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.year = calendar.get(Calendar.YEAR);
103f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.month = calendar.get(Calendar.MONTH) + 1; // cal is from 0..12
104f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.day = calendar.get(Calendar.DAY_OF_MONTH);
105f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.hour = calendar.get(Calendar.HOUR_OF_DAY);
106f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.minute = calendar.get(Calendar.MINUTE);
107f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.second = calendar.get(Calendar.SECOND);
108f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.nanoSeconds = calendar.get(Calendar.MILLISECOND) * 1000000;
109f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.timeZone = timeZone;
110f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
111f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
112f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
113f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
114f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Creates an <code>XMPDateTime</code>-instance from an ISO 8601 string.
115f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
116f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param strValue an ISO 8601 string
117f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @throws XMPException If the string is a non-conform ISO 8601 string, an exception is thrown
118f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
119f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public XMPDateTimeImpl(String strValue) throws XMPException
120f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
121f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		ISO8601Converter.parse(strValue, this);
122f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
123f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
124f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
125f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
126f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getYear()
127f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
128f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getYear()
129f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
130f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return year;
131f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
132f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
133f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
134f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
135f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setYear(int)
136f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
137f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setYear(int year)
138f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
139f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.year = Math.min(Math.abs(year), 9999);
140f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
141f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
142f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
143f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
144f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getMonth()
145f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
146f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getMonth()
147f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
148f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return month;
149f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
150f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
151f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
152f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
153f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setMonth(int)
154f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
155f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setMonth(int month)
156f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
157f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (month < 1)
158f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
159f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.month = 1;
160f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
161f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else if (month > 12)
162f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
163f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.month = 12;
164f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
165f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else
166f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
167f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.month = month;
168f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
169f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
170f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
171f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
172f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
173f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getDay()
174f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
175f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getDay()
176f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
177f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return day;
178f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
179f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
180f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
181f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
182f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setDay(int)
183f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
184f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setDay(int day)
185f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
186f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (day < 1)
187f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
188f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.day = 1;
189f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
190f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else if (day > 31)
191f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
192f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.day = 31;
193f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
194f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else
195f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
196f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.day = day;
197f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
198f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
199f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
200f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
201f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
202f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getHour()
203f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
204f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getHour()
205f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
206f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return hour;
207f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
208f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
209f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
210f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
211f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setHour(int)
212f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
213f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setHour(int hour)
214f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
215f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.hour = Math.min(Math.abs(hour), 23);
216f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
217f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
218f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
219f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
220f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getMinute()
221f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
222f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getMinute()
223f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
224f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return minute;
225f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
226f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
227f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
228f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
229f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setMinute(int)
230f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
231f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setMinute(int minute)
232f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
233f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.minute = Math.min(Math.abs(minute), 59);
234f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
235f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
236f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
237f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
238f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getSecond()
239f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
240f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getSecond()
241f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
242f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return second;
243f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
244f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
245f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
246f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
247f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setSecond(int)
248f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
249f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setSecond(int second)
250f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
251f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.second = Math.min(Math.abs(second), 59);
252f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
253f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
254f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
255f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
256f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getNanoSecond()
257f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
258f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int getNanoSecond()
259f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
260f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return nanoSeconds;
261f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
262f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
263f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
264f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
265f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setNanoSecond(int)
266f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
267f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setNanoSecond(int nanoSecond)
268f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
269f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.nanoSeconds = nanoSecond;
270f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
271f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
272f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
273f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
274f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see Comparable#compareTo(Object)
275f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
276f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int compareTo(Object dt)
277f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
278f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		long d = getCalendar().getTimeInMillis()
279f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				- ((XMPDateTime) dt).getCalendar().getTimeInMillis();
280f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (d != 0)
281f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
282f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			return (int) (d % 2);
283f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
284f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else
285f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
286f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			// if millis are equal, compare nanoseconds
287f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			d = nanoSeconds - ((XMPDateTime) dt).getNanoSecond();
288f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			return (int) (d % 2);
289f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
290f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
291f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
292f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
293f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
294f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getTimeZone()
295f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
296f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public TimeZone getTimeZone()
297f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
298f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return timeZone;
299f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
300f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
301f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
302f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
303f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#setTimeZone(TimeZone)
304f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
305f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void setTimeZone(TimeZone timeZone)
306f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
307f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.timeZone = timeZone;
308f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
309f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
310f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
311f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
312f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getCalendar()
313f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
314f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public Calendar getCalendar()
315f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
316f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance(Locale.US);
317f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.setGregorianChange(new Date(Long.MIN_VALUE));
318f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.setTimeZone(timeZone);
319f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.YEAR, year);
320f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.MONTH, month - 1);
321f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.DAY_OF_MONTH, day);
322f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.HOUR_OF_DAY, hour);
323f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.MINUTE, minute);
324f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.SECOND, second);
325f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		calendar.set(Calendar.MILLISECOND, nanoSeconds / 1000000);
326f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return calendar;
327f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
328f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
329f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
330f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
331f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @see XMPDateTime#getISO8601String()
332f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
333f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public String getISO8601String()
334f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
335f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return ISO8601Converter.render(this);
336f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
337f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
338f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
339f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
340f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns the ISO string representation.
341f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
342f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public String toString()
343f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
344f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return getISO8601String();
345f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
346f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling}