En fait, Chris Lercher mettre le doigt dessus, mais il ne fait dans un bref commentaire, donc je voulais développer sur elle.
Imaginez deux chronomètres; l'un est quelque part où UTC est l'heure locale le 1er janvier 1970, et l'autre chronomètre est local dans votre région (disons que c'est à New York, 5 heures après l'UTC). À UTC minuit, le 1er janvier 1970, le chronomètre UTC est démarré. 5 heures plus tard, votre chronomètre local est démarré. Ces deux temps de chronométrage diffèrent d'un certain montant, déterminé uniquement par la différence entre l'heure UTC et l'heure locale à locale minuit le 1er janvier 1970. Toutes les manigances de l'heure d'été, depuis lors, n'ont aucune incidence sur la différence entre ces chronomètres. Donc, toutes les corrections DST pour votre présent fois ou pour les fois où vous êtes convertir, sont hors de propos.Tout ce dont vous avez besoin est de savoir combien de temps plus tard votre chronomètre local a commencé le 1er janvier 1970.
Comme Chris l'a souligné, cela est juste: getOffset (0L), donc:
int offset = TimeZone.getDefault().getOffset(0L);
long newTime = oldTime - offset;
... devrait fonctionner correctement. Cependant ....
Pour vraiment aider saisir cela, notez ceci: « 0L » dans getOffset() est le nombre de millisecondes depuis l'époque UTC (qui est la seule époque réelle). Donc, votre variable offset va avoir le nombre de secondes de décalage à minuit UTC (c'est-à-dire, quand il était, disons, 19:00 le 31/12/1969 à New York). Si votre heure locale est passée de/à l'heure d'été dans ces dernières heures avant local minuit, alors getOffset (0L) ne serait pas correct. Vous devez savoir quel était votre statut en matière d'heure d'été au local à minuit, pas à minuit UTC. Je serais surpris si c'était le cas, n'importe où (c.-à-d., N'importe quel fuseau horaire qui a changé de/à DST entre leur minuit local et UTC minuit du 1er janvier 1970). Cependant, juste pour le plaisir, un hack pas cher pour aider à se prémunir contre ce serait de vérifier si le décalage changé dans les heures:
// Offset at UTC midnight
int offset = TimeZone.getDefault().getOffset(0L);
long newTime = oldTime - offset;
// Offset at Local midnight
int localMidnightOffset = TimeZone.getDefault().getOffset(-offset);
Ici, localMidnightOffset sera ce que le décalage horaire était à un moment -offset millisecondes après UTC minuit en 1970. Si aucun changement d'heure d'été n'a eu lieu, alors localMidnightOffset sera égal à l'offset, et vous avez terminé. Si un changement DST a se produit, alors vous pourriez avoir à chasser autour ... probablement continuer à faire un
localMidnightOffset = TimeZone.getDefault().getOffset(-localMidnightOffset)
jusqu'à ce qu'il cesse de changer ... et espérons que vous ne soyez pas pris dans une boucle sans fin. Je suis curieux de voir si quelqu'un a une solution convergente garantie. Kinda vous fait souhaiter que le monde soit plat, hein?
Cela ne tient pas compte du DST du tout. –
@Quartz - ça n'a pas à le faire, puisque nous avons affaire à des deltas de l'époque. Avez-vous un exemple (zone et timeSinceLocalEpoch) où cela échoue? – leedm777