12:xx shown as 00:xx in SimpleDateFormat.format("hh:mm:ss")
When using SimpleDateFormatter.format in the following code, hours between 12:00 and 12:59 are shown as 00:00 to 00:59 in startDateText TextView, while since 13:00 on they are correctly shown as 13:xx, 14:xx up to 23:59.
---- Refactored code as requested When the string in the dtold.parse(...) is an the in example the output hour is 00:00, when it is "13:00" it is correctly "13:00"
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
// one class needs to have a main() method
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
SimpleDateFormat dtnew = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
SimpleDateFormat dtold = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
Calendar cal = Calendar.getInstance();
cal.setTime(dtold.parse("2017-03-12 12:33:33"));
cal.add(Calendar.SECOND, 10);
System.out.println(dtnew.format(cal.getTime()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Solution 1:
First a couple of formatters like yours, only using DateTimeFormatter
from java.time
, the modern Java date and time API:
private static DateTimeFormatter dtfOld = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static DateTimeFormatter dtfNew = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
Two things to note: (1) Declare the formatters in the logical order, the order in which you are going to use them. Using the opposite order in the question confused me, and I’m unsure whether it confused yourself too. (2) In dtfOld
use uppercase HH
for hour of day in the interval 00 through 23. Lowercase hh
is for hour within AM or PM from 01 through 12 (in this case the same format pattern letters apply for SimpleDateFormat
and DateTimeFormatter
; there are differences, though). Now the rest is pretty boring, only simpler than your code:
LocalDateTime parsed = LocalDateTime.parse("2017-03-12 12:33:33", dtfOld);
System.out.println(parsed);
LocalDateTime dateTime = parsed.plusSeconds(10);
System.out.println(dateTime);
System.out.println(dateTime.format(dtfNew));
Output is:
2017-03-12T12:33:33
2017-03-12T12:33:43
12-03-2017 12:33:43
I am recommending java.time
. The old date and time classes that you used — SimpleDateFormat
, Calendar
and Date
— are long outdated. It’s not only in this case that the modern classes allow for simpler code, it’s quite common. I find java.time
generally so much nicer to work with.
What went wrong in your code?
I gave a hint already: Lowercase hh
is for hour within AM or PM from 01 through 12. When you don’t supply and parse an AM/PM marker, AM is used as the default. And 12:33:33 AM means a little more than half an hour past midnight, and is rendered as 00:33:33 on a 24 hour clock.
The times from 13:00 up to 23:59? They don’t exist in AM. Apparently SimpleDateFormat
doesn’t care and just extrapolates from the hours from 01 through 11 and therefore happens to give you the time you had expected. There’s a trick to tell it not to; but I wouldn’t want to bother, I’d rather not use the class at all.
Link
Oracle tutorial: Date Time explaining how to use java.time
.