/*******************************************************************************
* Copyright (c) 2010 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/
package org.epics.archiverappliance.engine.model;
/** Parser for scan or update periods
* @author Kay Kasemir
*/
public class PeriodFormat
{
/** Identifier for 'day' units */
private static final String DAYS = "days"; //$NON-NLS-1$
/** Identifier for 'hour' units */
private static final String HOURS = "hours"; //$NON-NLS-1$
/** Identifier for 'minute' units */
private static final String MINUTES = "minutes"; //$NON-NLS-1$
/** Identifier for 'second' units */
private static final String SECONDS = "seconds"; //$NON-NLS-1$
/** Seconds per minute */
private static final double SEC_PER_MIN = 60.0;
/** Seconds per hour */
private static final double SEC_PER_HOUR = 60.0*SEC_PER_MIN;
/** Seconds per day */
private static final double SEC_PER_DAY = 24.0*SEC_PER_HOUR;
/** Parse seconds from text.
* <p>
* Text must contain a (double) number,
* optionally followed by units "days", "hours", "minutes", "seconds".
* Only "m", "min", ... is interpreted as "minutes" as well.
* In the absense of units, it defaults to seconds.
*
* @param text Text to parse
* @return seconds
*/
public static double parseSeconds(String text)
{
text = text.trim().toLowerCase();
int units = findUnits(text, DAYS);
if (units > 0)
{
final double days = Double.parseDouble(text.substring(0, units));
return days*SEC_PER_DAY;
}
units = findUnits(text, HOURS);
if (units > 0)
{
final double hours = Double.parseDouble(text.substring(0, units));
return hours*SEC_PER_HOUR;
}
units = findUnits(text, MINUTES);
if (units > 0)
{
final double min = Double.parseDouble(text.substring(0, units));
return min*SEC_PER_MIN;
}
units = findUnits(text, SECONDS);
if (units < 0)
units = text.length();
return Double.parseDouble(text.substring(0, units));
}
/** Format seconds as string, using hours or minutes if appropriate.
* @param seconds Seconds to format
* @return A string that <code>parseSeconds()</code> can handle.
*/
@SuppressWarnings("nls")
public static String formatSeconds(double seconds)
{
if (seconds >= SEC_PER_DAY)
{
final double days = seconds/SEC_PER_DAY;
return String.format("%.2f days", days);
}
if (seconds >= SEC_PER_HOUR)
{
final double hours = seconds/SEC_PER_HOUR;
return String.format("%.2f h", hours);
}
if (seconds >= SEC_PER_MIN)
{
final double minutes = seconds/SEC_PER_MIN;
return String.format("%.2f min", minutes);
}
return String.format("%.2f sec", seconds);
}
/** Locate given "units", "unit", "uni", ... "u" in text.
* @param text Text to search
* @param units Units to locate
* @return Location of units in text, or -1
*/
private static int findUnits(final String text, final String units)
{
final String NUM_OR_SPACE = " 0123456789."; //$NON-NLS-1$
for (int len = units.length(); len > 0; --len)
{
final int pos = text.indexOf(units.substring(0, len));
if (pos > 0)
{
// Just before that position, there should be a space
// or the number. Don't find the "d" of "days" in "seconds".
final char prev_char = text.charAt(pos-1);
if (NUM_OR_SPACE.indexOf(prev_char) >= 0)
return pos;
}
}
return -1;
}
}