web-dev-qa-db-fra.com

NSDateFormatter avec 24 heures

J'ai un compte à rebours qui compte à rebours de la date/heure actuelle à une date/heure future spécifique. Cela fonctionne très bien, sauf pour un problème. Je saisis la date future en utilisant NSDateFormatter et dateFromString. Il ne semble pas être en mesure d’accepter une heure (heure) supérieure à 12 heures bien que cela indique qu’il n’est pas pris en charge. Existe-t-il un moyen d'activer le support 24 heures sur 24 ou une solution de contournement? Voici un extrait de mon code:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
NSDate *myDate = [df dateFromString:@"2010-03-14 15:00:00"];

Merci

42
John

NSDateFormatter suit la norme Unicode pour les modèles de date et d’heure . Utilisez 'H' pour l'heure sur une horloge de 24 heures:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *myDate = [df dateFromString:@"2010-03-14 15:00:00"];
65
VoidPointer

J'ai eu le même problème et utiliser HH ne fonctionnait que sur certains appareils, comme Roger a également vérifié. En fin de compte, c’est la solution qui a fonctionné pour moi, j’espère que cela fonctionnera pour les autres. Il était difficile de trouver cette réponse, il n’existait pas de forum, c’était littéralement des essais et des erreurs suivant la documentation Apple.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

    [dateFormatter setLocale:enUSPOSIXLocale];

    NSString *dateFormat = @"dd/MM/yyyy HH:mm"; //MM for month, mm for minutes

    [dateFormatter setDateFormat:dateFormat];
    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
    date = [dateFormatter dateFromString:string];
51
crojassoto

Ma solution sur Swift:

let formatter = NSDateFormatter()
var defIdentifer = formatter.locale.localeIdentifier
if !defIdentifer.hasSuffix("_POSIX") {
    defIdentifer = defIdentifer+"_POSIX"
    let locale = NSLocale(localeIdentifier: defIdentifer)
    formatter.locale = locale
}
formatter.dateFormat = "HH:mm"
8
EvGeniy Ilyin

Tiré de Questions/Réponses Techniques Apple sur NSDateFormatters

Q: J'utilise NSDateFormatter pour analyser une date de style Internet, mais cela échoue pour certains utilisateurs dans certaines régions. J'ai défini une chaîne de format de date spécifique; Cela ne devrait-il pas forcer NSDateFormatter à fonctionner indépendamment des paramètres de région de l'utilisateur?

Non. Bien que définir une chaîne de format de date semble fonctionner pour la plupart des utilisateurs, ce n'est pas la bonne solution à ce problème. Il existe de nombreux endroits où les chaînes de format se comportent de manière inattendue. 

Voici comment j'ai fait le mien à Swift:

private let dateFormatter: NSDateFormatter = {
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
    dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    dateFormatter.timeZone = NSTimeZone.init(forSecondsFromGMT: 0)
    return dateFormatter
}()
4
Harry Bloom

J'ai récemment eu un problème similaire, au lieu de HH, NSDateFormatter ignoré hh, a (symbole AM ​​/ PM) et G (nom de l'époque cyclique) dans mon application.

Et j’ai été surpris de constater que si j’allais dans les paramètres de localisation de mon appareil et si je faisais un choix aléatoire, tous les phénomènes fantastiques avaient disparu et l’erreur ne pouvait plus se reproduire. Très étrange.

Ensuite, j'ai testé sur simulateur pour étudier le problème. Il y a ma solution:

Après avoir créé la variable NSDateFormatter, définissez explicitement la propriété locale même si vous utilisez la locale actuelle. N'utilisez surtout pas [NSLocale currentLocale]. Celle-ci est boguée et peut être "surchargée" par l'utilisateur, utilisez systemLocale ou créez explicitement une instance NSLocale en utilisant un identificateur local.

3
Chris

Version Objective C permettant d’obtenir NSDate d’une chaîne de 24 heures lorsque l’utilisateur a défini le format 12 heures sur son iPhone sans modifier les paramètres régionaux ni le fuseau horaire:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSString *localeId = dateFormatter.locale.localeIdentifier;
if (! [localeId hasSuffix:@"_POSIX"]) {
    localeId = [localeId stringByAppendingString:@"_POSIX"];
    dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:localeId];
}
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH.mm.ss";

NSDate *date  = [dateFormatter dateFromString:dateText];
0
wzbozon