この「5W3D10H5M10S」のような文字列を秒に変換したい場合、前の文字列を引数として持つと、関数は「3319510」を返します。
- W = 週
- D = 日
- H = 時間
- M = 分
- S = 秒
私はこれを行う方法を考えてきましたが、どれも効率的ではありません.誰かが私を正しい方向に向けることができれば、それは素晴らしいことです.
正規表現と単純なループでそれを行うことができます:
private static final int[] timeMul = new int[] {7, 24, 60, 60, 1};
private static final Pattern rx = Pattern.compile(
"(?:(\\d+)W)?(?:(\\d+)D)?(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?"
);
public static int getSeconds(String str) {
Matcher m = rx.matcher(str);
if (!m.find()) {
return -1;
}
int res = 0;
for (int i = 0 ; i != m.groupCount() ; i++) {
String g = m.group(i+1);
res += g == null ? 0 : Integer.parseInt(g);
res *= timeMul[i];
}
return res;
}
あなたの文字列を式に変換ScriptEngineManager
して計算させてみませんか?
public void testIt() throws Exception {
final String in = "5W3D10H5M10S";
final String after = in.replaceAll("W", "*7D").
replaceAll("D", "*24H").
replaceAll("H", "*60M").
replaceAll("M", "*60+").
replaceAll("S", "");
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("js");
final Object result = engine.eval(after);
System.out.println("Result:" + String.valueOf(result));
}
出力:
Result:3319510.0
EDIT:少し簡略化(文字列操作が少ない)
DateFormat dateFormat = new SimpleDateFormat("d'D'HH'H'mm'M'ss'S'");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateString = "5W3D10H5M10S";
String[] dateAndWeek = dateString.split("W");
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.setTime(dateFormat.parse(dateAndWeek[1]));
cal.add(Calendar.DATE, 1);
cal.add(Calendar.WEEK_OF_YEAR, Integer.parseInt(dateAndWeek[0]));
long dateSeconds = cal.getTimeInMillis()/1000;//<--3319510
いくつかの境界条件と予期しない入力に対処するには、これを微調整する必要があります...
long wdh(String fmt) {
long tot = 0;
int current = 0;
for (char c : fmt.toCharArray()) {
if (Character.isDigit(c)) {
current *= 10;
current += c - '0';
continue;
}
switch (c) {
case 'W': tot += WEEK_SECONDS * current; current = 0; continue;
case 'D': tot += DAY_SECONDS * current; current = 0; continue;
case 'H': tot += HOUR_SECONDS * current; current = 0; continue;
case 'M': tot += MINUTE_SECONDS * current; current = 0; continue;
case 'S': tot += current; break;
}
}
return tot;
}
最も簡単な方法は、数値以外の文字に到達するまでテキストを単純にループし、前の文字位置の部分文字列を取得してテキストのそのセクションを取得し、それを int に解析して、文字に応じて必要な量を掛けることです。
例:
public long getSeconds(String funnyFormat)
{
long seconds = 0;
int lastIndex = 0;
for(int i = 0;i<funnyFormat.length;i++) {
char cur = funnyFormat.charAt(i);
if(cur < '0' && cur > '9') {
//If it's not a Number
int seg = Integer.parseInt(funnyFormat.substring(lastIndex,i));
lastIndex = i+1;
switch(cur){
case 'H':
long += seg*3600;
break;
case 'M':
long += seg*60;
break;
case 'S':
long += seg;
break;
//And so on and so forth
}
}
}
}