14

Calling DateTime.now().format() results in '28/08/2012 16:20' for current user locale 'French (France)' & '8/28/2012 4:20 PM' for current user locale 'English (United States)'.

Calling DateTime.now().date().format() results in '28/08/2012' for current user locale 'French (France)' & 8/28/2012 for current user locale 'English (United States)'.

Ideally a Time.format() instance method would exist so that DateTime.now().time().format() results in '16:20' for current user locale 'French (France)' & '4:20 PM' for current user locale 'English (United States)'.

Please suggest any and all locale sensitive workarounds for formatting the Time part only.

In my particular case, I'm not displaying this Time part only to the user via Visualforce, so an Apex workaround is what I'm looking for.

13

You could just split the DateTime format() result on the first space - does that give you what you're looking for?

public String myDateFormat(DateTime dt) {
    String[] parts = dt.format().split(' ');
    return (parts.size() == 3) ? (parts[1] + ' ' + parts[2]) : parts[1]; 
}

produces

6:38 PM

for me in English (United States), and

18:42

in French(France).

UPDATE

As tomlogic points out, the above method is not very robust - some locales may include spaces in the date or time portion of the format, and the ordering is not consistent. This second attempt assumes that the date and time are separated by zero or more spaces, but handles spaces within the two portions, and either ordering of date and time. The only assumption made is that the formatted Date is contained within the formatted Time:

public String myDateFormat(DateTime dt) {
    return dt.format().replace(dt.date().format(), '').trim();
}

Seems to work fine for Hebrew, Vietnamese & Korean, as well as English and French.

  • Guess we'd just have to cross our fingers that there aren't any locales with spaces in the date format part :) I can't think of any off the top of my head... – mjgallag Aug 29 '12 at 1:51
  • Or you can pass in a format string to get exactly what you need regardless of locale settings: .format('hh:mm aa'); – ca_peterson Aug 29 '12 at 4:00
  • 1
    Won't work for Hebrew, Vietnamese, Korean and possibly other locales. See my answer for details. Worth a feature request to Salesforce for either a Time.format() or a way to get locale-specific DateTime.format() strings for Time, Date and DateTime. – tomlogic Aug 31 '12 at 18:18
  • 1
    @metadaddy: much cleaner solution that I came up with -- nice trick to use substitution to strip the date. Would this one-liner be simpler? return dt.format().replace(dt.date().format(), '').trim(); – tomlogic Aug 31 '12 at 20:33
  • 1
    @tomlogic thanks, this works great, finally actually using it in released code, updated to dateTime.format().remove(dateTime.date().format()).trim() slightly more readable using the new string methods – mjgallag Jan 28 '13 at 14:30
3
String dt = Datetime.now().format();
Integer s = dt.indexOf(' ');
System.Debug(s+1);
System.Debug(dt.substring(s+1));

This should do it. No matter what timezone you are in. I tried it for a few and it worked fine!

Please try and let me know.

  • This is same answer as metadaddy gave above. – mjgallag Aug 29 '12 at 3:40
  • Yet simpler in that it just takes everything after the first space, even if it has more than 2 spaces... – tomlogic Aug 31 '12 at 18:19
3

This is a great question.

I can only come up with a workaround of using some external logic to choose between a format string of "HH:mm" for 24-hour mode and "h:mm a" for 12-hour mode.

One possibility would be to create a known datetime with a time in the PM hours (16:56) and a date with different numbers (11/12/2017). Format that to a string. Then try to match various patterns in that string, and use the matches to create the format string for the actual time you want to format:

  • "16:56" -> "HH:mm"
  • "4:56 PM" -> "h:mm a"
  • "4:56PM" -> "h:mma"
  • "PM4:56" -> "ah:mm"
  • "PM 4:56" -> "a h:mm"

Have a default format if you can't make a match.

Once you know the format (should only need to run once per instance), you can take a Time, promote it to a DateTime with some arbitrary date, and use the format method with your calculated format string.

Huge hack, and something that Salesforce should probably address by providing an API to get locale-specific format strings for Date, Time and DateTime.

Note that solutions that try to split the string on spaces won't work for all of the Salesforce supported locales. Some examples:

  • Hebrew, Vietnamese: 16:30 02/01/2008
  • Korean: 2008. 1. 2 PM 4:30 (interestingly, time is shown as 오전 6:00)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.