java.time through desugaring
Consider using java.time, the modern Java date and time API, for your time work.
Code has been edited after reading the question more closely.
private static final DateTimeFormatter TIME_PARSER
= DateTimeFormatter.ofPattern("hh:mma", Locale.ENGLISH);
public static void timeElapse(String start, String end) {
LocalTime currentTime = LocalTime.parse(start, TIME_PARSER);
LocalTime endTime = LocalTime.parse(end, TIME_PARSER);
if (currentTime.isAfter(endTime)) {
System.out.println("Time has passed");
} else {
System.out.println("You are on time");
}
}
Isn’t the code pretty self-explanatory? That’s one thing I find nice about java.time. And has been hinted in the comments, we need no time zone (except for corner cases). So I left out the third parameter. Let‘s try it out with your examples:
timeElapse("10:00AM", "10:00PM");
timeElapse("10:00AM", "12:00PM");
timeElapse("11:30AM", "05:00PM");
timeElapse("10:00AM", "01:00AM");
Output is:
You are on time
You are on time
You are on time
Time has passed
Doesn’t time zone matter? If your times fall in the fall back where clocks are turned backward and the same clock hours repeat, we’re at a loss to tell which is earlier. My code above does not take this corner case into account, and to do so, we would need to know the date too.
Original code
private static final DateTimeFormatter TIME_PARSER
= DateTimeFormatter.ofPattern("hh:mma", Locale.ENGLISH);
public static void timeElapse(String start, String end, String tz){
LocalTime startTime = LocalTime.parse(start, TIME_PARSER);
LocalTime endTime = LocalTime.parse(end, TIME_PARSER);
LocalTime now = LocalTime.now(ZoneId.of(tz));
if (now.isBefore(startTime)) {
System.out.println("Not open yet");
} else if (now.isAfter(endTime)) {
System.out.println("Time has passed");
} else {
System.out.println("You are on time");
}
}
Isn’t the code pretty self-explanatory? That’s one thing I find nice about java.time. Let‘s try it out with your examples:
timeElapse("10:00AM", "10:00PM", "Asia/Kuala_Lumpur");
timeElapse("10:00AM", "12:00PM", "Asia/Kuala_Lumpur");
timeElapse("11:30AM", "05:00PM", "Asia/Kuala_Lumpur");
timeElapse("10:00AM", "01:00AM", "Asia/Kuala_Lumpur");
I ran this code near 2:15 AM in Malaysia, so as expected the output was a bit dull:
Not open yet
Not open yet
Not open yet
Not open yet
Let’s also try:
timeElapse("12:00AM", "03:00AM", "Asia/Kuala_Lumpur");
timeElapse("01:00AM", "02:00AM", "Asia/Kuala_Lumpur");
You are on time
Time has passed
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from
org.threeten.bp
with subpackages.
What went wrong in your code?
You have got a backslash between the minutes and the AM/PM marker in your format pattern string: "hh:mm\\aa"
. This requires a backslash in your time strings, but they are like "10:00AM"
, that is, without any backslash. I believe that this caused your ParseException
. There may also be an issue with specifying Locale.getDefault()
for the formatter. AM and PM are hardly used in other languages than English but do have other names (texts) in some languages. You are requiring the text to be in the default language for your JVM (and your device).
Also be aware that if you wanted to compare the parsed times to the time now, that is easy with java.time. It is not with Date
and SimpleDateFormat
. SimpleDateFormat
parses each string into the specified time of day on January 1, 1970, so comparing with the time now will not make sense.
Links