2

I have a task in which i need to set hour, minute, meridian programmatically to Calendar object and need to display time in a format hh:mm a. Here below is my code so far.

Calendar calendar = (Calendar)dateNtime.clone();
        calendar.set(Calendar.HOUR, 12);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.AM_PM, 1);

SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
    String str = dateFormat.format(calendar.getTimeInMillis());

Where dateNTime is an existing calendar object which i have to use in constructing new one.

All is going fine except only a case while i set 12PM. it always format hh:mm a and results 12:00AM while it should be 12:00PM.

please help if anybody have a good experience with Calendar object and it's known issue or provide me if there is a good tutorial link.

Suresh Sharma
  • 1,826
  • 22
  • 41
  • Please provide a short but complete program demonstrating the problem. Personally I think I'd just set the HOUR to your target hour, adding 12 if you're trying to set it to PM... – Jon Skeet Jan 23 '15 at 07:05
  • 2
    Note that if you set the hour to *0* and then set AM_PM to 1, you get your desired result. – Jon Skeet Jan 23 '15 at 07:07

2 Answers2

5

The HOUR field is documented as:

Field number for get and set indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock (0 - 11).

So instead of setting it to 12, you should set it to 0.

Personally I'd just set the HOUR_OF_DAY field, adding 12 hours if you want to make it PM - and don't set the AM_PM field at all.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Solution using java.time, the modern API:

import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
        // timezone e.g. ZoneId.of("America/New_York")
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault())
                            .withHour(12)
                            .withMinute(0);
        System.out.println(zdt);

        // Get and display just time in default format
        LocalTime time = zdt.toLocalTime();
        System.out.println(time);

        // Display just time in a custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
        // Alternatively, dtf.format(time);
        String formatted = dtf.format(zdt);
        System.out.println(formatted);
    }
}

Output:

2021-06-06T12:00:15.855986+01:00[Europe/London]
12:00:15.855986
12:00 PM

ONLINE DEMO

How to convert Calendar to java.time type?

Instant instant = calendar.toInstant();
// Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
// timezone e.g. ZoneId.of("America/New_York")
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

What if I need Calendar object from java.time type?

For any reason, if you need to convert this object of ZonedDateTime to an object of java.util.Calendar, you can do so as follows:

Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(zdt.toInstant()));

Learn more about java.time, the modern Date-Time API* from Trail: Date Time.

Sometimes, comments get deleted and therefore quoting below a valuable comment from Ole V.V.:

For a more accurate conversion to Calendar you may use GregorianCalendar.from(zdt)


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110