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

org.jresearch.ical.util.DTBuilder Maven / Gradle / Ivy

Go to download

RFC 2445 defines protocols for interoperability between calendar applications, and this library provides java implementations for a number of RFC 2445 primitives including those that describe how events repeat. Start by taking alook at the compat packages.

There is a newer version: 1.0.11
Show newest version
// Copyright (C) 2006 Google Inc.
//
// 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 org.jresearch.ical.util;

import org.jresearch.ical.values.DateTimeValue;
import org.jresearch.ical.values.DateTimeValueImpl;
import org.jresearch.ical.values.DateValue;
import org.jresearch.ical.values.DateValueImpl;
import org.jresearch.ical.values.TimeValue;

/**
 * a mutable buffer that can be used to build {@link DateValue}s and
 * {@link DateTimeValue}s.
 *
 * @author [email protected] (Mike Samuel)
 */
public class DTBuilder {

	/** in AD. 0 to 1BC. */
	public int year;
	/** one indexed. */
	public int month;
	/** one indexed */
	public int day;
	/** zero indexed in 24 hour time. */
	public int hour;
	/** zero indexed */
	public int minute;
	/** zero indexed */
	public int second;

	public DTBuilder(final int year, final int month, final int day,
			final int hour, final int minute, final int second) {
		this.year = year;
		this.month = month;
		this.day = day;
		this.hour = hour;
		this.minute = minute;
		this.second = second;
	}

	public DTBuilder(final int year, final int month, final int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}

	public DTBuilder(final DateValue dv) {
		this.year = dv.year();
		this.month = dv.month();
		this.day = dv.day();
		if (dv instanceof TimeValue) {
			final TimeValue tv = (TimeValue) dv;
			this.hour = tv.hour();
			this.minute = tv.minute();
			this.second = tv.second();
		}
	}

	/**
	 * produces a normalized date time, using zero for the time fields if none
	 * were provided.
	 * 
	 * @return not null
	 */
	public DateTimeValue toDateTime() {
		normalize();
		return new DateTimeValueImpl(year, month, day, hour, minute, second);
	}

	/**
	 * produces a normalized date.
	 * 
	 * @return not null
	 */
	public DateValue toDate() {
		normalize();
		return new DateValueImpl(year, month, day);
	}

	/**
	 * behavior undefined unless normalized. If you're not sure whether it's
	 * appropriate to use this method, use
	 * toDateValue().compareTo(dv) instead.
	 */
	public int compareTo(final DateValue dv) {
		long dvComparable = (((((long) dv.year()) << 4) + dv.month()) << 5) + dv.day();
		long dtbComparable = ((((long) year << 4) + month << 5)) + day;
		if (dv instanceof TimeValue) {
			final TimeValue tv = (TimeValue) dv;
			dvComparable = (((((dvComparable << 5) + tv.hour()) << 6) + tv.minute()) << 6) + tv.second();
			dtbComparable = (((((dtbComparable << 5) + hour) << 6) + minute) << 6) + second;
		}
		final long delta = dtbComparable - dvComparable;
		return delta < 0 ? -1 : delta == 0 ? 0 : 1;
	}

	/**
	 * makes sure that the fields are in the proper ranges, by e.g. converting
	 * 32 January to 1 February, or month 0 to December of the year before.
	 */
	public void normalize() {
		this.normalizeTime();
		this.normalizeDate();
	}

	@Override
	public String toString() {
		return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":"
				+ second;
	}

	@Override
	public boolean equals(final Object o) {
		if (!(o instanceof DTBuilder)) {
			return false;
		}
		final DTBuilder that = (DTBuilder) o;
		return this.year == that.year
				&& this.month == that.month
				&& this.day == that.day
				&& this.hour == that.hour
				&& this.minute == that.minute
				&& this.second == that.second;
	}

	@Override
	public int hashCode() {
		return ((((((((year << 4) + month << 5) + day) << 5) + hour) << 6) + minute) << 6) + second;
	}

	private void normalizeTime() {
		final int addMinutes = ((second < 0) ? (second - 59) : second) / 60;
		second -= addMinutes * 60;
		minute += addMinutes;
		final int addHours = ((minute < 0) ? (minute - 59) : minute) / 60;
		minute -= addHours * 60;
		hour += addHours;
		final int addDays = ((hour < 0) ? (hour - 23) : hour) / 24;
		hour -= addDays * 24;
		day += addDays;
	}

	private void normalizeDate() {
		while (day <= 0) {
			final int days = TimeUtils.yearLength(month > 2 ? year : year - 1);
			day += days;
			--year;
		}
		if (month <= 0) {
			final int years = month / 12 - 1;
			year += years;
			month -= 12 * years;
		} else if (month > 12) {
			final int years = (month - 1) / 12;
			year += years;
			month -= 12 * years;
		}
		while (true) {
			if (month == 1) {
				final int yearLength = TimeUtils.yearLength(year);
				if (day > yearLength) {
					++year;
					day -= yearLength;
				}
			}
			final int monthLength = TimeUtils.monthLength(year, month);
			if (day > monthLength) {
				day -= monthLength;
				if (++month > 12) {
					month -= 12;
					++year;
				}
			} else {
				break;
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy