diff --git a/src/uws/ISO8601Format.java b/src/uws/ISO8601Format.java
index fab1cc0764870375c9b4af55745a039d5830d940..597e0faa25ba3b057be14e502a476c8b777c88a5 100644
--- a/src/uws/ISO8601Format.java
+++ b/src/uws/ISO8601Format.java
@@ -1,5 +1,24 @@
 package uws;
 
+/*
+ * This file is part of UWSLibrary.
+ * 
+ * UWSLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * UWSLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Copyright 2014-2015 - Astronomisches Rechen Institut (ARI)
+ */
+
 import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.util.Calendar;
@@ -32,16 +51,51 @@ import java.util.regex.Pattern;
  * 	{@link TimeZone#getAvailableIDs()}.
  * </p>
  * 
- *  <h3>Date parsing</h3>
+ * <h3>Date parsing</h3>
  *  
- *  <p>
- *    This class is able to parse dates - with the function {@link #parse(String)} - formatted strictly in ISO8601
- *    but is also more permissive. Particularly, separators (like '-' and ':') are optional. The date and time separator
- *    ('T') can be replaced by a space.
- *  </p>
+ * <p>
+ * 	This class is able to parse dates - with the function {@link #parse(String)} - formatted in ISO-8601.
+ * 	This parser allows the following general syntaxes:
+ * </p>
+ * <ul>
+ * 	<li>YYYY (e.g. 2015)</li>
+ * 	<li>YYYY-MM (e.g. 2015-12)</li>
+ * 	<li>YYYY-MM-DD (e.g. 2015-12-11)</li>
+ * 	<li>YYYY-MM-DD'T'hh:mmTZD (e.g. 2015-12-11T20:28+01:00 or 2015-12-11T19:28Z)</li>
+ * 	<li>YYYY-MM-DD'T'hh:mm:ssTZD (e.g. 2015-12-11T20:28:30+01:00 or 2015-12-11T19:28:30Z)</li>
+ * 	<li>YYYY-MM-DD'T'hh:mm:ss.sTZD (e.g. 2015-12-11T20:28:30.45+01:00 or 2015-12-11T19:28:30.45Z)</li>
+ * </ul>
+ * <p>Where:</p>
+ * <ul>
+ * 	<li>YYYY = four-digit year</li>
+ * 	<li>MM   = two-digit month (01=January, etc.)</li>
+ * 	<li>DD   = two-digit day of month (01 through 31)</li>
+ * 	<li>hh   = two digits of hour (00 through 23) (am/pm NOT allowed)</li>
+ * 	<li>mm   = two digits of minute (00 through 59)</li>
+ * 	<li>ss   = two digits of second (00 through 59)</li>
+ * 	<li>s    = one or more digits representing a decimal fraction of a second (i.e. milliseconds)</li>
+ * 	<li>TZD  = time zone designator (Z or +hh:mm or -hh:mm)</li>
+ * </ul>
+ * 
+ * <p>
+ * 	It is also possible to express the date in weeks with the following syntax: YYYY-'W'ww-D
+ * 	(e.g. 2015-W50, 2015-W50-5, 2015-W50-5T20:28:30.45+01:00). <code>ww</code> must a 2 digits number between
+ * 	1 and the number of weeks available in the chosen year. <code>D</code> corresponds to the day
+ * 	of the week: Monday = 1, Tuesday = 2, ..., Sunday = 7.
+ * </p>
+ * 
+ * <p>
+ * 	A last representation of the date is possible: in days of year: YYYY-DDD
+ * 	(e.g. 2015-345, 2015-345T20:28:30.45+01:00). <code>DDD</code> must be a value between 1 and the number of
+ * 	days there is in the chosen year.
+ * </p>
+ * 
+ * <p>
+ * 	Separators (like '-', ':' and '.') are optional. The date and time separator ('T') may be replaced by a space.
+ * </p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (10/2014)
+ * @version 4.2 (12/2015)
  * @since 4.1
  */
 public class ISO8601Format {
@@ -53,6 +107,9 @@ public class ISO8601Format {
 	/** Indicate the time zone in which the date and time should be formatted (whatever is the time zone of the given date). */
 	public static String targetTimeZone = "UTC"; // for the local time zone: TimeZone.getDefault().getID();
 
+	/** Object to use to format numbers with one digit (ie. 1, 2, 0).
+	 * @since 4.2 */
+	protected final static DecimalFormat oneDigitFmt = new DecimalFormat("0");
 	/** Object to use to format numbers with two digits (ie. 12, 02, 00). */
 	protected final static DecimalFormat twoDigitsFmt = new DecimalFormat("00");
 	/** Object to use to format numbers with three digits (ie. 001, 000, 123). */
@@ -230,23 +287,109 @@ public class ISO8601Format {
 		return new Date(parse(strDate));
 	}
 
+	public final static void main(final String[] args) throws Throwable{
+		System.out.println("Date in millis: " + ISO8601Format.parse("2015-12-11"));
+	}
+
+	/**
+	 * <p>Regular expression of the Time part of the ISO-8601 representation.</p>
+	 * 
+	 * <p>Indexes of the identified groups in this regular expression.</p><pre>
+	 * ( 0: everything)
+	 * ( 1: T or space)
+	 *   2: hours (hh)
+	 * ( 3: minutes + seconds + milliseconds)
+	 *   4: minutes (mm)
+	 * ( 5: seconds + milliseconds)
+	 *   6: seconds (ss)
+	 * ( 7: '.' + milliseconds)
+	 *   8: milliseconds (s...)
+	 * ( 9: full time zone: 'Z' or hours:minutes)
+	 *  10: sign (+ or -)
+	 *  11: hours offset (hh)
+	 * (12: ':' + minutes offset)
+	 *  13: minutes offset (mm)</pre>
+	 *  
+	 * @since 4.2
+	 */
+	private final static String ISO8601_TIME_REGEX = "((T| )(\\d{2})(:?(\\d{2})(:?(\\d{2})(\\.?(\\d{1,}))?)?)?(Z|(\\+|-)(\\d{2})(:?(\\d{2}))?)?)?";
+
+	/**
+	 * <p>{@link Pattern} object implementing the ISO-8601 representation.</p>
+	 * 
+	 * <p>The regular expression used in this {@link Pattern} identifies the following groups:</p><pre>
+	 * (    0: everything)
+	 *      1: year (yyyy)
+	 * (    2: '-' and the rest of the date (may include the time))
+	 * (    3: the rest of the date (may include the time))
+	 *      4: month (MM)
+	 * (    5: '-' and the day of the month)
+	 *      6: day of the month (dd)
+	 *   7-20: TIME
+	 *     21: day of the year (ddd)
+	 *  22-35: TIME
+	 *     36: week of the year (ww)
+	 * (   37: '-' and the day of the week)
+	 *     38: the day of the week (d)
+	 *  39-52: TIME</pre>
+	 * 
+	 * <p>All groups named <code>TIME</code> refer to {@link #ISO8601_TIME_REGEX}.</p>
+	 *  
+	 * <p>Groups in parenthesis should be ignored ; but an exception must be done for the 9th of {@link #ISO8601_TIME_REGEX} which may contain 'Z' meaning a UTC time zone.</p>
+	 * 
+	 * <p>Separator characters ('-', '.' and ':') are optional. The separator 'T' may be replaced by a ' '.</p>
+	 *  
+	 * @since 4.2
+	 */
+	private final static Pattern ISO8601_PATTERN = Pattern.compile("(\\d{4})(-?((\\d{2})(-?(\\d{2})" + ISO8601_TIME_REGEX + ")?|(\\d{3})" + ISO8601_TIME_REGEX + "|W(\\d{2})(-?(\\d)" + ISO8601_TIME_REGEX + ")?))?");
+
 	/**
 	 * <p>Parse the given date expressed using the ISO8601 format ("yyyy-MM-dd'T'hh:mm:ss.sssZ"
 	 * or "yyyy-MM-dd'T'hh:mm:ss.sssZ[+|-]hh:mm:ss").</p>
 	 * 
 	 * <p>
-	 * 	The syntax of the given date may be more or less strict. Particularly, separators like '-' and ':' are optional.
-	 * 	Besides the date and time separator ('T') may be replaced by a space.
+	 * 	This parser allows the following general syntaxes:
 	 * </p>
+	 * <ul>
+	 * 	<li>YYYY (e.g. 2015)</li>
+	 * 	<li>YYYY-MM (e.g. 2015-12)</li>
+	 * 	<li>YYYY-MM-DD (e.g. 2015-12-11)</li>
+	 * 	<li>YYYY-MM-DD'T'hh:mmTZD (e.g. 2015-12-11T20:28+01:00 or 2015-12-11T19:28Z)</li>
+	 * 	<li>YYYY-MM-DD'T'hh:mm:ssTZD (e.g. 2015-12-11T20:28:30+01:00 or 2015-12-11T19:28:30Z)</li>
+	 * 	<li>YYYY-MM-DD'T'hh:mm:ss.sTZD (e.g. 2015-12-11T20:28:30.45+01:00 or 2015-12-11T19:28:30.45Z)</li>
+	 * </ul>
+	 * <p>Where:</p>
+	 * <ul>
+	 * 	<li>YYYY = four-digit year</li>
+	 * 	<li>MM   = two-digit month (01=January, etc.)</li>
+	 * 	<li>DD   = two-digit day of month (01 through 31)</li>
+	 * 	<li>hh   = two digits of hour (00 through 23) (am/pm NOT allowed)</li>
+	 * 	<li>mm   = two digits of minute (00 through 59)</li>
+	 * 	<li>ss   = two digits of second (00 through 59)</li>
+	 * 	<li>s    = one or more digits representing a decimal fraction of a second (i.e. milliseconds)</li>
+	 * 	<li>TZD  = time zone designator (Z or +hh:mm or -hh:mm)</li>
+	 * </ul>
 	 * 
 	 * <p>
-	 * 	The minimum allowed string is the date: "yyyy-MM-dd". All other date-time fields are optional,
-	 * 	BUT, the time zone can be given without the time.
+	 * 	It is also possible to express the date in weeks with the following syntax: YYYY-'W'ww-D
+	 * 	(e.g. 2015-W50, 2015-W50-5, 2015-W50-5T20:28:30.45+01:00). <code>ww</code> must a 2 digits number between
+	 * 	1 and the number of weeks available in the chosen year. <code>D</code> corresponds to the day
+	 * 	of the week: Monday = 1, Tuesday = 2, ..., Sunday = 7.
+	 * </p>
+	 * 
+	 * <p>
+	 * 	A last representation of the date is possible: in days of year: YYYY-DDD
+	 * 	(e.g. 2015-345, 2015-345T20:28:30.45+01:00). <code>DDD</code> must be a value between 1 and the number of
+	 * 	days there is in the chosen year.
 	 * </p>
 	 * 
 	 * <p>
 	 * 	If no time zone is specified (by a 'Z' or a time offset), the time zone in which the date is expressed
 	 * 	is supposed to be the local one.
+	 * </p>
+	 * 
+	 * <p>
+	 * 	Separators (like '-', ':' and '.') are optional. The date and time separator ('T') may be replaced by a space.
 	 * </p> 
 	 * 
 	 * @param strDate	Date expressed as a string in ISO8601 format.
@@ -257,40 +400,12 @@ public class ISO8601Format {
 	 * @throws ParseException	If the given date is not expressed in ISO8601 format or is not merely parseable with this implementation.
 	 */
 	public static long parse(final String strDate) throws ParseException{
-		Pattern p = Pattern.compile("(\\d{4})-?(\\d{2})-?(\\d{2})([T| ](\\d{2}):?(\\d{2}):?(\\d{2})(\\.(\\d+))?(Z|([\\+|\\-])(\\d{2}):?(\\d{2})(:?(\\d{2}))?)?)?");
-		/*
-		 * With this regular expression, we will get the following groups:
-		 * 
-		 * 	( 0: everything)
-		 * 	  1: year  (yyyy)
-		 * 	  2: month (MM)
-		 * 	  3: day   (dd)
-		 * 	( 4: the full time part)
-		 * 	  5: hours        (hh)
-		 * 	  6: minutes      (mm)
-		 * 	  7: seconds      (ss)
-		 * 	( 8: the full ms part)
-		 * 	  9: milliseconds (sss)
-		 * 	(10: the full time zone part: 'Z' or the applied time offset)
-		 * 	 11: sign of the offset ('+' if an addition was applied, '-' if it was a subtraction)
-		 * 	 12: applied hours offset   (hh)
-		 * 	 13: applied minutes offset (mm)
-		 * 	(14: the full seconds offset)
-		 * 	 15: applied seconds offset (ss)
-		 * 
-		 * Groups in parenthesis should be ignored ; but an exception must be done for the 10th which may contain 'Z' meaning a UTC time zone.
-		 * 
-		 * All groups from the 4th (included) are optional. If not filled, an optional group is set to NULL.
-		 * 
-		 * This regular expression is more permissive than the strict definition of the ISO8601 format. Particularly, separator characters
-		 * ('-', 'T' and ':') are optional and it is possible to specify seconds in the time zone offset.
-		 */
-
-		Matcher m = p.matcher(strDate);
+		Matcher m = ISO8601_PATTERN.matcher(strDate);
 		if (m.matches()){
-			Calendar cal = new GregorianCalendar();
+			GregorianCalendar cal = new GregorianCalendar();
+			int timeGroupInd = -1;
 
-			// Set the time zone:
+			// SET THE TIME ZONE:
 			/* 
 			 * Note: In this library, we suppose that any date provided without specified time zone, is in UTC.
 			 * 
@@ -305,20 +420,56 @@ public class ISO8601Format {
 			 */
 			cal.setTimeZone(TimeZone.getTimeZone("UTC"));
 
-			// Set the date:
-			cal.set(Calendar.DAY_OF_MONTH, twoDigitsFmt.parse(m.group(3)).intValue());
-			cal.set(Calendar.MONTH, twoDigitsFmt.parse(m.group(2)).intValue() - 1);
+			// SET THE DATE:
 			cal.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
-
-			// Set the time:
+			// ...month based:
 			if (m.group(4) != null){
-				cal.set(Calendar.HOUR_OF_DAY, twoDigitsFmt.parse(m.group(5)).intValue());
-				cal.set(Calendar.MINUTE, twoDigitsFmt.parse(m.group(6)).intValue());
-				cal.set(Calendar.SECOND, twoDigitsFmt.parse(m.group(7)).intValue());
-				if (m.group(9) != null)
-					cal.set(Calendar.MILLISECOND, twoDigitsFmt.parse(m.group(9)).intValue());
+				cal.set(Calendar.MONTH, getMonth(m.group(4)));
+				if (m.group(5) != null)
+					cal.set(Calendar.DAY_OF_MONTH, getDayOfMonth(m.group(6), cal));
 				else
+					cal.set(Calendar.DAY_OF_MONTH, 1);
+				timeGroupInd = 7;
+			}
+			// ...day based:
+			else if (m.group(21) != null){
+				cal.set(Calendar.DAY_OF_YEAR, getDayOfYear(m.group(21), cal));
+				timeGroupInd = 22;
+			}
+			// ...week based:
+			else if (m.group(36) != null){
+				cal.set(Calendar.WEEK_OF_YEAR, getWeekOfYear(m.group(36), cal));
+				if (m.group(37) != null)
+					cal.set(Calendar.DAY_OF_WEEK, getDayOfWeek(m.group(38)));
+				// set the index of the time group:
+				timeGroupInd = 39;
+			}
+			// ...no month & day specified:
+			else{
+				cal.set(Calendar.MONTH, 0);
+				cal.set(Calendar.DAY_OF_MONTH, 1);
+			}
+
+			// SET THE TIME:
+			if (timeGroupInd > 0 && m.group(timeGroupInd) != null){
+				cal.set(Calendar.HOUR_OF_DAY, getHours(m.group(timeGroupInd + 2)));
+				if (m.group(timeGroupInd + 3) != null){
+					cal.set(Calendar.MINUTE, getMinutes(m.group(timeGroupInd + 4)));
+					if (m.group(timeGroupInd + 5) != null){
+						cal.set(Calendar.SECOND, getSeconds(m.group(timeGroupInd + 6)));
+						if (m.group(timeGroupInd + 7) != null)
+							cal.set(Calendar.MILLISECOND, twoDigitsFmt.parse(m.group(timeGroupInd + 8)).intValue());
+						else
+							cal.set(Calendar.MILLISECOND, 0);
+					}else{
+						cal.set(Calendar.SECOND, 0);
+						cal.set(Calendar.MILLISECOND, 0);
+					}
+				}else{
+					cal.set(Calendar.MINUTE, 0);
+					cal.set(Calendar.SECOND, 0);
 					cal.set(Calendar.MILLISECOND, 0);
+				}
 			}else{
 				cal.set(Calendar.HOUR_OF_DAY, 0);
 				cal.set(Calendar.MINUTE, 0);
@@ -326,17 +477,205 @@ public class ISO8601Format {
 				cal.set(Calendar.MILLISECOND, 0);
 			}
 
-			// Compute and apply the offset:
-			if (m.group(10) != null && !m.group(10).equals("Z")){
-				int sign = (m.group(11).equals("-") ? 1 : -1);
-				cal.add(Calendar.HOUR_OF_DAY, sign * twoDigitsFmt.parse(m.group(12)).intValue());
-				cal.add(Calendar.MINUTE, sign * twoDigitsFmt.parse(m.group(13)).intValue());
-				if (m.group(15) != null)
-					cal.add(Calendar.SECOND, sign * twoDigitsFmt.parse(m.group(15)).intValue());
+			// COMPUTE AND APPLY THE OFFSET (if any is specified):
+			if (timeGroupInd > 0 && m.group(timeGroupInd + 9) != null && !m.group(timeGroupInd + 9).equals("Z")){
+				int sign = (m.group(timeGroupInd + 10).equals("-") ? 1 : -1);
+				cal.add(Calendar.HOUR_OF_DAY, sign * getHours(m.group(timeGroupInd + 11)));
+				if (m.group(timeGroupInd + 12) != null)
+					cal.add(Calendar.MINUTE, sign * getMinutes(m.group(timeGroupInd + 13)));
 			}
 
 			return cal.getTimeInMillis();
 		}else
 			throw new ParseException("Invalid date format: \"" + strDate + "\"! An ISO8601 date was expected.", 0);
 	}
+
+	/**
+	 * <p>Convert the given ISO-8601 day of year value into a Java day of year value.</p>
+	 * 
+	 * <i>Note: Same representation in ISO-8601 and Java.</i>
+	 * 
+	 * @param str	Textual representation of the day of year in ISO-8601.
+	 * @param cal	The calendar in which the year has already been set.
+	 *           	<i>Note: This parameter is used to know the maximum number of days there are for the set year.
+	 *           	(see {@link GregorianCalendar#getActualMaximum(int)})</i>
+	 * 
+	 * @return	The corresponding Java day of year.
+	 * 
+	 * @throws ParseException	If the given day of year is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getDayOfYear(final String str, final GregorianCalendar cal) throws ParseException{
+		/* A day of year can only be between 1 and 365 (or 366 in leap year). */
+		int dayOfYear = threeDigitsFmt.parse(str).intValue();
+		if (dayOfYear < 1 || dayOfYear > cal.getActualMaximum(Calendar.DAY_OF_YEAR))
+			throw new ParseException("Incorrect day of year: " + dayOfYear + "! An integer between 1 and " + cal.getActualMaximum(Calendar.DAY_OF_YEAR) + " was expected.", -1);
+		return dayOfYear;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 day of month value into a Java day of month value.</p>
+	 * 
+	 * <i>Note: Same representation in ISO-8601 and Java.</i>
+	 * 
+	 * @param str	Textual representation of the day of month in ISO-8601.
+	 * @param cal	The calendar in which the year and the month has already been set.
+	 *           	<i>Note: This parameter is used to know the maximum number of days there are for the set month and year.
+	 *           	(see {@link GregorianCalendar#getActualMaximum(int)})</i>
+	 * 
+	 * @return	The corresponding Java day of month.
+	 * 
+	 * @throws ParseException	If the given day of month is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getDayOfMonth(final String str, final GregorianCalendar cal) throws ParseException{
+		int dayOfMonth = twoDigitsFmt.parse(str).intValue();
+		if (dayOfMonth < 1 || dayOfMonth > cal.getActualMaximum(Calendar.DAY_OF_MONTH))
+			throw new ParseException("Incorrect day of month: " + dayOfMonth + "! An integer between 1 and " + cal.getActualMaximum(Calendar.DAY_OF_MONTH) + " was expected.", -1);
+		return dayOfMonth;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 day of week value into a Java day of week value.</p>
+	 * 
+	 * <ul>
+	 * 	<li><u>In ISO-8601</u>: Monday = 1, Tuesday = 2, ..., Saturday = 6, Sunday = 7.</li>
+	 * 	<li><u>In Java</u>    : Monday = 2, Tuesday = 3, ..., Saturday = 7, Sunday = 1.</li>
+	 * </ul>
+	 * 
+	 * @param str	Textual representation of the day of week in ISO-8601.
+	 * 
+	 * @return	The corresponding Java day of week.
+	 * 
+	 * @throws ParseException	If the given day of week is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getDayOfWeek(final String str) throws ParseException{
+		int dayOfWeek = oneDigitFmt.parse(str).intValue();
+		if (dayOfWeek < 1 || dayOfWeek > 7)
+			throw new ParseException("Incorrect day of week: " + dayOfWeek + "! An integer between 1 (for Monday) and 7 (for Sunday) was expected.", -1);
+		else if (dayOfWeek == 7)
+			dayOfWeek = 1;
+		else
+			dayOfWeek++;
+		return dayOfWeek;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 week of year value into a Java week of year value.</p>
+	 * 
+	 * <i>Note: Same representation in ISO-8601 and Java.</i>
+	 * 
+	 * @param str	Textual representation of the week of year value in ISO-8601.
+	 * @param cal	The calendar in which the year has already been set.
+	 *           	<i>Note: This parameter is used to know the maximum number of weeks there are for the set year.
+	 *           	(see {@link GregorianCalendar#getActualMaximum(int)})</i>
+	 * 
+	 * @return	The corresponding Java week of year value.
+	 * 
+	 * @throws ParseException	If the given week of year value is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getWeekOfYear(final String str, final GregorianCalendar cal) throws ParseException{
+		int weekOfYear = twoDigitsFmt.parse(str).intValue();
+		if (weekOfYear < 1 || weekOfYear > cal.getActualMaximum(Calendar.WEEK_OF_YEAR))
+			throw new ParseException("Incorrect week of year value: " + weekOfYear + "! An integer between 1 and " + cal.getActualMaximum(Calendar.WEEK_OF_YEAR) + " was expected.", -1);
+		return weekOfYear;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 month index into a Java index.</p>
+	 * 
+	 * <ul>
+	 * 	<li><u>In ISO-8601</u>: January = 1, February = 2, ..., December = 12.</li>
+	 * 	<li><u>In Java</u>    : January = 0, February = 1, ..., December = 11.</li>
+	 * </ul>
+	 * 
+	 * @param str	Textual representation of the month index in ISO-8601.
+	 * 
+	 * @return	The corresponding Java month index.
+	 * 
+	 * @throws ParseException	If the given month index is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getMonth(final String str) throws ParseException{
+		int month = twoDigitsFmt.parse(str).intValue();
+		if (month < 1 || month > 12)
+			throw new ParseException("Incorrect month value: " + month + "! An integer between 1 and 12 was expected.", -1);
+		return month - 1;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 hours value into a Java hours value.</p>
+	 * 
+	 * <ul>
+	 * 	<li><u>In ISO-8601</u>: 0 -&gt; 24.</li>
+	 * 	<li><u>In Java</u>    : Calendar.HOUR_OF_DAY for 0 -&gt; 24.</li>
+	 * </ul>
+	 * 
+	 * @param str	Textual representation of the hours value in ISO-8601.
+	 * 
+	 * @return	The corresponding Java hours value.
+	 * 
+	 * @throws ParseException	If the given hours value is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getHours(final String str) throws ParseException{
+		int hours = twoDigitsFmt.parse(str).intValue();
+		if (hours < 0 || hours > 24)
+			throw new ParseException("Incorrect hour value: " + hours + "! An integer between 0 and 24 was expected.", -1);
+		return hours;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 minutes value into a Java minutes value.</p>
+	 * 
+	 * <ul>
+	 * 	<li><u>In ISO-8601</u>: 0 -&gt; 60.</li>
+	 * 	<li><u>In Java</u>    : 0 -&gt; 60.</li>
+	 * </ul>
+	 * 
+	 * @param str	Textual representation of the minutes value in ISO-8601.
+	 * 
+	 * @return	The corresponding Java minutes value.
+	 * 
+	 * @throws ParseException	If the given minutes value is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getMinutes(final String str) throws ParseException{
+		int minutes = twoDigitsFmt.parse(str).intValue();
+		if (minutes < 0 || minutes > 60)
+			throw new ParseException("Incorrect minute value: " + minutes + "! An integer between 0 and 60 was expected.", -1);
+		return minutes;
+	}
+
+	/**
+	 * <p>Convert the given ISO-8601 seconds value into a Java seconds value.</p>
+	 * 
+	 * <ul>
+	 * 	<li><u>In ISO-8601</u>: 0 -&gt; 60.</li>
+	 * 	<li><u>In Java</u>    : 0 -&gt; 60.</li>
+	 * </ul>
+	 * 
+	 * @param str	Textual representation of the seconds value in ISO-8601.
+	 * 
+	 * @return	The corresponding Java seconds value.
+	 * 
+	 * @throws ParseException	If the given seconds value is incorrect according to ISO-8601.
+	 * 
+	 * @since 4.2
+	 */
+	private static final int getSeconds(final String str) throws ParseException{
+		int seconds = twoDigitsFmt.parse(str).intValue();
+		if (seconds < 0 || seconds > 60)
+			throw new ParseException("Incorrect second value: " + seconds + "! An integer between 0 and 60 was expected.", -1);
+		return seconds;
+	}
 }
diff --git a/test/uws/TestISO8601Format.java b/test/uws/TestISO8601Format.java
index 22c9ee920c8fd0585a9dae1b0df7a7db60cbced5..d61067e486c8d283c1e3c55538bb5bb760911578 100644
--- a/test/uws/TestISO8601Format.java
+++ b/test/uws/TestISO8601Format.java
@@ -15,6 +15,7 @@ public class TestISO8601Format {
 
 	private final long date = 1411737870325L;		// Fri Sep 26 15:24:30 CEST 2014 = 2014-09-26T15:24:30.325+02:00 = 1411737870325 ms
 	private final long dateAlone = 1411689600000L;
+	private final long dateWithNoTime = 1449792000000L; // Fri Dec 11 2015 = 2015-12-11 = 1449792000000 ms 
 
 	private final long oldDate = -3506029200000L;	// Thu Nov 25 00:00:00 CET 1858 = 1858-11-25T00:00:00+01:00 = -3506029200000 ms
 
@@ -115,6 +116,14 @@ public class TestISO8601Format {
 			assertEquals(oldDate, ISO8601Format.parse("1858-11-25T00:00:00+01:00"));
 			assertEquals(oldDate, ISO8601Format.parse("1858-11-24T23:00:00Z"));
 
+			// Test with a date expressed in weeks:
+			assertEquals(dateWithNoTime, ISO8601Format.parse("2015-W50-5"));
+			assertEquals(dateWithNoTime, ISO8601Format.parse("2015W505"));
+
+			// Test with a date expressed in days of year:
+			assertEquals(dateWithNoTime, ISO8601Format.parse("2015-345"));
+			assertEquals(dateWithNoTime, ISO8601Format.parse("2015345"));
+
 			// Test with a perfectly valid date in ISO8601: 
 			assertEquals(dateAlone, ISO8601Format.parse("2014-09-26"));
 			assertEquals(date, ISO8601Format.parse("2014-09-26T15:24:30.325+02:00"));
@@ -155,9 +164,58 @@ public class TestISO8601Format {
 			assertEquals(date, ISO8601Format.parse("2014-09-26 13:24:30.325"));
 			assertEquals(date - 325, ISO8601Format.parse("2014-09-26 13:24:30"));
 
-		}catch(ParseException ex){
+			// Test with only the year: YYYY
+			assertEquals(0, ISO8601Format.parse("1970"));
+
+			// Test with only the year and month: YYYY-MM
+			assertEquals(0, ISO8601Format.parse("1970-01"));
+
+			// Test with a complete date: YYYY-MM-DD
+			assertEquals(0, ISO8601Format.parse("1970-01-01"));
+
+			// Test with a complete date: YYYY-'W'ww-D
+			assertEquals(0, ISO8601Format.parse("1970-W01-4"));
+
+			// Test with a complete date plus hours: YYYY-MM-DDThh:mmTZD
+			// ...with no time zone information:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00"));
+			// ...with Z:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00Z"));
+			// ...with time zone:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00+00:00"));
+
+			// Test with a complete date plus hours and minutes: YYYY-MM-DDThh:mmTZD
+			// ...with no time zone information:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00"));
+			// ...with Z:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00Z"));
+			// ...with time zone:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00+00"));
+
+			// Test with a complete date plus hours, minutes and seconds: YYYY-MM-DDThh:mm:ssTZD
+			// ...with no time zone information:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00"));
+			// ...with Z:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00Z"));
+			// ...with time zone:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00-0000"));
+
+			// Test with a complete date plus hours, minutes, seconds and a decimal fraction of a second: YYYY-MM-DDThh:mm:ss.sTZD
+			// ...with no time zone information:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00.0"));
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00.0000000"));
+			// ...with Z:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00.0Z"));
+			// ...with time zone:
+			assertEquals(0, ISO8601Format.parse("1970-01-01 00:00:00.0-00"));
+			assertEquals(0, ISO8601Format.parse("1970-01-01 03:00:00.0+03"));
+			assertEquals(0, ISO8601Format.parse("1970-01-01 03:00:00.0+03:00"));
+
+		}catch(Exception ex){
 			ex.printStackTrace(System.err);
+			fail("No error should have occured here! All date expressions are correct.");
 		}
+
 	}
 
 }