001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020package org.apache.isis.core.progmodel.facets.value.datejodalocal; 021 022import java.util.List; 023import java.util.StringTokenizer; 024 025import com.google.common.collect.Iterables; 026 027import org.joda.time.LocalDate; 028import org.joda.time.format.DateTimeFormatter; 029 030import org.apache.isis.applib.profiles.Localization; 031import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException; 032import org.apache.isis.core.progmodel.facets.value.JodaFunctions; 033 034public final class JodaLocalDateUtil { 035 036 private JodaLocalDateUtil(){} 037 038 static LocalDate parseDate(final String dateStr, final Localization localization, List<DateTimeFormatter> parseFormatters) { 039 Iterable<DateTimeFormatter> elements = Iterables.transform(parseFormatters, JodaFunctions.withLocale(localization)); 040 LocalDate parsedDate = parseDate(dateStr, elements); 041 return parsedDate; 042 } 043 044 045 private static LocalDate parseDate(String dateStr, Iterable<DateTimeFormatter> formatters) { 046 for(DateTimeFormatter formatter: formatters) { 047 try { 048 return formatter.parseLocalDate(dateStr); 049 } catch (final IllegalArgumentException e) { 050 // continue to next 051 } 052 } 053 throw new TextEntryParseException("Not recognised as a date: " + dateStr); 054 } 055 056 // ////////////////////////////////////// 057 058 static LocalDate relativeDate(final LocalDate contextDate, final String str, final boolean add) { 059 LocalDate relativeDate = contextDate; 060 if (str.equals("")) { 061 return contextDate; 062 } 063 064 try { 065 final StringTokenizer st = new StringTokenizer(str.substring(1), " "); 066 while (st.hasMoreTokens()) { 067 final String token = st.nextToken(); 068 relativeDate = adjustDate(relativeDate, token, add); 069 } 070 return relativeDate; 071 } catch (final Exception e) { 072 return contextDate; 073 } 074 } 075 076 private static LocalDate adjustDate(final LocalDate contextDate, String str, final boolean add) { 077 int hours = 0; 078 int minutes = 0; 079 int days = 0; 080 int months = 0; 081 int years = 0; 082 083 if (str.endsWith("H")) { 084 str = str.substring(0, str.length() - 1); 085 hours = Integer.valueOf(str).intValue(); 086 } else if (str.endsWith("M")) { 087 str = str.substring(0, str.length() - 1); 088 minutes = Integer.valueOf(str).intValue(); 089 } else if (str.endsWith("w")) { 090 str = str.substring(0, str.length() - 1); 091 days = 7 * Integer.valueOf(str).intValue(); 092 } else if (str.endsWith("y")) { 093 str = str.substring(0, str.length() - 1); 094 years = Integer.valueOf(str).intValue(); 095 } else if (str.endsWith("m")) { 096 str = str.substring(0, str.length() - 1); 097 months = Integer.valueOf(str).intValue(); 098 } else if (str.endsWith("d")) { 099 str = str.substring(0, str.length() - 1); 100 days = Integer.valueOf(str).intValue(); 101 } else { 102 days = Integer.valueOf(str).intValue(); 103 } 104 105 if (add) { 106 return add(contextDate, years, months, days, hours, minutes); 107 } else { 108 return add(contextDate, -years, -months, -days, -hours, -minutes); 109 } 110 } 111 112 private static LocalDate add(final LocalDate original, final int years, final int months, final int days, final int hours, final int minutes) { 113 if(hours != 0 || minutes != 0) { 114 throw new IllegalArgumentException("cannot add non-zero hours or minutes to a LocalDate"); 115 } 116 return original.plusYears(years).plusMonths(months).plusDays(days); 117 } 118 119 120 // ////////////////////////////////////// 121 122 public static String titleString(final DateTimeFormatter formatter, final LocalDate date) { 123 return date == null ? "" : formatter.print(date); 124 } 125 126 127}