/******************************************************************************* * Copyright (c) 2004, 2006 * Thomas Hallgren, Kenneth Olwing, Mitch Sonies * Pontus Rydin, Nils Unden, Peer Torngren * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed above, as Initial Contributors under such license. * The text of such license is available at www.eclipse.org. *******************************************************************************/ package org.eclipse.buckminster.core.helpers; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.eclipse.buckminster.core.Messages; import org.eclipse.osgi.util.NLS; /** * @author Thomas Hallgren */ public abstract class DateAndTimeUtils { public static final String ISO_8601Pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; //$NON-NLS-1$ public static final DateFormat ISO_8601Format; public static final TimeZone UTC; public static final String[] commonFormats = new String[] { ISO_8601Pattern, "yyyy-MM-dd_HH-mm-ss", "yyyyMMddHHmm", "yyyyMMdd-HHmm", "yyyyMMdd" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ public static final DateFormat[] commonFormatters; // Milliseconds corresponding to approximately 10 years // private static final long SANITY_THRESHOLD = (10 * 365 + 3) * 24 * 60 * 60 * 1000; static { ISO_8601Format = new SimpleDateFormat(ISO_8601Pattern); UTC = TimeZone.getTimeZone("UTC"); //$NON-NLS-1$ ISO_8601Format.setCalendar(Calendar.getInstance(UTC)); int idx = commonFormats.length; commonFormatters = new DateFormat[idx]; while (--idx > 0) { DateFormat dm = new SimpleDateFormat(commonFormats[idx]); dm.setTimeZone(UTC); dm.setLenient(false); commonFormatters[idx] = dm; } commonFormatters[0] = ISO_8601Format; } /** * Create a date by parsing a string that conforms to the ISO-8601 format * "yyyy-MM-dd'T'HH:mm:ss.SSSZ". The UTC time zone will be used. * * @param dateStr * the string to parse * @return the resulting date or <code>null</code> if the * <code>dateStr</code> was <code>null</code>. * @throws ParseException * if <code>dateStr</code> does not conform to the expected * format. */ public static Date fromISOFormat(String dateStr) throws ParseException { if (dateStr == null) return null; synchronized (ISO_8601Format) { return ISO_8601Format.parse(dateStr); } } public static Date fromString(String timestampStr) throws ParseException { for (int idx = 0; idx < commonFormatters.length; ++idx) { try { return parseSaneDate(commonFormatters[idx], timestampStr); } catch (ParseException e1) { } } throw new ParseException(NLS.bind(Messages.Unable_to_parse_0_as_timestamp, timestampStr), 0); } /** * Create a string from <code>date</code> that is formatted according to * ISO-8601 format "yyyy-MM-dd'T'HH:mm:ss.SSSZ" and using the UTC * time zone. * * @param date * the date that should be formatted. * @return The formatted String or <code>null</code> if the argument is * null. */ public static String toISOFormat(Date date) { if (date == null) return null; synchronized (ISO_8601Format) { return ISO_8601Format.format(date); } } private static Date parseSaneDate(DateFormat mf, String str) throws ParseException { long now = System.currentTimeMillis(); Date dt; synchronized (mf) { dt = mf.parse(str); } long tm = dt.getTime(); if (tm > now + SANITY_THRESHOLD || tm < now - SANITY_THRESHOLD) throw new ParseException(Messages.Bogus, 0); return dt; } }