Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 260   Methods: 7
NCLOC: 88   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DateUtils.java 16.7% 55.9% 71.4% 53.2%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant.util;
 55   
 
 56   
 import java.text.ChoiceFormat;
 57   
 import java.text.DateFormat;
 58   
 import java.text.MessageFormat;
 59   
 import java.text.SimpleDateFormat;
 60   
 import java.util.Calendar;
 61   
 import java.util.Date;
 62   
 import java.util.Locale;
 63   
 import java.util.TimeZone;
 64   
 
 65   
 /**
 66   
  * Helper methods to deal with date/time formatting with a specific
 67   
  * defined format (<a href="http://www.w3.org/TR/NOTE-datetime">ISO8601</a>)
 68   
  * or a plurialization correct elapsed time in minutes and seconds.
 69   
  *
 70   
  * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
 71   
  * @author Stefan Bodewig
 72   
  *
 73   
  * @since Ant 1.5
 74   
  * 
 75   
  * @version $Revision: 1.8 $
 76   
  */
 77   
 public final class DateUtils {
 78   
 
 79   
     /**
 80   
      * ISO8601-like pattern for date-time. It does not support timezone.
 81   
      *  <tt>yyyy-MM-ddTHH:mm:ss</tt>
 82   
      */
 83   
     public static final String ISO8601_DATETIME_PATTERN
 84   
             = "yyyy-MM-dd'T'HH:mm:ss";
 85   
 
 86   
     /**
 87   
      * ISO8601-like pattern for date. <tt>yyyy-MM-dd</tt>
 88   
      */
 89   
     public static final String ISO8601_DATE_PATTERN
 90   
             = "yyyy-MM-dd";
 91   
 
 92   
     /**
 93   
      * ISO8601-like pattern for time.  <tt>HH:mm:ss</tt>
 94   
      */
 95   
     public static final String ISO8601_TIME_PATTERN
 96   
             = "HH:mm:ss";
 97   
 
 98   
     /**
 99   
      * Format used for SMTP (and probably other) Date headers.
 100   
      */
 101   
     public static final DateFormat DATE_HEADER_FORMAT
 102   
         = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
 103   
 
 104   
 
 105   
 // code from Magesh moved from DefaultLogger and slightly modified
 106   
     private static final MessageFormat MINUTE_SECONDS
 107   
             = new MessageFormat("{0}{1}");
 108   
 
 109   
     private static final double[] LIMITS = {0, 1, 2};
 110   
 
 111   
     private static final String[] MINUTES_PART =
 112   
             {"", "1 minute ", "{0,number} minutes "};
 113   
 
 114   
     private static final String[] SECONDS_PART =
 115   
             {"0 seconds", "1 second", "{1,number} seconds"};
 116   
 
 117   
     private static final ChoiceFormat MINUTES_FORMAT =
 118   
             new ChoiceFormat(LIMITS, MINUTES_PART);
 119   
 
 120   
     private static final ChoiceFormat SECONDS_FORMAT =
 121   
             new ChoiceFormat(LIMITS, SECONDS_PART);
 122   
 
 123   
     static {
 124  1
         MINUTE_SECONDS.setFormat(0, MINUTES_FORMAT);
 125  1
         MINUTE_SECONDS.setFormat(1, SECONDS_FORMAT);
 126   
     }
 127   
 
 128   
     /** private constructor */
 129  0
     private DateUtils() {
 130   
     }
 131   
 
 132   
 
 133   
     /**
 134   
      * Format a date/time into a specific pattern.
 135   
      * @param date the date to format expressed in milliseconds.
 136   
      * @param pattern the pattern to use to format the date.
 137   
      * @return the formatted date.
 138   
      */
 139  1
     public static String format(long date, String pattern) {
 140  1
         return format(new Date(date), pattern);
 141   
     }
 142   
 
 143   
 
 144   
     /**
 145   
      * Format a date/time into a specific pattern.
 146   
      * @param date the date to format expressed in milliseconds.
 147   
      * @param pattern the pattern to use to format the date.
 148   
      * @return the formatted date.
 149   
      */
 150  4
     public static String format(Date date, String pattern) {
 151  4
         DateFormat df = createDateFormat(pattern);
 152  4
         return df.format(date);
 153   
     }
 154   
 
 155   
 
 156   
     /**
 157   
      * Format an elapsed time into a plurialization correct string.
 158   
      * It is limited only to report elapsed time in minutes and
 159   
      * seconds and has the following behavior.
 160   
      * <ul>
 161   
      * <li>minutes are not displayed when 0. (ie: "45 seconds")</li>
 162   
      * <li>seconds are always displayed in plural form (ie "0 seconds" or
 163   
      * "10 seconds") except for 1 (ie "1 second")</li>
 164   
      * </ul>
 165   
      * @param time the elapsed time to report in milliseconds.
 166   
      * @return the formatted text in minutes/seconds.
 167   
      */
 168  5
     public static String formatElapsedTime(long millis) {
 169  5
         long seconds = millis / 1000;
 170  5
         long minutes = seconds / 60;
 171  5
         Object[] args = {new Long(minutes), new Long(seconds % 60)};
 172  5
         return MINUTE_SECONDS.format(args);
 173   
     }
 174   
 
 175   
     /**
 176   
      * return a lenient date format set to GMT time zone.
 177   
      * @param pattern the pattern used for date/time formatting.
 178   
      * @return the configured format for this pattern.
 179   
      */
 180  4
     private static DateFormat createDateFormat(String pattern) {
 181  4
         SimpleDateFormat sdf = new SimpleDateFormat(pattern);
 182  4
         TimeZone gmt = TimeZone.getTimeZone("GMT");
 183  4
         sdf.setTimeZone(gmt);
 184  4
         sdf.setLenient(true);
 185  4
         return sdf;
 186   
     }
 187   
 
 188   
     /**
 189   
      * Calculate the phase of the moon for a given date.
 190   
      *
 191   
      * <p>Code heavily influenced by hacklib.c in <a
 192   
      * href="http://www.nethack.org/">Nethack</a></p>
 193   
      *
 194   
      * <p>The Algorithm:
 195   
      *
 196   
      * <pre>
 197   
      * moon period = 29.53058 days ~= 30, year = 365.2422 days
 198   
      *
 199   
      * days moon phase advances on first day of year compared to preceding year
 200   
      *  = 365.2422 - 12*29.53058 ~= 11
 201   
      *
 202   
      * years in Metonic cycle (time until same phases fall on the same days of
 203   
      *  the month) = 18.6 ~= 19
 204   
      *
 205   
      * moon phase on first day of year (epact) ~= (11*(year%19) + 18) % 30
 206   
      *  (18 as initial condition for 1900)
 207   
      *
 208   
      * current phase in days = first day phase + days elapsed in year
 209   
      *
 210   
      * 6 moons ~= 177 days
 211   
      * 177 ~= 8 reported phases * 22
 212   
      * + 11/22 for rounding
 213   
      * </pre>
 214   
      *
 215   
      * @return The phase of the moon as a number between 0 and 7 with
 216   
      *         0 meaning new moon and 4 meaning full moon.
 217   
      *
 218   
      * @since 1.2, Ant 1.5
 219   
      */
 220  2
     public static int getPhaseOfMoon(Calendar cal) {
 221  2
         int dayOfTheYear = cal.get(Calendar.DAY_OF_YEAR);
 222  2
         int yearInMetonicCycle = ((cal.get(Calendar.YEAR) - 1900) % 19) + 1;
 223  2
         int epact = (11 * yearInMetonicCycle + 18) % 30;
 224  2
         if ((epact == 25 && yearInMetonicCycle > 11) || epact == 24) {
 225  0
             epact++;
 226   
         }
 227  2
         return (((((dayOfTheYear + epact) * 6) + 11) % 177) / 22) & 7;
 228   
     }
 229   
 
 230   
     /**
 231   
      * Returns the current Date in a format suitable for a SMTP date
 232   
      * header.
 233   
      *
 234   
      * @since Ant 1.5.2
 235   
      */
 236  0
     public static String getDateForHeader() {
 237  0
         Calendar cal = Calendar.getInstance();
 238  0
         TimeZone tz = cal.getTimeZone();
 239  0
         int offset = tz.getOffset(cal.get(Calendar.ERA), 
 240   
                                   cal.get(Calendar.YEAR),
 241   
                                   cal.get(Calendar.MONTH),
 242   
                                   cal.get(Calendar.DAY_OF_MONTH),
 243   
                                   cal.get(Calendar.DAY_OF_WEEK),
 244   
                                   cal.get(Calendar.MILLISECOND));
 245  0
         StringBuffer tzMarker = new StringBuffer(offset < 0 ? "-" : "+");
 246  0
         offset = Math.abs(offset);
 247  0
         int hours = offset / (60 * 60 * 1000);
 248  0
         int minutes = offset / (60 * 1000) - 60 * hours;
 249  0
         if (hours < 10) {
 250  0
             tzMarker.append("0");
 251   
         }
 252  0
         tzMarker.append(hours);
 253  0
         if (minutes < 10) {
 254  0
             tzMarker.append("0");
 255   
         }
 256  0
         tzMarker.append(minutes);
 257  0
         return DATE_HEADER_FORMAT.format(cal.getTime()) + tzMarker.toString();
 258   
     }
 259   
 }
 260