I am trying to parse a timestamp that looks like this according to the error I was given. Attached below is my code for parsing, I followed the documentation regarding the symbols like u,y,M,h,H in DateTimeFormatter so I am quite confused why it is not working? Thank you.
java.time.format.DateTimeParseException: Text '2022-12-26T14:52:02 08:00' could not be parsed at index 19
@Composable
fun ExpandedBusStop(
modifier: Modifier = Modifier,
currentBusStopService: SingaporeBusServices,
) {
// Determine the Current Timestamp as LocalDateTime
var currentTimestamp = LocalDateTime.now() //.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"))
val datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
// datetimeFormatter.setTimeZone(TimeZone.getTimeZone("GMT 14"))
var nextBusEtaArray = Array<String>(3) { "" }
var nextBusOccupancyArray = Array<String>(3) { "" }
val currentBusService = currentBusStopService.busServiceNumber
for (i: Int in 0..2) {
// Determining the ETA of the Next 3 Buses in Minutes
val nextBus = currentBusStopService.nextBus1
val nextBusTimestampString = nextBus.estimatedArrival // In the Event there are no longer any buses
val nextBusTimestamp = LocalDateTime.parse(nextBusTimestampString, datetimeFormatter)
val nextBusETA = Duration.between(currentTimestamp, nextBusTimestamp)
// Round down to Nearest Minute and Convert into a String
nextBusEtaArray[i] = nextBusETA.toString().toInt().toString()
// Determining the Occupancy Rates of the Next 3 Buses
val nextBusOccupancy = nextBus.busOccupancyLevels
nextBusOccupancyArray[i] = nextBusOccupancy
}
Divider(thickness = 2.dp)
Row {
// Bus Service Number
Text(
text = currentBusService,
style = MaterialTheme.typography.h5,
modifier = modifier.weight(2f)
)
Spacer(modifier = modifier.weight(1f))
// Waiting Time Occupancy Rate for each Incoming Bus
Column() {
Text(
text = nextBusEtaArray[0],
style = MaterialTheme.typography.body2
)
// TODO Replace with Infographic
Text(
text = nextBusOccupancyArray[0],
style = MaterialTheme.typography.body2
)
}
Column() {
Text(
text = nextBusEtaArray[1],
style = MaterialTheme.typography.body2
)
// TODO Replace with Infographic
Text(
text = nextBusOccupancyArray[0],
style = MaterialTheme.typography.body2
)
}
Column() {
Text(
text = nextBusEtaArray[2],
style = MaterialTheme.typography.body2
)
// TODO Replace with Infographic
Text(
text = nextBusOccupancyArray[0],
style = MaterialTheme.typography.body2
)
}
}
Divider(thickness = 2.dp)
}
CodePudding user response:
According to the DateTimeFormatter docs:
Offset Z: This formats the offset based on the number of pattern letters. One, two or three letters outputs the hour and minute, without a colon, such as ' 0130'. The output will be ' 0000' when the offset is zero. Four letters outputs the full form of localized offset, equivalent to four letters of Offset-O. The output will be the corresponding localized offset text if the offset is zero. Five letters outputs the hour, minute, with optional second if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or more letters throws IllegalArgumentException.
Hence the correct pattern you should use is this:
yyyy-MM-dd'T'HH:mm:ssZZZZZ
The snippet below works correctly and prints out "{OffsetSeconds=28800, InstantSeconds=1672037522},ISO resolved to 2022-12-26T14:52:02":
fun main() {
val datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZZZZZ")
println(datetimeFormatter.parse("2022-12-26T14:52:02 08:00"))
}
CodePudding user response:
You do not need a DateTimeFormatter
java.time
API is based on ISO 8601 and therefore you do not need a DateTimeFormatter
to parse a date-time string which is already in ISO 8601 format (e.g. your date-time string, 2022-12-26T14:52:02 08:00
).
Demo:
import java.time.OffsetDateTime;
class Main {
public static void main(String args[]) {
String strDateTime = "2022-12-26T14:52:02 08:00";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
}
}
Output:
2022-12-26T14:52:02 08:00
Learn more about the modern Date-Time API from Trail: Date Time.