/**
* Copyright Intellectual Reserve, 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.gedcomx.date;
/**
* A Date Range
* @author John Clark.
*/
public class GedcomxDateRange extends GedcomxDate {
private boolean approximate = false;
private GedcomxDateSimple start = null;
private GedcomxDateDuration duration = null;
private GedcomxDateSimple end = null;
/**
* Instantiate a new Range date from the formal string
* @param date The formal date string
*/
public GedcomxDateRange(String date) {
if(date == null || date.length() < 1) {
throw new GedcomxDateException("Invalid Range");
}
String range = date;
// If range starts with A it is recurring
if(date.charAt(0) == 'A') {
approximate = true;
range = date.substring(1);
}
// / is required
if(!date.contains("/")) {
throw new GedcomxDateException("Invalid Range: / is required");
}
/**
* range -> parts
* / -> []
* +1000/ -> ["+1000"]
* /+1000 -> ["","+1000"]
* +1000/+2000 -> ["+1000","+2000"]
*/
String[] parts = range.split("/");
if(parts.length < 1 || parts.length > 2) {
throw new GedcomxDateException("Invalid Range: One or two parts are required");
}
if(!parts[0].equals("")) {
try {
start = new GedcomxDateSimple(parts[0]);
} catch (GedcomxDateException e) {
throw new GedcomxDateException(e.getMessage() + " in Range Start Date");
}
}
if(parts.length == 2) {
if (parts[1].charAt(0) == 'P') {
if(start == null) {
throw new GedcomxDateException("Invalid Range: A range may not end with a duration if missing a start date");
}
try {
duration = new GedcomxDateDuration(parts[1]);
} catch(GedcomxDateException e) {
throw new GedcomxDateException(e.getMessage() + " in Range End Duration");
}
// Use the duration to calculate the end date
end = GedcomxDateUtil.addDuration(start, duration);
} else {
try {
end = new GedcomxDateSimple(parts[1]);
} catch(GedcomxDateException e) {
throw new GedcomxDateException(e.getMessage() + " in Range End Date");
}
if(start != null) {
duration = GedcomxDateUtil.getDuration(start, end);
}
}
}
}
/**
* Get the start of the range
* @return The Start Date
*/
public GedcomxDateSimple getStart() {
return start;
}
/**
* Get the duration between the start and end dates
* @return The Duration
*/
public GedcomxDateDuration getDuration() {
return duration;
}
/**
* Get the end of the range
* @return The End Date
*/
public GedcomxDateSimple getEnd() {
return end;
}
/**
* Get the type of this date
* @return The Date Type
*/
@Override
public GedcomxDateType getType() {
return GedcomxDateType.RANGE;
}
/**
* Whether or not this date is considered approximate
* @return True if it this date is approximate
*/
@Override
public boolean isApproximate() {
return approximate;
}
/**
* Return the formal string for this date
* @return The formal string
*/
@Override
public String toFormalString() {
StringBuilder range = new StringBuilder();
if(approximate) {
range.append('A');
}
if(start != null) {
range.append(start.toFormalString());
}
range.append('/');
if(duration != null) {
range.append(duration.toFormalString());
} else if(end != null) {
range.append(end.toFormalString());
}
return range.toString();
}
}