src/net/fortuna/ical4j/util/Dates.java

Tue, 10 Feb 2015 18:12:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 10 Feb 2015 18:12:00 +0100
changeset 0
fb9019fb1bf7
permissions
-rw-r--r--

Import initial revisions of existing project AndroidCaldavSyncAdapater,
forked from upstream repository at 27e8a0f8495c92e0780d450bdf0c7cec77a03a55.

     1 /**
     2  * Copyright (c) 2012, Ben Fortuna
     3  * All rights reserved.
     4  *
     5  * Redistribution and use in source and binary forms, with or without
     6  * modification, are permitted provided that the following conditions
     7  * are met:
     8  *
     9  *  o Redistributions of source code must retain the above copyright
    10  * notice, this list of conditions and the following disclaimer.
    11  *
    12  *  o Redistributions in binary form must reproduce the above copyright
    13  * notice, this list of conditions and the following disclaimer in the
    14  * documentation and/or other materials provided with the distribution.
    15  *
    16  *  o Neither the name of Ben Fortuna nor the names of any other contributors
    17  * may be used to endorse or promote products derived from this software
    18  * without specific prior written permission.
    19  *
    20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  */
    32 package net.fortuna.ical4j.util;
    34 import java.text.MessageFormat;
    35 import java.util.ArrayList;
    36 import java.util.Calendar;
    37 import java.util.List;
    38 import java.util.TimeZone;
    40 import net.fortuna.ical4j.model.Date;
    41 import net.fortuna.ical4j.model.DateTime;
    42 import net.fortuna.ical4j.model.parameter.Value;
    44 /**
    45  * $Id$
    46  *
    47  * Created on 26/06/2005
    48  *
    49  * Implements a collection of utility methods relevant to date processing.
    50  * 
    51  * @author Ben Fortuna
    52  */
    53 public final class Dates {
    55     /**
    56      * Number of milliseconds in one second.
    57      */
    58     public static final long MILLIS_PER_SECOND = 1000;
    60     /**
    61      * Number of milliseconds in one minute.
    62      */
    63     public static final long MILLIS_PER_MINUTE = 60000;
    65     /**
    66      * Number of milliseconds in one hour.
    67      */
    68     public static final long MILLIS_PER_HOUR = 3600000;
    70     /**
    71      * Number of milliseconds in one day.
    72      */
    73     public static final long MILLIS_PER_DAY = 86400000;
    75     /**
    76      * Number of milliseconds in one week.
    77      */
    78     public static final long MILLIS_PER_WEEK = 604800000;
    80     /**
    81      * Number of days in one week.
    82      */
    83     public static final int DAYS_PER_WEEK = 7;
    85     /**
    86      * Constant indicating precision to the second.
    87      */
    88     public static final int PRECISION_SECOND = 0;
    90     /**
    91      * Constant indicating precision to the day.
    92      */
    93     public static final int PRECISION_DAY = 1;
    95     /**
    96      * Maximum number of weeks per year.
    97      */
    98     public static final int MAX_WEEKS_PER_YEAR = 53;
   100     /**
   101      * Maximum number of days per year.
   102      */
   103     public static final int MAX_DAYS_PER_YEAR = 366;
   105     /**
   106      * Maximum number of days per month.
   107      */
   108     public static final int MAX_DAYS_PER_MONTH = 31;
   110     private static final String INVALID_WEEK_MESSAGE = "Invalid week number [{0}]";
   112     private static final String INVALID_YEAR_DAY_MESSAGE = "Invalid year day [{0}]";
   114     private static final String INVALID_MONTH_DAY_MESSAGE = "Invalid month day [{0}]";
   116     /**
   117      * Constructor made private to prevent instantiation.
   118      */
   119     private Dates() {
   120     }
   122     /**
   123      * Returns the absolute week number for the year specified by the
   124      * supplied date. Note that a value of zero (0) is invalid for the
   125      * weekNo parameter and an <code>IllegalArgumentException</code>
   126      * will be thrown.
   127      * @param date a date instance representing a week of the year
   128      * @param weekNo a week number offset
   129      * @return the absolute week of the year for the specified offset
   130      */
   131     public static int getAbsWeekNo(final java.util.Date date, final int weekNo) {
   132         if (weekNo == 0 || weekNo < -MAX_WEEKS_PER_YEAR || weekNo > MAX_WEEKS_PER_YEAR) {
   133             throw new IllegalArgumentException(MessageFormat.format(INVALID_WEEK_MESSAGE,
   134                     new Object[] {new Integer(weekNo)}));
   135         }
   136         if (weekNo > 0) {
   137             return weekNo;
   138         }
   139         final Calendar cal = Calendar.getInstance();
   140         cal.setTime(date);
   141         final int year = cal.get(Calendar.YEAR);
   142         // construct a list of possible week numbers..
   143         final List weeks = new ArrayList();
   144         cal.set(Calendar.WEEK_OF_YEAR, 1);
   145         while (cal.get(Calendar.YEAR) == year) {
   146             weeks.add(new Integer(cal.get(Calendar.WEEK_OF_YEAR)));
   147             cal.add(Calendar.WEEK_OF_YEAR, 1);
   148         }
   149         return ((Integer) weeks.get(weeks.size() + weekNo)).intValue();
   150     }
   152     /**
   153      * Returns the absolute year day for the year specified by the
   154      * supplied date. Note that a value of zero (0) is invalid for the
   155      * yearDay parameter and an <code>IllegalArgumentException</code>
   156      * will be thrown.
   157      * @param date a date instance representing a day of the year
   158      * @param yearDay a day of year offset
   159      * @return the absolute day of month for the specified offset
   160      */
   161     public static int getAbsYearDay(final java.util.Date date, final int yearDay) {
   162         if (yearDay == 0 || yearDay < -MAX_DAYS_PER_YEAR || yearDay > MAX_DAYS_PER_YEAR) {
   163             throw new IllegalArgumentException(MessageFormat.format(INVALID_YEAR_DAY_MESSAGE,
   164                     new Object[] {new Integer(yearDay)}));
   165         }
   166         if (yearDay > 0) {
   167             return yearDay;
   168         }
   169         final Calendar cal = Calendar.getInstance();
   170         cal.setTime(date);
   171         final int year = cal.get(Calendar.YEAR);
   172         // construct a list of possible year days..
   173         final List days = new ArrayList();
   174         cal.set(Calendar.DAY_OF_YEAR, 1);
   175         while (cal.get(Calendar.YEAR) == year) {
   176             days.add(new Integer(cal.get(Calendar.DAY_OF_YEAR)));
   177             cal.add(Calendar.DAY_OF_YEAR, 1);
   178         }
   179         return ((Integer) days.get(days.size() + yearDay)).intValue();
   180     }
   182     /**
   183      * Returns the absolute month day for the month specified by the
   184      * supplied date. Note that a value of zero (0) is invalid for the
   185      * monthDay parameter and an <code>IllegalArgumentException</code>
   186      * will be thrown.
   187      * @param date a date instance representing a day of the month
   188      * @param monthDay a day of month offset
   189      * @return the absolute day of month for the specified offset
   190      */
   191     public static int getAbsMonthDay(final java.util.Date date, final int monthDay) {
   192         if (monthDay == 0 || monthDay < -MAX_DAYS_PER_MONTH || monthDay > MAX_DAYS_PER_MONTH) {
   193             throw new IllegalArgumentException(MessageFormat.format(INVALID_MONTH_DAY_MESSAGE,
   194                     new Object[] {new Integer(monthDay)}));
   195         }
   196         if (monthDay > 0) {
   197             return monthDay;
   198         }
   199         final Calendar cal = Calendar.getInstance();
   200         cal.setTime(date);
   201         final int month = cal.get(Calendar.MONTH);
   202         // construct a list of possible month days..
   203         final List days = new ArrayList();
   204         cal.set(Calendar.DAY_OF_MONTH, 1);
   205         while (cal.get(Calendar.MONTH) == month) {
   206             days.add(new Integer(cal.get(Calendar.DAY_OF_MONTH)));
   207             cal.add(Calendar.DAY_OF_MONTH, 1);
   208         }
   209         return ((Integer) days.get(days.size() + monthDay)).intValue();
   210     }
   212     /**
   213      * Returns a new date instance of the specified type. If no type is
   214      * specified a DateTime instance is returned.
   215      * @param date a seed Java date instance
   216      * @param type the type of date instance
   217      * @return an instance of <code>net.fortuna.ical4j.model.Date</code>
   218      */
   219     public static Date getInstance(final java.util.Date date, final Value type) {
   220         if (Value.DATE.equals(type)) {
   221             return new Date(date);
   222         }
   223         return new DateTime(date);
   224     }
   226     /**
   227      * Returns an instance of <code>java.util.Calendar</code> that is suitably
   228      * initialised for working with the specified date.
   229      * @param date a date instance
   230      * @return a <code>java.util.Calendar</code>
   231      */
   232     public static Calendar getCalendarInstance(final Date date) {
   233         Calendar instance = null;
   234         if (date instanceof DateTime) {
   235             final DateTime dateTime = (DateTime) date;
   236             if (dateTime.getTimeZone() != null) {
   237                 instance = Calendar.getInstance(dateTime.getTimeZone());
   238             }
   239             else if (dateTime.isUtc()) {
   240                 instance = Calendar.getInstance(TimeZones.getUtcTimeZone());
   241             }
   242             else {
   243             	// a date-time without a timezone but not UTC is floating
   244                 instance = Calendar.getInstance();
   245             }
   246         }
   247         else {
   248             instance = Calendar.getInstance(TimeZones.getDateTimeZone());
   249         }
   250         return instance;
   251     }
   253     /**
   254      * @param time the time value to round
   255      * @param precision the rounding precision
   256      * @return a round time value
   257      * @deprecated It is not all that useful to perform rounding without specifying an
   258      * explicit timezone.
   259      */
   260     public static long round(final long time, final int precision) {
   261         return round(time, precision, TimeZone.getDefault());
   262 //        return round(time, precision, TimeZone.getTimeZone(TimeZones.UTC_ID));
   263         /*
   264         long newTime = time;
   265         if (precision == PRECISION_DAY) {
   266             long remainder = newTime%(1000*60*60); // get the mod remainder using milliseconds*seconds*min
   267             newTime = newTime-remainder;
   268               // remove the remainder from the time to clear the milliseconds, seconds and minutes
   269         }
   270         else if (precision == PRECISION_SECOND) {
   271             long remainder = newTime%(1000); // get the mod remainder using milliseconds
   272             newTime = newTime-remainder;  // remove the remainder from the time to clear the milliseconds
   273         }
   274         return newTime;
   275 	*/
   276     }
   278     /**
   279      * Rounds a time value to remove any precision smaller than specified.
   280      * @param time the time value to round
   281      * @param precision the rounding precision
   282      * @param tz the timezone of the rounded value
   283      * @return a round time value
   284      */
   285     public static long round(final long time, final int precision, final TimeZone tz) {
   286         if ((precision == PRECISION_SECOND) && ((time % Dates.MILLIS_PER_SECOND) == 0)) {
   287             return time;
   288         }
   289         final Calendar cal = Calendar.getInstance(tz);
   290         cal.setTimeInMillis(time);
   291         if (precision == PRECISION_DAY) {
   292 //            return (long) Math.floor(time / (double) Dates.MILLIS_PER_DAY) * Dates.MILLIS_PER_DAY;
   293             cal.set(Calendar.HOUR_OF_DAY, 0);
   294             cal.clear(Calendar.MINUTE);
   295             cal.clear(Calendar.SECOND);
   296             cal.clear(Calendar.MILLISECOND);
   297         }
   298         else if (precision == PRECISION_SECOND) {
   299 //            return (long) Math.floor(time / (double) Dates.MILLIS_PER_SECOND) * Dates.MILLIS_PER_SECOND;
   300             cal.clear(Calendar.MILLISECOND);
   301         }
   302         // unrecognised precision..
   303         return cal.getTimeInMillis();
   304     }
   306     /**
   307      * Returns the {@code System.currentTimeMillis()}, rounded to the second.
   308      * <p>By doing a rough rounding here, we avoid an expensive java.util.Calendar based
   309      *  rounding later on.</p>
   310      * @return the current time in millisec.
   311      */
   312     public static long getCurrentTimeRounded() {
   313         return (long) Math.floor(System.currentTimeMillis() / (double) Dates.MILLIS_PER_SECOND) * Dates.MILLIS_PER_SECOND;
   314     }
   315 }

mercurial