/******************************************************************************* * * Copyright 2010 Alexandru Craciun, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. ******************************************************************************/ package org.netxilia.api.utils; import java.util.HashSet; import java.util.Locale; import java.util.Set; import org.joda.time.Chronology; import org.joda.time.DateTime; import org.joda.time.DateTimeField; import org.joda.time.DateTimeFieldType; import org.joda.time.DurationFieldType; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; import org.joda.time.ReadablePartial; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeParserBucket; /** * * @author <a href='mailto:ax.craciun@gmail.com'>Alexandru Craciun</a> * */ public class DateUtils { /** * * @param formatter * @param text * @return the ReadablePartial corresponding to the given formatter and text */ public static ReadablePartial parsePartial(DateTimeFormatter formatter, String text) { PartialDateTimeParserBucket bucket = new PartialDateTimeParserBucket(); int newPos = formatter.getParser().parseInto(bucket, text, 0); if (newPos >= 0 && newPos >= text.length()) { long millis = bucket.computeMillis(true, text); DateTime dt = new DateTime(millis, (Chronology) null); if (bucket.isHasDate() && bucket.isHasTime()) { return dt.toLocalDateTime(); } if (bucket.isHasDate()) { return dt.toLocalDate(); } return dt.toLocalTime(); } throw new IllegalArgumentException("Cannot parse date:" + text); } public static Class<? extends ReadablePartial> getPartialClass(DateTimeFormatter dateTimeFormatter) { String text = dateTimeFormatter.print(System.currentTimeMillis()); ReadablePartial parsed = parsePartial(dateTimeFormatter, text); return parsed.getClass(); } public static LocalDateTime toLocalDateTime(ReadablePartial partial, LocalDateTime fullDateTime) { if (partial instanceof LocalDateTime) { return (LocalDateTime) partial; } if (partial instanceof LocalDate) { LocalDate d = (LocalDate) partial; return new LocalDateTime(d.getYear(), d.getMonthOfYear(), d.getDayOfMonth(), fullDateTime.getHourOfDay(), fullDateTime.getMinuteOfHour(), fullDateTime.getSecondOfMinute(), fullDateTime.getMillisOfSecond()); } if (partial instanceof LocalTime) { LocalTime t = (LocalTime) partial; return new LocalDateTime(fullDateTime.getYear(), fullDateTime.getMonthOfYear(), fullDateTime .getDayOfMonth(), t.getHourOfDay(), t.getMinuteOfHour(), t.getSecondOfMinute(), t .getMillisOfSecond()); } throw new IllegalArgumentException("The partial parameter has an unsupported class:" + partial.getClass()); } public static LocalDate toLocalDate(ReadablePartial partial, LocalDate fullDate) { if (partial instanceof LocalDateTime) { LocalDateTime d = (LocalDateTime) partial; return d.toLocalDate(); } if (partial instanceof LocalDate) { return (LocalDate) partial; } if (partial instanceof LocalTime) { return fullDate; } throw new IllegalArgumentException("The partial parameter has an unsupported class:" + partial.getClass()); } public static int getField(ReadablePartial partial, LocalDateTime fullDateTime, DateTimeFieldType field) { return partial.isSupported(field) ? partial.get(field) : fullDateTime.get(field); } /** * * Tracks the types of field set. * */ private static class PartialDateTimeParserBucket extends DateTimeParserBucket { private static final Set<DurationFieldType> TIME_DURATION_TYPES = new HashSet<DurationFieldType>(); static { TIME_DURATION_TYPES.add(DurationFieldType.millis()); TIME_DURATION_TYPES.add(DurationFieldType.seconds()); TIME_DURATION_TYPES.add(DurationFieldType.minutes()); TIME_DURATION_TYPES.add(DurationFieldType.hours()); } private boolean hasTime = false; private boolean hasDate = false; public PartialDateTimeParserBucket() { super(0, null, null); } private void checkDateTime(DateTimeFieldType fieldType) { boolean isTime = TIME_DURATION_TYPES.contains(fieldType.getDurationType()); hasTime = isTime || hasTime; hasDate = !isTime || hasDate; } public boolean isHasTime() { return hasTime; } public boolean isHasDate() { return hasDate; } @Override public void saveField(DateTimeField field, int value) { checkDateTime(field.getType()); super.saveField(field, value); } @Override public void saveField(DateTimeFieldType fieldType, int value) { checkDateTime(fieldType); super.saveField(fieldType, value); } @Override public void saveField(DateTimeFieldType fieldType, String text, Locale locale) { checkDateTime(fieldType); super.saveField(fieldType, text, locale); } } }