All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.addthis.basis.time.Dates Maven / Gradle / Ivy

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.addthis.basis.time;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;

import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;


public class Dates {
    public static final DateTimeFormatter rfc1123 = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z");
    public static final DateTimeFormatter yMdFormat = DateTimeFormat.forPattern("yyyy-MM-dd");

    /**
     * Convenience method to create a new single field period of arbitrary type
     * (e.g. 10 days, 6 months, etc.)
     * 

* Requires that type be a single field period * * @param length * @param type * @return */ public static Period period(int length, PeriodType type) { return new Period(null, type).withField(type.getFieldType(0), length); } /** * Truncate interval start and end by current time * (start/end values after current time are set to current time) *

* Truncate interval start by a specified number of period types * (eg. 30 days, 52 weeks, etc.) *

* If type is null, no truncation is performed. *

* When no truncation is performed, the input interval is returned * (this is useful for efficiently testing if truncation was performed). * * @param interval * @param limit number of TYPE periods above which interval should be truncated * @param type single field period type (the result of this method is undefined for multi-field period types) * @return */ public static Interval truncateInterval(Interval interval, int limit, PeriodType type) { Interval truncatedInterval = interval; if (type != null) { // Truncate end DateTime now = new DateTime(); if (interval.getEnd().isAfter(now)) { if (interval.getStart().isAfter(now)) { truncatedInterval = new Interval(now, now); } else { truncatedInterval = interval.withEnd(now); } } // Truncate start if (truncatedInterval.toPeriod(type).getValue(0) > --limit) { Period limitPeriod = period(limit, type); DateTime truncatedStart = truncatedInterval.getEnd().minus(limitPeriod); truncatedInterval = truncatedInterval.withStart(truncatedStart); } } return truncatedInterval; } /** * Create an interval from two date strings *

* begStr | endStr | return * ------------------------- * bad | bad | (now, now) * bad | E | (E, E) * B | bad | (B, B) * B | E | (B, E) * B(>E)| E( * ("bad" in the table above indicates that the input * is either null or fails to parse) *

* TODO: accept default beg/end parameters * * @param begStr beginning of interval * @param endStr end of interval * @return */ public static Interval parseInterval(String begStr, String endStr, DateTimeFormatter format) { DateTime beg = null; DateTime end = null; boolean begFailed = false; boolean endFailed = false; try { beg = format.parseDateTime(begStr); } catch (Exception e) { begFailed = true; } try { end = format.parseDateTime(endStr); } catch (Exception e) { endFailed = true; } if (begFailed && endFailed) { end = beg = new DateTime(); } else if (begFailed) { beg = end; } else if (endFailed) { end = beg; } if (beg.isAfter(end)) { beg = end; } return new Interval(beg, end); } /** * Create an interval from two date strings in yyyy-MM-dd format * * @param begStr * @param endStr * @return */ public static Interval parseInterval(String begStr, String endStr) { return parseInterval(begStr, endStr, yMdFormat); } /* * Java Date methods * (deprecated - use Joda time and std formats) */ public static final DateTimeFormatter yMdHFormat = DateTimeFormat.forPattern("yyMMddHH"); /** * @param d * @return Date with same date as d and time 23:59:59:999 */ public static Date endOfDay(Date d) { Calendar calendar = new GregorianCalendar(); calendar.setTime(d); calendar.set(Calendar.AM_PM, Calendar.PM); calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); calendar.set(Calendar.HOUR, calendar.getActualMaximum(Calendar.HOUR)); return calendar.getTime(); } /** * @param d * @return Date with same date as d and time 00:00:00:000 */ public static Date begOfDay(Date d) { Calendar calendar = new GregorianCalendar(); calendar.setTime(d); calendar.set(Calendar.AM_PM, Calendar.AM); calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); calendar.set(Calendar.HOUR, calendar.getActualMinimum(Calendar.HOUR)); return calendar.getTime(); } /** * For iterating over the period units in an interval (inclusive of start and end) *

* e.g. iterating over [2008-01-01, 2008-01-03] by DAYS will result in a series of * DateTime objects which when formatted as above produce the following: * 2008-01-01, 2008-01-02, 2008-01-03 * regardless of the time fields in the input interval * * @param interval * @return */ public static Iterable iterableInterval(Interval interval, DTimeUnit type) { return new IterableInterval(interval, type); } public static Iterator intervalIterator(Interval interval, DTimeUnit type) { return new IterableInterval(interval, type); } private static class IterableInterval implements Iterable, Iterator { private DateTime end; private DateTime currentInstant; private Period increment; public IterableInterval(Interval interval, DTimeUnit per) { if (per == DTimeUnit.ALL_TIME) { this.increment = period(1, PeriodType.millis()); this.end = interval.getStart(); this.currentInstant = end.minus(increment); } else { this.increment = period(1, per.toPeriodType()); this.end = interval.getEnd().property(per.toDateTimeFieldType()).roundFloorCopy(); this.currentInstant = interval.getStart().minus(increment); } } public Iterator iterator() { return this; } /* (non-Javadoc) * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return currentInstant.isBefore(end); } /* (non-Javadoc) * @see java.util.Iterator#next() */ public DateTime next() { currentInstant = currentInstant.plus(increment); return currentInstant; } /* (non-Javadoc) * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy