从字符串中提取多个 TimeUnits
Extract multiple TimeUnits from a String
我正在尝试去除字符串的每个时间单位,例如
字符串“4w10d50m39s”将return TimeUnit 为 4 周,TimeUnit 为 10 天,TimeUnit 为 50 分钟,TimeUnit 为 39 秒。
我怎样才能做到这一点?
上下文:我需要他们将所有时间单位加起来转换为毫秒并将其用作时间戳,它将在 Minecraft 服务器内部使用,用于为特定用户添加等级的命令时间量,例如:/addrank iLalox Vip 4w5d,这会将到期日期设置为:System.currentMillis() + timeInMillis
.
要提取单位,您可以使用正则表达式
\d+[wdms]
然后您可以使用 matcher
从字符串中提取匹配项并创建 TimeUnit
。 TimeUnit
中没有 Week
常量,所以我将周表示为 amount of weeks * 7
天数。
public static void main(String[] args) {
String test = new String("4w10d50m39s");
Pattern pattern = Pattern.compile("\d+[wdms]");
Matcher matcher = pattern.matcher(test);
while(matcher.find()) {
String unit = matcher.group();
char timeType = unit.charAt(unit.length() - 1);
int timeAmount = Integer.parseInt(unit.substring(0, unit.length() - 1));
if(timeType == 'd') {
System.out.println(TimeUnit.DAYS.toDays(timeAmount) + " DAYS");
}
if(timeType == 'm') {
System.out.println(TimeUnit.MINUTES.toMinutes(timeAmount) + " MINUTES");
}
if(timeType == 's') {
System.out.println(TimeUnit.SECONDS.toSeconds(timeAmount) + " SECONDS");
}
if(timeType == 'w') {
System.out.println(TimeUnit.DAYS.toDays(timeAmount * 7L) + " DAYS IN WEEK");
}
}
}
输出:
28 DAYS IN WEEK
10 DAYS
50 MINUTES
39 SECONDS
java.time
的周期、持续时间和瞬间
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。假设您的到期时间是实时的(不是 Minecraft 时间):
String string = "4w10d50m39s";
String dayBasedString
= string.replaceFirst("(^(?:\d+w)?(?:\d+d)?).*$", "");
String timeBasedString = string.substring(dayBasedString.length());
Period period = dayBasedString.isEmpty()
? Period.ZERO
: Period.parse("P" + dayBasedString);
assert period.getYears() == 0 : period;
assert period.getMonths() == 0 : period;
Duration dur = timeBasedString.isEmpty()
? Duration.ZERO
: Duration.parse("PT" + timeBasedString);
dur = Duration.ofDays(period.getDays()).plus(dur);
Instant now = Instant.now();
Instant expiration = now.plus(dur);
System.out.format("Now: %s; expiration: %s%n", now, expiration);
我运行刚才的代码片段时的输出:
Now: 2021-08-20T18:24:35.701136Z; expiration:
2021-09-27T19:15:14.701136Z
Java 有 classes Period
用于基于天的周期,Duration
用于基于时间的周期。由于您的字符串是两者,因此我同时使用 classes。 Instant
class 时间点,例如 运行k 的到期时间。
Period
class 可以像 P4w10d
一样原生地解析字符串,Duration
class 像 PT50m39s
一样。挑战在于在几周和几天之后以及小时、分钟和秒之前拆分您的字符串。我的正则表达式匹配包含周 and/or 天的字符串的任何(可能为空)部分,并将这部分复制到一个单独的变量。然后将其余部分复制到另一个变量并没有那么复杂。 Period
可能包含年、月和日(周自动转换为日)。为了使我的以下计算起作用,我需要假设没有年或月,因为我不知道这些天有多少天。我还假设一天是 24 小时,尽管现实生活中并非总是如此。
作为变体,您可以使用 ZonedDateTime
表示当前时间。优点是您可以先直接添加 Period
,然后再添加 Duration
,而无需先将周和日转换为 Duration
。作为进一步的变体,您可以使用 ThreeTen Extra 项目中的 PeriodDuration
class。我没有检查过,但我希望可以将 PeriodDuration
添加到 ZonedDateTime
,因为它很有意义。
I need them to sum all the Time unit converted to millis and use it as
a time stamp, …
为此,您既不需要自己对单位求和,也不需要转换为毫秒。 Period
和 Duration
解析较大的字符串块,Instant.plus()
直接接受我们最终得到的 Duration
对象。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time。
- ThreeTen-Extra - Home
我正在尝试去除字符串的每个时间单位,例如
字符串“4w10d50m39s”将return TimeUnit 为 4 周,TimeUnit 为 10 天,TimeUnit 为 50 分钟,TimeUnit 为 39 秒。
我怎样才能做到这一点?
上下文:我需要他们将所有时间单位加起来转换为毫秒并将其用作时间戳,它将在 Minecraft 服务器内部使用,用于为特定用户添加等级的命令时间量,例如:/addrank iLalox Vip 4w5d,这会将到期日期设置为:System.currentMillis() + timeInMillis
.
要提取单位,您可以使用正则表达式
\d+[wdms]
然后您可以使用 matcher
从字符串中提取匹配项并创建 TimeUnit
。 TimeUnit
中没有 Week
常量,所以我将周表示为 amount of weeks * 7
天数。
public static void main(String[] args) {
String test = new String("4w10d50m39s");
Pattern pattern = Pattern.compile("\d+[wdms]");
Matcher matcher = pattern.matcher(test);
while(matcher.find()) {
String unit = matcher.group();
char timeType = unit.charAt(unit.length() - 1);
int timeAmount = Integer.parseInt(unit.substring(0, unit.length() - 1));
if(timeType == 'd') {
System.out.println(TimeUnit.DAYS.toDays(timeAmount) + " DAYS");
}
if(timeType == 'm') {
System.out.println(TimeUnit.MINUTES.toMinutes(timeAmount) + " MINUTES");
}
if(timeType == 's') {
System.out.println(TimeUnit.SECONDS.toSeconds(timeAmount) + " SECONDS");
}
if(timeType == 'w') {
System.out.println(TimeUnit.DAYS.toDays(timeAmount * 7L) + " DAYS IN WEEK");
}
}
}
输出:
28 DAYS IN WEEK
10 DAYS
50 MINUTES
39 SECONDS
java.time
的周期、持续时间和瞬间我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。假设您的到期时间是实时的(不是 Minecraft 时间):
String string = "4w10d50m39s";
String dayBasedString
= string.replaceFirst("(^(?:\d+w)?(?:\d+d)?).*$", "");
String timeBasedString = string.substring(dayBasedString.length());
Period period = dayBasedString.isEmpty()
? Period.ZERO
: Period.parse("P" + dayBasedString);
assert period.getYears() == 0 : period;
assert period.getMonths() == 0 : period;
Duration dur = timeBasedString.isEmpty()
? Duration.ZERO
: Duration.parse("PT" + timeBasedString);
dur = Duration.ofDays(period.getDays()).plus(dur);
Instant now = Instant.now();
Instant expiration = now.plus(dur);
System.out.format("Now: %s; expiration: %s%n", now, expiration);
我运行刚才的代码片段时的输出:
Now: 2021-08-20T18:24:35.701136Z; expiration: 2021-09-27T19:15:14.701136Z
Java 有 classes Period
用于基于天的周期,Duration
用于基于时间的周期。由于您的字符串是两者,因此我同时使用 classes。 Instant
class 时间点,例如 运行k 的到期时间。
Period
class 可以像 P4w10d
一样原生地解析字符串,Duration
class 像 PT50m39s
一样。挑战在于在几周和几天之后以及小时、分钟和秒之前拆分您的字符串。我的正则表达式匹配包含周 and/or 天的字符串的任何(可能为空)部分,并将这部分复制到一个单独的变量。然后将其余部分复制到另一个变量并没有那么复杂。 Period
可能包含年、月和日(周自动转换为日)。为了使我的以下计算起作用,我需要假设没有年或月,因为我不知道这些天有多少天。我还假设一天是 24 小时,尽管现实生活中并非总是如此。
作为变体,您可以使用 ZonedDateTime
表示当前时间。优点是您可以先直接添加 Period
,然后再添加 Duration
,而无需先将周和日转换为 Duration
。作为进一步的变体,您可以使用 ThreeTen Extra 项目中的 PeriodDuration
class。我没有检查过,但我希望可以将 PeriodDuration
添加到 ZonedDateTime
,因为它很有意义。
I need them to sum all the Time unit converted to millis and use it as a time stamp, …
为此,您既不需要自己对单位求和,也不需要转换为毫秒。 Period
和 Duration
解析较大的字符串块,Instant.plus()
直接接受我们最终得到的 Duration
对象。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time。
- ThreeTen-Extra - Home