Reputation: 59
I'm trying to load from XML a schedule field which looks like this: "MON 17:20"
I want to avoid parse manually using string replace e.t.c. I checked online for this code
final String dateInString = "Mon, 05 May 1980";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, d MMM yyyy", Locale.ENGLISH);
final LocalDate dateTime = LocalDate.parse(dateInString, formatter);
But it has no week field (I cannot retrieve the week). Is there any similar short parse system?
Upvotes: 1
Views: 294
Reputation: 86203
The problem isn’t that it’s difficult to parse using a DateTimeFormatter
. The problem is that we haven’t got a good type to parse into. The information doesn’t fit in a LocalDate
or LocalDateTime
, for example. And depending on what you need for your scheduler I think that the solution is to parse into two objects instead of one: a day of week and a time of day.
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE H:mm")
.toFormatter(Locale.ENGLISH);
String scheduleString = "MON 17:20";
TemporalAccessor parsed = formatter.parse(scheduleString);
DayOfWeek dow = DayOfWeek.from(parsed);
LocalTime time = LocalTime.from(parsed);
System.out.format("Schedule: every %s at %s", dow, time);
Output:
Schedule: every MONDAY at 17:20
Explicit use of the TemporalAccessor
interface is considered low-level, but I much prefer this solution over String.replace()
or String.split()
. If you want to avoid the low-level interface, just parse the string twice, once into a DayOfWeek
and once into a LocalTime
.
Upvotes: 0
Reputation: 22977
Of course it's possible with the Java 8 Date & Time API.
You seem to have three fields: the day-of-week, the hour-of-day and the minute-of-hour. This could normally be parsed using DateTimeFormatter::ofPattern
with the formatting string EEE HH:mm
, but the problem is that MON
(in all caps) is not standard; it should be Mon
instead.
So we need to build our formatter using the DateTimeFormatterBuilder
, instructing that the string should be parsed in a case-insensitive manner:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE HH:mm")
.toFormatter(Locale.ROOT);
The only thing to do is parsing the fields using
TemporalAccessor parsed = formatter.parse(elem);
Now parsed
contains the abovementioned parsed fields.
Of course, you don't have to convert this to an actual date. There are many use cases where one don't want a date, but rather only a day-of-week and the time. This is an example.
But if you, for example, want to get the current date and adjust it to match the data from your schedule, you can do something like this:
TemporalAdjuster adj = TemporalAdjusters.nextOrSame(DayOfWeek.of(parsed.get(ChronoField.DAY_OF_WEEK)));
LocalDateTime now = LocalDate.now()
.atTime(LocalTime.from(parsed))
.with(adj);
Upvotes: 1
Reputation: 40034
Try this.
final String dateInString = "Thu Apr 30, 2020 17:20";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd, yyyy HH:mm");
final LocalDateTime dateTime = LocalDateTime.parse(dateInString, formatter);
System.out.println(dateTime);
The above parses to this.
2020-04-30T17:20
If you want the week you can do this.
System.out.println(dateTime.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
System.out.println(dateTime.get(ChronoField.ALIGNED_WEEK_OF_YEAR));
Prints
5
18
Updated Answer.
final String dateInString ="MON 17:20";
String[] vals = dateInString.split("\\s+");
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
final LocalTime dateTime = LocalTime.parse(vals[1], formatter);
System.out.println(vals[0] + " " + dateTime);
Prints
MON 17:20
Read the details at ChronoField
Check the java.time package for more on the Java Temporal capabilities.
Upvotes: 1
Reputation: 829
You need to pass your LocalDate object into the example shown here: Get Week Number of LocalDate (Java 8)
That should get it for you.
From the link above pass your 'dateTime' field in the code like...
TemporalField woy = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear();
int weekNumber = dateTime.get(woy);
Depending on your locale and where this code will run you might want to consider WeekFields.ISO as mentioned at the link above.
Upvotes: 0