How to remove 'at' from formatted date string?
Asked Answered
N

3

8

This is the date formatter setup:

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .medium

Expected output:

Aug 13, 2017 6:04:11 PM

Current output:

Aug 13, 2017 at 6:04:11 PM

How can the 'at' word be removed ideally without specifying a format string and where does it come from?

With Austrian German locale:

dateFormatter.locale = Locale(identifier: "de_AT")
13.08.2017, 18:04:11

With US English locale:

dateFormatter.locale = Locale(identifier: "en_US")
Aug 13, 2017 at 6:04:11 PM
Noeminoesis answered 13/8, 2017 at 16:12 Comment(2)
What is your current locale? Or do you use also the dateFormat property?Baalbeer
@Baalbeer I’ve just extended the posting with the locale information. The ‘at’ seems to come from the English locale. I don’t use the dateFormat property.Noeminoesis
P
-4

You can achieve the expected output using

dateFormatter.dateFormat = "MMM dd, yyyy h:mm:ss a".

The at word is put there due to the current locale, so if you want to get rid of it for all locales, you should specify the exact date format as you can see above.

Pandurate answered 13/8, 2017 at 16:21 Comment(2)
That would give Aug. 13, 2017 6:22:48 PM for the german locale, which does not "look right" :)Logomachy
It's poor practice to hardcode a specific date and time format. This results in a very unexpected date and time for most users in various locales.Uriia
L
10

One option would be to make two separate conversions, one setting only dateStyle = .medium, and one setting only timeStyle = .medium, and then concatenate the result. But I don't know if a

<date><space><time>

format makes sense in all languages and locales.

A better approach is to use setLocalizedDateFormatFromTemplate:

dateFormatter.setLocalizedDateFormatFromTemplate("MMM dd yyyy jj:mm:ss")

This comes close to what you wanted, and is guaranteed to give a sensible result for all locale settings. Here some examples.

en_US:   Aug 13, 2017, 6:33:54 PM
de:      13. Aug. 2017, 18:33:54
ja:      2017年8月13日 18:33:54

Note the usage of jj format for the hour, this will be interpreted as HH (24 hour format) or hh (12 hour AM/PM format), depending on the locale.

Logomachy answered 13/8, 2017 at 16:44 Comment(4)
That looks good! But I’d like to avoid specifying a format string and find out where ‘at’ comes from.Noeminoesis
@AndrasHatvani Then please answer the question posted by vadian just below your question.Uriia
@AndrasHatvani: The "at" is part of the locale. (NS)DateFormatter ultimately uses the "ICU library for Unicode". The relevant part could be ures_getStringByIndex(dateTimePatterns.getAlias(), glueIndex, &resStrLen, &status); in source.icu-project.org/repos/icu/trunk/icu4c/source/i18n/…. I don't know if that "glue" is configurable, but I doubt it.Logomachy
@AndrasHatvani: As I understand it from that ICU source code, "date" and "time" are glued together with a locale dependent string. Therefore doing two separate conversions (my first suggestion) would give the same result without the glue string.Logomachy
D
-2

You can write it to a string and use text.Replace to replace it with nothing.

Doubletime answered 13/8, 2017 at 16:15 Comment(1)
That would work only for certain locales. The string can e.g. be 13.08.2017, 18:18:33 in the German locale.Logomachy
P
-4

You can achieve the expected output using

dateFormatter.dateFormat = "MMM dd, yyyy h:mm:ss a".

The at word is put there due to the current locale, so if you want to get rid of it for all locales, you should specify the exact date format as you can see above.

Pandurate answered 13/8, 2017 at 16:21 Comment(2)
That would give Aug. 13, 2017 6:22:48 PM for the german locale, which does not "look right" :)Logomachy
It's poor practice to hardcode a specific date and time format. This results in a very unexpected date and time for most users in various locales.Uriia

© 2022 - 2025 — McMap. All rights reserved.