2017-08-18 4 views
2

Ma question est très similaire à Get "time with time zone" from "time without time zone" and the time zone name (je pense). Je veux juste le faire dans Swift.Comment "combiner" une date non-zonée et un fuseau horaire?

Quoi qu'il en soit, je suis en train d'écrire une fonction avec la signature suivante:

func combine(_ date: Date, with timeZone: TimeZone) -> Date? 

Ce qu'il fait est qu'il prend essentiellement à une date et retourne une date « zoné ». Si la date n'existe pas dans le fuseau horaire, elle renvoie nil.

Pour éviter d'être une question XY, voici une capture d'écran:

enter image description here

Je demande à l'utilisateur une date et un fuseau horaire et je veux combiner ces deux en un seul Date.

Je vais essayer de mon mieux pour expliquer. Je vais exprimer les dates dans le format de timeIntervalFrom1970 pour le rendre aussi clair que possible.

Dites que je passe en 0 comme date et GMT-1 en tant que fuseau horaire, il renverra 3600. 0 est 1970-1-1 00:00:00. 01/01/1970 00:00:00 GMT-1 est 01/01/1970 01:00:00 GMT, qui est 3600.

Voici comment j'ai essayé de mettre en œuvre cette:

return date.addingTimeInterval(-timeZone.secondsFromGMT(for: date)) 

Cela semble fonctionner le plus mais pas tout le temps. Cependant, je ne pense pas qu'il renvoie les résultats corrects si DST s'implique et le tout devient salissant. Il se sent aussi "mathématique". Je préférerais une approche sans mathématiques, en utilisant seulement les méthodes de l'API Foundation.

Alors, Comment puis-je implémenter cette méthode?

+0

Il n'y a pas de "Date zonée", une "Date" est un point absolu dans le temps. - Ce que vous pouvez faire est de créer une date à partir * des composants de date * (année, mois, jour, heure, minute, seconde), un fuseau horaire * et un calendrier. * –

+0

@MartinR Je suis conscient de cela oui. C'est pourquoi je me bats pour faire ça. J'utilise des formulaires eureka et la première ligne du tableau est en fait un 'DateTimeRow' que je ne peux obtenir qu'une' Date'. Et je veux convertir cette date à une nouvelle date en fonction du fuseau horaire sélectionné. – Sweeper

+0

Je ne peux pas le tester actuellement, mais l'ajustement par la * différence * des décalages GMT entre le fuseau horaire local et l'autre fuseau horaire devrait fonctionner. Vous pouvez également convertir Date-> DateComponents-> Date en utilisant le fuseau horaire local pour la première conversion et l'autre fuseau horaire pour la deuxième conversion. –

Répondre

1

Dans votre exemple, l'API vous donne un Date, mais vous voulez interpréter que « 18/08/2017 08:08 » dans une zone de temps donné. En supposant que l'élément d'UI de formulaires eureka utilise le fuseau horaire du calendrier actuel pour l'affichage, vous pouvez convertir la date en DateComponents et en retour en un Date avec un fuseau horaire différent.

func combine(_ date: Date, with timeZone: TimeZone) -> Date? { 
    var cal = Calendar.current 
    let comp = cal.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: date) 
    cal.timeZone = timeZone 
    return cal.date(from: comp) 
} 

nil sera retourné si la combinaison jour/heure n'existe pas dans l'autre fuseau horaire.

+0

Quand je sélectionne "aujourd'hui 8:37:37" et j'imprime la date que je reçois. C'est "2017-08-18 07:37:37 +0000". Le fuseau horaire de l'appareil est GMT + 1. Apparemment, l'API convertit la date sélectionnée en UTC. Est-ce que cela "utilise le fuseau horaire du calendrier actuel pour l'affichage" comme vous l'avez dit? – Sweeper

+0

Ensuite, comment devrais-je déterminer s'il utilise le fuseau horaire du calendrier actuel pour l'affichage? – Sweeper

+0

Quel fuseau horaire avez-vous choisi? Quelle est la 'date' avant et après la conversion? –