/* =========================================================================== * Copyright (c) 2007 Serena Software. All rights reserved. * * Use of the Sample Code provided by Serena is governed by the following * terms and conditions. By using the Sample Code, you agree to be bound by * the terms contained herein. If you do not agree to the terms herein, do * not install, copy, or use the Sample Code. * * 1. GRANT OF LICENSE. Subject to the terms and conditions herein, you * shall have the nonexclusive, nontransferable right to use the Sample Code * for the sole purpose of developing applications for use solely with the * Serena software product(s) that you have licensed separately from Serena. * Such applications shall be for your internal use only. You further agree * that you will not: (a) sell, market, or distribute any copies of the * Sample Code or any derivatives or components thereof; (b) use the Sample * Code or any derivatives thereof for any commercial purpose; or (c) assign * or transfer rights to the Sample Code or any derivatives thereof. * * 2. DISCLAIMER OF WARRANTIES. TO THE MAXIMUM EXTENT PERMITTED BY * APPLICABLE LAW, SERENA PROVIDES THE SAMPLE CODE AS IS AND WITH ALL * FAULTS, AND HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EITHER * EXPRESSED, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY * IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A * PARTICULAR PURPOSE, OF LACK OF VIRUSES, OF RESULTS, AND OF LACK OF * NEGLIGENCE OR LACK OF WORKMANLIKE EFFORT, CONDITION OF TITLE, QUIET * ENJOYMENT, OR NON-INFRINGEMENT. THE ENTIRE RISK AS TO THE QUALITY OF * OR ARISING OUT OF USE OR PERFORMANCE OF THE SAMPLE CODE, IF ANY, * REMAINS WITH YOU. * * 3. EXCLUSION OF DAMAGES. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE * LAW, YOU AGREE THAT IN CONSIDERATION FOR RECEIVING THE SAMPLE CODE AT NO * CHARGE TO YOU, SERENA SHALL NOT BE LIABLE FOR ANY DAMAGES WHATSOEVER, * INCLUDING BUT NOT LIMITED TO DIRECT, SPECIAL, INCIDENTAL, INDIRECT, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF * PROFITS OR CONFIDENTIAL OR OTHER INFORMATION, FOR BUSINESS INTERRUPTION, * FOR PERSONAL INJURY, FOR LOSS OF PRIVACY, FOR NEGLIGENCE, AND FOR ANY * OTHER LOSS WHATSOEVER) ARISING OUT OF OR IN ANY WAY RELATED TO THE USE * OF OR INABILITY TO USE THE SAMPLE CODE, EVEN IN THE EVENT OF THE FAULT, * TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR BREACH OF CONTRACT, * EVEN IF SERENA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE * FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SHALL APPLY TO THE * MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW. NOTWITHSTANDING THE ABOVE, * IN NO EVENT SHALL SERENA'S LIABILITY UNDER THIS AGREEMENT OR WITH RESPECT * TO YOUR USE OF THE SAMPLE CODE AND DERIVATIVES THEREOF EXCEED US$10.00. * * 4. INDEMNIFICATION. You hereby agree to defend, indemnify and hold * harmless Serena from and against any and all liability, loss or claim * arising from this agreement or from (i) your license of, use of or * reliance upon the Sample Code or any related documentation or materials, * or (ii) your development, use or reliance upon any application or * derivative work created from the Sample Code. * * 5. TERMINATION OF THE LICENSE. This agreement and the underlying * license granted hereby shall terminate if and when your license to the * applicable Serena software product terminates or if you breach any terms * and conditions of this agreement. * * 6. CONFIDENTIALITY. The Sample Code and all information relating to the * Sample Code (collectively "Confidential Information") are the * confidential information of Serena. You agree to maintain the * Confidential Information in strict confidence for Serena. You agree not * to disclose or duplicate, nor allow to be disclosed or duplicated, any * Confidential Information, in whole or in part, except as permitted in * this Agreement. You shall take all reasonable steps necessary to ensure * that the Confidential Information is not made available or disclosed by * you or by your employees to any other person, firm, or corporation. You * agree that all authorized persons having access to the Confidential * Information shall observe and perform under this nondisclosure covenant. * You agree to immediately notify Serena of any unauthorized access to or * possession of the Confidential Information. * * 7. AFFILIATES. Serena as used herein shall refer to Serena Software, * Inc. and its affiliates. An entity shall be considered to be an * affiliate of Serena if it is an entity that controls, is controlled by, * or is under common control with Serena. * * 8. GENERAL. Title and full ownership rights to the Sample Code, * including any derivative works shall remain with Serena. If a court of * competent jurisdiction holds any provision of this agreement illegal or * otherwise unenforceable, that provision shall be severed and the * remainder of the agreement shall remain in full force and effect. * =========================================================================== */ /* * This experimental plugin extends Hudson support for Dimensions SCM repositories * * @author Tim Payne * */ // Package name package hudson.plugins.dimensionsscm; // General imports import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; import java.io.Serializable; /** * A set of methods for converting Date objects to and from strings in a valid * date format, and also validating that strings are in an Oracle date format. * Note: this class uses only Locale.US at the moment - this may need changing. * @author Tim Payne */ public class DateUtils implements Serializable { private static final String DATE_PATTERN = "dd-MMM-yyyy"; private static final String DATETIME_PATTERN = "dd-MMM-yyyy HH:mm:ss"; private static final String RFCDATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); // should this be "GMT"? private static TimeZone tzl = TimeZone.getDefault(); /** * Attempt to parse as date-and-time patterns first (since a timestamp * string with a date-and-time would also be parsed by a date pattern). */ private static final String PATTERNS[] = { DATETIME_PATTERN, DATE_PATTERN, RFCDATETIME_PATTERN }; /** * Parses a date from a string in known format, using UTC time zone. * NOTE: This should ONLY be used if the caller has no knowledge of the * time zone to be used. Most of the time the overloaded method below * should be used. * @param dateStr a String containing a date in known form * @return a Date object, or null */ public static Date parse(String dateStr) { return parse(dateStr, tzl); } /** * Parses a date from a string in known form. * @param dateStr a String containing a date in known form * @param tz the TimeZone to be used when parsing the date string * @return a Date object, or null */ public static Date parse(String dateStr, TimeZone tz) { Date date = null; dateStr = dateStr.trim(); for (int i = 0; i < PATTERNS.length; ++i) { try { SimpleDateFormat df= new SimpleDateFormat(PATTERNS[i], Locale.US); df.setTimeZone(tz); date = df.parse(dateStr); if (date != null) { break; } } catch (ParseException pe) { /* do nothing, try the next pattern. */ } } return date; } /** * Validates whether a given string is in correct known date format or date-time format. * Note that this is stricter than the {@link #parse(String)} method is. * @param dateStr the String containing the date to be validated * @return true if the string is in a valid format, false otherwise */ public static boolean validate(String dateStr) { boolean ret = false; dateStr = dateStr.trim(); for (int i = 0; i < PATTERNS.length; ++i) { try { SimpleDateFormat df = new SimpleDateFormat(PATTERNS[i], Locale.US); Date date = df.parse(dateStr); if (date != null && df.format(date).equalsIgnoreCase(dateStr)) { ret = true; break; } } catch (ParseException pe) { /* do nothing, try the next pattern. */ } } return ret; } /** * Note that comparing dates that have been converted from one format into * another should always be done with a tolerance (like comparing doubles * or floats) to allow for the fact that some accuracy may be lost (for * instance by rounding to the nearest second). * @param d1 first date to compare. * @param d2 second date to compare. * @param toleranceMillis millisecond tolerance to allow. * @return 0 if the two dates are within toleranceMillis milliseconds of * each other, negative if d1 < d2, positive if d1 > d2 */ public static int compare(Date d1, Date d2, long toleranceMillis) { int ret; long diff = d1.getTime() - d2.getTime(); if (Math.abs(diff) <= Math.abs(toleranceMillis)) { ret = 0; } else if (diff < 0L) { ret = -1; } else if (diff > 0L) { ret = 1; } else { // doesn't happen. ret = 0; } return ret; } /** * Formats a string in known date-time form from a date object, * using UTC time zone. * NOTE: This should ONLY be used if the caller has no knowledge of the * time zone to be used. Most of the time the overloaded method below * should be used. * @param date the date to be formatted * @return a String containing a date in known date-time form, or null */ public static String format(Date date) { return format(date, tzl); } /** * Formats a string in known date-time form from a date object, * using UTC time zone. * @param date the date to be formatted * @param tz the TimeZone to be used when parsing the date string * @return a String containing a date in known date-time form, or null */ public static String format(Date date, TimeZone tz) { SimpleDateFormat df = new SimpleDateFormat(DATETIME_PATTERN, Locale.US); df.setTimeZone(tz); return df.format(date); } /** * Gets "now" in RFC format * @return a String containing a date in known RFC */ public static String getNowStrDate() { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Calendar opDate = Calendar.getInstance(); df.setTimeZone(tzl); return df.format(opDate.getTime()); } /** * Gets "now" in RFC format * @param timezone tz * @return a String containing a date in known RFC */ public static String getNowStrDate(TimeZone tz) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Calendar opDate = Calendar.getInstance(); df.setTimeZone(tz); return df.format(opDate.getTime()); } /** * Gets "now" in verbose format * @return a String containing a date in verbose format */ public static String getNowStrDateVerbose() { SimpleDateFormat df = new SimpleDateFormat("yyyy.MMMMM.dd hh:mm:ss aaa z"); Calendar opDate = Calendar.getInstance(); df.setTimeZone(tzl); return df.format(opDate.getTime()); } /** * Gets a date in RFC format * @param calendar date * @return a String containing a date in known RFC */ public static String getStrDate(Calendar opDate) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(tzl); return df.format(opDate.getTime()); } /** * Gets a date in RFC format * @param calendar date * @param timezone tz * @return a String containing a date in known RFC */ public static String getStrDate(Calendar opDate, TimeZone tz) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(tz); return df.format(opDate.getTime()); } }