81

After formatting a datetime, the time displays AM or PM in upper case, but I want it in lower case like am or pm.

This is my code:

public class Timeis {
    public static void main(String s[]) {
        long ts = 1022895271767L;
        String st = null;  
        st = new SimpleDateFormat(" MMM d 'at' hh:mm a").format(ts);
        System.out.println("time is " + ts);  
    }
}
Brad Koch
  • 19,267
  • 19
  • 110
  • 137
xrcwrn
  • 5,339
  • 17
  • 68
  • 129
  • 1
    `st.toLowerCase()` will do it and there is no easier way. – Marko Topolnik Nov 27 '12 at 10:00
  • 4
    The trouble is that, like month and day names, the AM/PM marker is locale-specific - it may not make sense in some languages to force everything to lower case (leaving aside the fact that some languages just use 24 hour clock for everything and don't really have terms for AM and PM at all). – Ian Roberts Nov 27 '12 at 10:09
  • For new readers to this question I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `Instant`, `ZoneId` `ZonedDateTime` and `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Dec 04 '21 at 12:07

11 Answers11

101

This works

public class Timeis {
    public static void main(String s[]) {
        long ts = 1022895271767L;
        SimpleDateFormat sdf = new SimpleDateFormat(" MMM d 'at' hh:mm a");
        // CREATE DateFormatSymbols WITH ALL SYMBOLS FROM (DEFAULT) Locale
        DateFormatSymbols symbols = new DateFormatSymbols(Locale.getDefault());
        // OVERRIDE SOME symbols WHILE RETAINING OTHERS
        symbols.setAmPmStrings(new String[] { "am", "pm" });
        sdf.setDateFormatSymbols(symbols);
        String st = sdf.format(ts);
        System.out.println("time is " + st);
    }
}
trav3ll3r
  • 30
  • 1
  • 6
James Jithin
  • 10,183
  • 5
  • 36
  • 51
  • 1
    @BrianAgnew, Not sure, you may try updating the property of the DateFormatSymbols instance received from http://joda-time.sourceforge.net/api-release/org/joda/time/DateTimeUtils.html#getDateFormatSymbols%28java.util.Locale%29 – James Jithin Nov 27 '12 at 10:34
  • 1
    When specifying `Locale` in `SimpleDateFormate`, using `DateFormatSymbols` messes it up. You would probable have to specifically set all of the symbols and not just am/pm. – Suragch Oct 17 '14 at 06:48
  • 1
    It's Great! Thank's buddy. :) – Kartheek Oct 19 '16 at 09:00
  • 1
    thanks working great, provided in my case need to replace `" "` with `""`, e.g **hh:mm a** to **hh:mma** – Shantaram Tupe Jan 02 '18 at 07:35
92

Unfortunately the standard formatting methods don't let you do that. Nor does Joda. I think you're going to have to process your formatted date by a simple post-format replace.

String str = oldstr.replace("AM", "am").replace("PM","pm");

You could use the replaceAll() method that uses regepxs, but I think the above is perhaps sufficient. I'm not doing a blanket toLowerCase() since that could screw up formatting if you change the format string in the future to contain (say) month names or similar.

EDIT: James Jithin's solution looks a lot better, and the proper way to do this (as noted in the comments)

stkent
  • 19,772
  • 14
  • 85
  • 111
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
9

If you don't want to do string substitution, and are using Java 8 javax.time:

Map<Long, String> ampm = new HashMap<>();
ampm.put(0l, "am");
ampm.put(1l, "pm");

DateTimeFormatter dtf = new DateTimeFormatterBuilder()
        .appendPattern("E M/d h:mm")
        .appendText(ChronoField.AMPM_OF_DAY, ampm)
        .toFormatter()
        .withZone(ZoneId.of("America/Los_Angeles"));

It's necessary to manually build a DateTimeFormatter (specifying individual pieces), as there is no pattern symbol for lowercase am/pm. You can use appendPattern before and after.

I believe there is no way to substitute the default am/pm symbols, making this is the only way short of doing the string replace on the final string.

Nikola Mihajlović
  • 2,286
  • 2
  • 19
  • 23
7
Calendar c = Calendar.getInstance();

System.out.println("Current time => " + c.getTime());

SimpleDateFormat df = new SimpleDateFormat("HH:mm a");
String formattedDate = df.format(c.getTime());
formattedDate = formattedDate.replace("a.m.", "AM").replace("p.m.","PM");

TextView textView = findViewById(R.id.textView);
textView.setText(formattedDate);
clemens
  • 16,716
  • 11
  • 50
  • 65
Mourya
  • 71
  • 1
  • 1
5

Try this:

System.out.println("time is " + ts.toLowerCase());

Although you may be able to create a custom format as detailed here and here

Unfortunately out of the box the AM and PM do not seem to be customisable in the standard SimpleDateFormat class

Community
  • 1
  • 1
RNJ
  • 15,272
  • 18
  • 86
  • 131
2

James's answer is great if you want different style other than default am, pm. But I'm afraid you need mapping between Locale and Locale specific AM/PM set to adopting the override. Now you simply use java built-in java.util.Formatter class. So an easy example looks like this:

System.out.println(String.format(Locale.UK, "%1$tl%1$tp", LocalTime.now()));

It gives:

9pm

To note that if you want upper case, just replace "%1$tp" with "%1$Tp". You can find more details at http://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#dt.

ShenYi
  • 121
  • 1
  • 7
2
new SimpleDateFormat("MMM d 'at' hh:mm a", new Locale("en", "IN"));

change to a locale that uses am/pm instead of AM/PM.

Agnibha
  • 613
  • 1
  • 11
  • 20
1
    String today = now.format(new DateTimeFormatterBuilder()
            .appendPattern("MM/dd/yyyy ")
            .appendText(ChronoField.AMPM_OF_DAY)
            .appendLiteral(" (PST)")
            .toFormatter(Locale.UK));

// output => 06/18/2019 am (PST)

Locale.UK => am or pm; Locale.US => AM or PM; try different locale for your needs (defaul, etc.)

dfostic
  • 1,608
  • 15
  • 8
0

just add toLowarCase() like this

public class Timeis {
public static void main(String s[]) {
      long ts = 1022895271767L;
      String st = null;  
      st = new SimpleDateFormat(" MMM d 'at' hh:mm a").format(ts).toLowerCase();
      System.out.println("time is " + ts);  
}
}

and toUpperCase() if you want upper case

3zcs
  • 35
  • 4
  • 18
0

This is how we perform in android studio's java code pass unix timestamp as parameter

private String convertTimeToTimeStamp(Long timeStamp){
            SimpleDateFormat sdf=new SimpleDateFormat("hh:mm aaa", Locale.getDefault());
            return sdf.format(timeStamp);
        }

function returns time of format 09:30 PM

Shashank Pandey
  • 683
  • 6
  • 14
0

dateString.toLowerCase();

String timeString= new SimpleDateFormat(" MMM d 'at' hh:mma") .format(timestaamp) .toLowerCase();

System.out.println("time is " + tstimeString);