2010-04-13 14 views
66

J'ai besoin de forcer toutes les opérations liées au temps à GMT/UTC, quel que soit le fuseau horaire défini sur la machine. Un moyen pratique de le faire dans le code?Forcer le fuseau horaire Java en GMT/UTC

Pour clarifier, j'utilise l'heure du serveur DB pour toutes les opérations, mais il sort formaté selon le fuseau horaire local.

Merci!

+0

En fait, son problème est un sous-ensemble du mien, mais j'ai trouvé une solution. – SyBer

+0

Examinez la question en double et recherchez "Joda" et "DateTimeZone". –

Répondre

90

L'OP a répondu à cette question de changer le fuseau horaire par défaut pour une instance unique d'une machine virtuelle Java en cours d'exécution, définissez la propriété du système user.timezone:

java -Duser.timezone=GMT ... <main-class> 

Si vous devez définir des fuseaux horaires spécifiques lors de la récupération des objets Date/Heure/Horodatage à partir d'une base de données ResultSet, utilisez la seconde forme des méthodes getXXX qui prend un objet Calendar:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
ResultSet rs = ...; 
while (rs.next()) { 
    Date dateValue = rs.getDate("DateColumn", tzCal); 
    // Other fields and calculations 
} 

Ou, fixer la date dans un PreparedStatement:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
PreparedStatement ps = conn.createPreparedStatement("update ..."); 
ps.setDate("DateColumn", dateValue, tzCal); 
// Other assignments 
ps.executeUpdate(); 

Ces veillera à ce que la valeur stockée dans la base de données est cohérente lorsque la colonne de base de données ne conserve pas les informations de fuseau horaire. Les classes java.util.Date et java.sql.Date stockent le temps réel (en millisecondes) en UTC. Pour les formater en sortie vers un autre fuseau horaire, utilisez SimpleDateFormat. Vous pouvez également associer un fuseau horaire à la valeur à l'aide d'un objet Calendrier:

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>"); 
//... 
Date dateValue = rs.getDate("DateColumn"); 
Calendar calValue = Calendar.getInstance(tz); 
calValue.setTime(dateValue); 
+0

Une chose à noter à propos de la définition du fuseau horaire pour l'ensemble de la JVM est qu'elle affecte tout, y compris la journalisation. Juste quelque chose à garder à l'esprit si c'est l'effet désiré. –

+0

Oui, ça va. Juste un point à mentionner, que je mets réellement le user.timezone directement dans le code, plutôt que via le paramètre -D. – SyBer

+5

@SyBer: Cela fonctionne mais vous devez vous assurer que vous définissez ceci avant toute méthode appelle la méthode TimeZone.getDefault(). Sinon, vous aurez une certaine confusion puisque la valeur par défaut est mise en cache après la première exécution. Cela signifie également que cela pourrait être un problème si vous faites ceci dans une API/bibliothèque (cachée de la vue normale) - soyez sûr de documenter fortement ce que vous faites. –

6

Je voudrais récupérer l'heure de la base de données dans une forme brute (horodatage long ou java's Date), puis utilisez SimpleDateFormat pour le mettre en forme, ou Calendrier pour le manipuler. Dans les deux cas, vous devez définir le fuseau horaire des objets avant de l'utiliser.

Voir SimpleDateFormat.setTimeZone(..) et Calendar.setTimeZone(..) pour plus de détails

3

Vous pouvez changer le fuseau horaire en utilisant TimeZone.setDefault() - même temporairement, pour certaines opérations.

+0

Pas d'offense, mais modifier temporairement un état statique global sonne comme une très mauvaise idée ... –

12

Aussi, si vous pouvez définir fuseau horaire JVM cette façon

System.setProperty("user.timezone", "EST"); 

ou -Duser.timezone=GMT dans les args JVM.

7

pour moi, SimpleDateFormat juste rapide,

private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd"); 
    private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd"); 
    static { 
     GMT.setTimeZone(TimeZone.getTimeZone("GMT")); 
    SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney")); 
    } 

puis formatez la date avec fuseau horaire différent.

1

créer une paire client/serveur, de sorte qu'après l'exécution, le serveur client envoie l'heure et la date correctes. Ensuite, le client demande au serveur pm GMT et le serveur renvoie la bonne réponse.

-2

Si vous souhaitez obtenir l'heure GMT uniquement avec l'utilisateur: var currentTime = new Date(); var currentYear = '2010' var currentMonth = 10; var currentDay = '30' var currentHours = '20' var currentMinutes = '20' var currentSeconds = '00' var currentMilliseconds = '00'

currentTime.setFullYear(currentYear); 
currentTime.setMonth((currentMonth-1)); //0is January 
currentTime.setDate(currentDay); 
currentTime.setHours(currentHours); 
currentTime.setMinutes(currentMinutes); 
currentTime.setSeconds(currentSeconds); 
currentTime.setMilliseconds(currentMilliseconds); 

var currentTimezone = currentTime.getTimezoneOffset(); 
currentTimezone = (currentTimezone/60) * -1; 
var gmt =""; 
if (currentTimezone !== 0) { 
    gmt += currentTimezone > 0 ? ' +' : ' '; 
    gmt += currentTimezone; 
} 
alert(gmt) 
+2

qui ressemble à du JavaScript (! = Java) pour moi. – Phil

1

wow. Je sais que c'est un ancien thread mais tout ce que je peux dire, c'est de ne pas appeler TimeZone.setDefault() dans un code au niveau de l'utilisateur. Cela définit toujours le fuseau horaire pour l'ensemble de la JVM et est presque toujours une très mauvaise idée. Apprenez à utiliser la bibliothèque joda.time ou la nouvelle classe DateTime dans Java 8 qui est très similaire à la bibliothèque joda.time.