parent
a76d5cb1ac
commit
0373867875
10 changed files with 250 additions and 51 deletions
@ -0,0 +1,181 @@ |
|||||||
|
package com.mousetech.gourmetj.utils; |
||||||
|
|
||||||
|
import java.util.Scanner; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handle conversion of complex time fields where days, hours, |
||||||
|
* minutes and seconds may be present as separate entities. |
||||||
|
* |
||||||
|
* @author timh |
||||||
|
* @since Jan 8, 2022 |
||||||
|
*/ |
||||||
|
public class TimeFormatter { |
||||||
|
|
||||||
|
/* Logger */ |
||||||
|
|
||||||
|
private static final Logger log = |
||||||
|
LoggerFactory.getLogger(TimeFormatter.class); |
||||||
|
|
||||||
|
public static String formatTime(Long ltime) { |
||||||
|
if (ltime == null) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
int time = ltime.intValue(); |
||||||
|
int dd, hh, mm, ss; |
||||||
|
ss = time % 60; |
||||||
|
time /= 60; |
||||||
|
mm = time % 60; |
||||||
|
time /= 60; |
||||||
|
hh = time % 24; |
||||||
|
dd = time / 24; |
||||||
|
StringBuffer sb = new StringBuffer(20); |
||||||
|
if (dd > 0) { |
||||||
|
sb.append(dd).append("d "); |
||||||
|
} |
||||||
|
if (hh > 0) { |
||||||
|
sb.append(hh).append("h "); |
||||||
|
} |
||||||
|
if (mm > 0) { |
||||||
|
sb.append(mm); |
||||||
|
if ((ss == 0) && (hh == 0)) { |
||||||
|
sb.append(" minutes"); |
||||||
|
} else { |
||||||
|
sb.append("min. "); |
||||||
|
} |
||||||
|
} |
||||||
|
if (ss > 0) { |
||||||
|
sb.append(dd).append("sec. "); |
||||||
|
} |
||||||
|
return sb.toString().trim(); |
||||||
|
} |
||||||
|
|
||||||
|
// private enum MunchUnit {
|
||||||
|
// mu_NONE, mu_DAY, mu_HOUR, mu_MINUTE, mw_SECOND
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static class TimeMuncher { |
||||||
|
|
||||||
|
public class MunchException extends Exception { |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
final private String SPAT_DAYS = "days?|d"; |
||||||
|
final private String SPAT_HOURS = "hours?|h|hr"; |
||||||
|
final private String SPAT_MINUTES = "minutes?|mins?|m"; |
||||||
|
final private String SPAT_SECONDS = "seconds?|secs?|s"; |
||||||
|
|
||||||
|
final Pattern pat_number; |
||||||
|
final Pattern pat_days; |
||||||
|
final Pattern pat_hours; |
||||||
|
final Pattern pat_mins; |
||||||
|
final Pattern pat_secs; |
||||||
|
|
||||||
|
final Scanner scanner; |
||||||
|
|
||||||
|
public TimeMuncher(String timestr) { |
||||||
|
pat_number = |
||||||
|
Pattern.compile("(\\d[\\,\\.]?\\d*)?(.*)"); |
||||||
|
// Compile here for future I18N support
|
||||||
|
pat_days = Pattern.compile(SPAT_DAYS); |
||||||
|
pat_hours = Pattern.compile(SPAT_HOURS); |
||||||
|
pat_mins = Pattern.compile(SPAT_MINUTES); |
||||||
|
pat_secs = Pattern.compile(SPAT_SECONDS); |
||||||
|
|
||||||
|
scanner = new Scanner(timestr); |
||||||
|
scanner.useDelimiter("\\W"); |
||||||
|
} |
||||||
|
|
||||||
|
public Long scan() { |
||||||
|
Double sum = null; |
||||||
|
Double dvalue = null; |
||||||
|
|
||||||
|
try { |
||||||
|
while (scanner.hasNext()) { |
||||||
|
if (scanner.hasNextDouble()) { |
||||||
|
dvalue = scanner.nextDouble(); |
||||||
|
} else { |
||||||
|
String units = scanner.next(); |
||||||
|
sum = setSum(sum, dvalue, units); |
||||||
|
dvalue = null; |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (MunchException e) { |
||||||
|
log.warn("Unparseable time value"); |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (sum == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return sum.longValue(); |
||||||
|
} |
||||||
|
|
||||||
|
private Double setSum(Double sum, Double dvalue, |
||||||
|
String units) throws MunchException { |
||||||
|
Matcher m; |
||||||
|
|
||||||
|
m = pat_number.matcher(units); |
||||||
|
|
||||||
|
if (!m.matches()) { |
||||||
|
throw new MunchException(); |
||||||
|
} |
||||||
|
if (m.group(1) != null) { |
||||||
|
String a = m.group(1); |
||||||
|
if (dvalue != null) { |
||||||
|
throw new MunchException(); |
||||||
|
} |
||||||
|
dvalue = Double |
||||||
|
.valueOf(a); |
||||||
|
//units = units.substring(m.end());
|
||||||
|
} |
||||||
|
units = m.group(2); |
||||||
|
m = pat_days.matcher(units); |
||||||
|
if (m.matches()) { |
||||||
|
return addToSum(sum, dvalue, |
||||||
|
24L * 60L * 60L * 1000L); |
||||||
|
} |
||||||
|
m = pat_hours.matcher(units); |
||||||
|
if (m.matches()) { |
||||||
|
return addToSum(sum, dvalue, 60L * 60L * 1000L); |
||||||
|
} |
||||||
|
m = pat_mins.matcher(units); |
||||||
|
if (m.matches()) { |
||||||
|
return addToSum(sum, dvalue, 60L * 1000L); |
||||||
|
} |
||||||
|
m = pat_secs.matcher(units); |
||||||
|
if (m.matches()) { |
||||||
|
return addToSum(sum, dvalue, 1000L); |
||||||
|
} |
||||||
|
return sum; |
||||||
|
} |
||||||
|
|
||||||
|
private Double addToSum(Double sum, Double dvalue, |
||||||
|
long l) throws MunchException { |
||||||
|
if (dvalue == null) { |
||||||
|
throw new TimeMuncher.MunchException(); |
||||||
|
} |
||||||
|
dvalue *= l; |
||||||
|
if (sum == null) { |
||||||
|
sum = 0.0; |
||||||
|
} |
||||||
|
sum += dvalue; |
||||||
|
return sum; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static Long parseTime(String timestr) { |
||||||
|
TimeMuncher muncher = new TimeMuncher(timestr); |
||||||
|
|
||||||
|
Long interval = muncher.scan(); |
||||||
|
return interval; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
package com.mousetech.gourmetj.utils; |
@ -1,13 +1,14 @@ |
|||||||
<!DOCTYPE html> |
<!DOCTYPE html> |
||||||
<html xmlns="http://www.w3.org/1999/xhtml"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
||||||
<html> |
|
||||||
<head> |
<head> |
||||||
<title>ERROR - Page Expired</title> |
<title>ERROR - Page Expired</title> |
||||||
</head> |
</head> |
||||||
<body> |
<body> |
||||||
<h1>Page Expired</h1> |
<h1>Page Expired</h1> |
||||||
<p>The page state could not be restored because it was left |
<p>The page state could not be restored because it was |
||||||
idle too long.</p> |
left idle too long.</p> |
||||||
<p><a href="/main.jsf">Return to Main Page</a></p> |
<p> |
||||||
|
<a href="/main.jsf">Return to Main Page</a> |
||||||
|
</p> |
||||||
</body> |
</body> |
||||||
</html> |
</html> |
@ -0,0 +1,44 @@ |
|||||||
|
/** |
||||||
|
* Copyright (C) 2022, Tim Holloway |
||||||
|
* |
||||||
|
* Date written: Jan 8, 2022 |
||||||
|
* Author: Tim Holloway <timh@mousetech.com> |
||||||
|
*/ |
||||||
|
package com.mousetech.gourmetj.utils; |
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author timh |
||||||
|
* @since Jan 8, 2022 |
||||||
|
*/ |
||||||
|
class TimeFormatterTest { |
||||||
|
|
||||||
|
/** |
||||||
|
* @throws java.lang.Exception |
||||||
|
*/ |
||||||
|
@BeforeAll |
||||||
|
static void setUpBeforeClass() throws Exception { |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
void test() { |
||||||
|
assertEquals(5000, TimeFormatter.parseTime("5s")); |
||||||
|
assertEquals(5000*60, TimeFormatter.parseTime("5m")); |
||||||
|
|
||||||
|
assertEquals(3600_000 + 25*60_000, TimeFormatter.parseTime("1 hour, 25 min")); |
||||||
|
|
||||||
|
assertEquals(5*3600000 + 6*60000, TimeFormatter.parseTime("5h 6m")); |
||||||
|
assertEquals(277562000L, TimeFormatter.parseTime("3d 5h 6m 2s")); |
||||||
|
|
||||||
|
assertEquals(18000000L, TimeFormatter.parseTime("1.5 hours")); |
||||||
|
|
||||||
|
assertEquals(3*3600_000, TimeFormatter.parseTime("3 hours")); |
||||||
|
|
||||||
|
assertNull(TimeFormatter.parseTime("1 week")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue