Period, Duration and Instant from java.time
I recommend that you use java.time, the modern Java date and time API, for your date and time work. Assuming your expiration is in real time (not Minecraft time):
String string = "4w10d50m39s";
String dayBasedString
= string.replaceFirst("(^(?:\\d+w)?(?:\\d+d)?).*$", "$1");
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);
Output when I ran the snippet just now:
Now: 2021-08-20T18:24:35.701136Z; expiration:
2021-09-27T19:15:14.701136Z
Java has classes Period
for day-based periods and Duration
for time-based ones. Since your string is both, I am using both classes. And the Instant
class for a point in time like the expiration time of your rank.
The Period
class can natively parse a String like P4w10d
, and the Duration
class one like PT50m39s
. The challenge is to split your string after the weeks and days and before the hours, minutes and seconds. My regular expression matches any (possibly empty) part of the string containing weeks and/or days and copies this part to a separate variable. Then copying the rest to another variable is not so complicated. A Period
may contain years, months and days (weeks are automatically converted to days). For my following calculation to work I need to assume that there were no years or months since I don’t know how many days those are. I am also assuming that a day is 24 hours even though this is not always the case in real life.
As a variation you may use a ZonedDateTime
for the current time. The advantage will be that you can directly add first a Period
and then a Duration
to it without the need to convert the weeks and days to a Duration
first. And as a further variation you may use the PeriodDuration
class from the ThreeTen Extra project. I haven’t checked, but I would expect that it would be possible to add a PeriodDuration
to a ZonedDateTime
since it would make good sense.
I need them to sum all the Time unit converted to millis and use it as
a time stamp, …
For that you neither need to sum the units yourself nor to convert to milliseconds. Period
and Duration
parse larger chunks of your string, and Instant.plus()
directly accepts the Duration
object that we end up with.
Links