2008-11-12 5 views
5

Je dois être en mesure de stocker une date (année/mois/jour) sans composante temporelle. C'est un concept abstrait d'une date, comme un anniversaire - je dois représenter une date dans l'année et pas un instant particulier dans le temps. J'utilise Java pour analyser la date à partir de certains textes d'entrée, et j'ai besoin de stocker dans une base de données MySQL. Quel que soit le fuseau horaire de la base de données, de l'application ou de tout client, ils doivent tous voir la même année/mois/jour.Dates sans composant de fuseau horaire ou de fuseau horaire dans Java/MySQL

Mon application s'exécutera sur une machine avec un fuseau horaire différent du serveur de base de données, et je n'en ai aucun contrôle. Est-ce que quelqu'un a une solution élégante pour m'assurer que je stocke la date correctement?

Je peux penser à ces solutions, dont aucun ne semble très agréable:

  • Interrogation ma connexion MySQL pour son fuseau horaire et analyser la date d'entrée dans ce fuseau horaire
  • processus la date tout à fait comme une chaîne aaaa -MM-dd

Répondre

2

Je conclus que la meilleure façon dans mon application en cours (un utilitaire simple en utilisant l'API JDBC directement) était d'insérer directement une chaîne. Pour une application Hibernate plus grande, je pourrais prendre la peine d'écrire mon propre type d'utilisateur. Ne peut pas croire quelqu'un n'a pas déjà résolu ce problème dans un certain code accessible au public si ...

+0

Oui, dans votre code Java, créez votre propre type de dates, ou utilisez simplement une chaîne. Un objet java.util.Date est un instant spécifique dans le temps et ne modélise pas correctement votre cas d'utilisation. – erickson

+0

J'ai un cas d'utilisation similaire: une date arbitraire indépendante de l'année pour corréler mes données aux données saisonnières. J'ai stocké le mois et le jour comme entiers plutôt que d'utiliser une chaîne, et je ne stocke aucune représentation de l'année. – AjahnCharles

2

Vous pouvez mettre à zéro tous les trucs temps/fuseau horaire:

public static Date truncateDate(Date date) 
    { 
     GregorianCalendar cal = getGregorianCalendar(); 
     cal.set(Calendar.ZONE_OFFSET, 0); // UTC 
     cal.set(Calendar.DST_OFFSET, 0); // We don't want DST to get in the way. 

     cal.setTime(date); 
     cal.set(Calendar.MILLISECOND, 0); 
     cal.set(Calendar.SECOND, 0); 
     cal.set(Calendar.MINUTE, 0); 
     cal.set(Calendar.HOUR, 0); 
     cal.set(Calendar.AM_PM, Calendar.AM); 

     return cal.getTime(); 
    } 
0

Pourriez-vous simplement utiliser le type MySQL DATE dans votre table, puis utiliser essentiellement la chaîne formatée dans votre instruction d'insertion? Je pense que quelque chose comme ça permettrait d'éviter les ajustements de fuseau horaire.

INSERT INTO time_table(dt) VALUES('2008-12-31') 
+0

Bonjour, vulnérabilité d'injection SQL! –

0

Puisque vous spécifiez que votre serveur et DB sont dans des fuseaux horaires différents, il me semble que vous avez un problème avec l'interprétation. Si vous remettez à zéro la date, ou stockez comme MM-jj-aaaa, ce qui revient à la même chose, stockez-vous la date du serveur ou la date db? S'il est 23h00 sur le serveur et 1h00 le lendemain sur la base de données, quelle date est "correcte"? Quand vous regarderez les dates d'une année à partir de maintenant, vous souviendrez-vous du nombre de machines sur lequel les dates dépendent?

Ces considérations peuvent être un peu exagérées. Mais pourquoi ne pas simplement stocker les dates en GMT (en mettant à zéro les secondes si vous voulez)?

+0

Interrogateur ne voulait pas enregistrer une instance de temps spécifique, juste la date. Une date de naissance dans ce cas. Donc, le fuseau horaire devient non pertinent, seulement quand analysé devrait le fuseau horaire local être interprété. Régler le fuseau horaire sur UTC/GMT est effectivement la même chose. Donc, je ne peux pas voir comme ... aucun point dans votre réponse du tout. Ai-je manqué quelque chose? Je pense que je dois parce que vous êtes probablement mille fois plus expérimenté que moi. –

0

La classe java.sql.Date existe exactement pour cette raison, malheureusement il est très peu pratique à utiliser, car il étend simplement java.util.Date et vous devez manuellement mettre la partie temps à zéro.