Horodatage Java - Comment créer un horodatage avec la date 23/09/2007?

Réponses:

154

Par Timestamp, je suppose que vous voulez dire java.sql.Timestamp. Vous remarquerez que cette classe a un constructeur qui accepte un longargument. Vous pouvez analyser cela en utilisant la DateFormatclasse:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);
Adam Paynter
la source
1
Le format de date ISO normal est aaaa-MM-jj, sinon génial!
vidstige
1
nouvel horodatage (heure); donnant une erreur qu'aucun constructeur comme celui-ci prend une valeur longue :(
Bhanu Sharma
1
@Bhanu La documentation montre que cela prend une valeur longue et semble fonctionner correctement: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok
FYI, les anciennes classes de date-heure terriblement gênantes telles que java.util.Date , java.util.Calendaret java.text.SimpleDateFormatsont maintenant héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir le didacticiel d'Oracle .
Basil Bourque
121

Et ça?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
Pigouina
la source
1
Timestamp timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); indique que la méthode valueOf n'est pas définie pour le type Timestamp dans jDK 7
Ashish Ratan
nouvel horodatage (heure); donnant l'erreur qu'aucun constructeur comme celui-ci ne prend une valeur de chaîne :(
Bhanu Sharma
@Bhanu Le constructeur prend le temps unix en millisecondes. Utilisez la méthode statique valueOf si vous souhaitez obtenir un horodatage à partir d'une chaîne.
Hazok
4
Cela semble être la meilleure réponse à la question.
Hazok
1
La meilleure réponse a Date, qui est obsolète, est une mauvaise pratique pour l'utiliser. Cette réponse est meilleure. Merci
Alberici
18

Que voulez-vous dire horodatage? Si vous voulez dire millisecondes depuis l'époque Unix:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

Si vous voulez un objet java.sql.Timestamp réel:

Timestamp ts = new Timestamp(millis);
Matthew Flaschen
la source
2
FAUX et ne compilera pas! Erreur de compilation: 09 est un nombre octal, mais 9 est hors de portée pour les octals. Erreur de logique: le mois est basé sur 0, vous obtiendrez le 23 OCTOBRE 2007
user85421
Je ne peux pas obtenir d'erreur de logique s'il ne compile pas. :) Sérieusement, bonnes prises, Carlos. L'octal j'ai attrapé avant mais collé mal de toute façon. :(
Matthew Flaschen
En fait, le constructeur Timestamp est déprécié plutôt que vous pouvez utiliser la méthode Timestamp.valueOf ()
Shiva Komuravelly
@ShivaKomuravelly tous les constructeurs d'horodatage ne sont pas obsolètes et du moins pas, ce qui prend autant de millisecondes, le constructeur qui prend la date comme argument est obsolète
pas de nom
Et il y a une constante pour ça (au lieu de mois = 9):Calendar.SEPTEMBER
Guillaume Husta
11

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

Mettons à jour cette page en affichant le code à l'aide de java.time framework intégré à Java 8 et supérieur.

Ces nouvelles classes sont inspirées de Joda-Time , défini par JSR 310 , et étendues par le ThreeTen-Extra projet . Ils remplacent les anciennes classes date-heure notoirement gênantes fournies avec les premières versions de Java.

Dans java.time, an Instantest un moment sur la chronologie en UTC. A ZonedDateTimeest un instant ajusté dans un fuseau horaire ( ZoneId).

Le fuseau horaire est crucial ici. Une date de September 23, 2007ne peut pas être traduite en un moment de la chronologie sans appliquer un fuseau horaire. Considérez qu'un nouveau jour se lève plus tôt à Paris qu'à Montréal où il est encore «hier».

En outre, un java.sql.Timestamp représente à la fois une date et une heure du jour. Il faut donc injecter une heure pour accompagner la date. Nous supposons que vous voulez que le premier moment de la journée soit l'heure de la journée. Notez que ce n'est pas toujours le moment00:00:00.0 cause de l'heure d'été et éventuellement d'autres anomalies.

Notez que contrairement à l'ancienne classe java.util.Date, et contrairement à Joda-Time, les types java.time ont une résolution de nanosecondes plutôt que de millisecondes. Cela correspond à la résolution de java.sql.Timestamp.

Notez que java.sql.Timestamp a la mauvaise habitude d'appliquer implicitement le fuseau horaire par défaut actuel de votre JVM à sa valeur date-heure lors de la génération d'une représentation sous forme de chaîne via sa toStringméthode. Ici, vous voyez mon America/Los_Angelesfuseau horaire appliqué. En revanche, les classes java.time sont plus saines, utilisant les formats standard ISO 8601 .

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

Dump dans la console.

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

Lorsqu'il est exécuté.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [Amérique / Montréal] = instant: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00,0

D'ailleurs, à partir de JDBC 4.2, vous pouvez utiliser directement les types java.time. Pas besoin de java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*classes.

Où obtenir les classes java.time?

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .

Basil Bourque
la source
3
Je me demande comment je peux obtenir OP ou mods pour marquer votre réponse comme la bonne. La réponse acceptée est tellement dépassée.
sttaq
Très bien, sauf pour une faute de frappe. asStartOfDay () doit être atStartOfDay ().
Tullochgorum
@Tullochgorum Fixé. Merci. Pour info, sur Stack Overflow, vous êtes invités à effectuer vous-même de telles modifications, si vous le souhaitez.
Basil Bourque
5

Vous pouvez également effectuer les opérations suivantes:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());
Alex
la source
2
FAUX: essayez un System.out.println du résultat! Vous obtiendrez quelque chose comme: "2009-10-23 15: 26: 56.171" Le mois est basé sur 0 donc le 9 est octobre!
user85421
Je savais qu'une de ces constantes était basée sur zéro, merci. Message mis à jour.
Alex
1
Oh, et j'ai mis 'non testé' :)
Alex
4

Selon l' API, le constructeur qui accepterait l'année, le mois, etc. est obsolète. Au lieu de cela, vous devez utiliser le constructeur qui accepte un long. Vous pouvez utiliser une implémentation de Calendar pour construire la date souhaitée et accéder à la représentation temporelle sous forme de long, par exemple avec la méthode getTimeInMillis .

Philipp
la source
1

Par souci d'exhaustivité, également une solution avec Joda-Time version 2.5 et sa DateTimeclasse:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
utilisateur152468
la source
1
Bonne réponse, mais vous avez manqué un élément crucial : le fuseau horaire . Si vous omettez un fuseau horaire, le fuseau horaire par défaut actuel de la machine virtuelle Java est appliqué à l' DateTimeobjet. Cela signifie que vos résultats varieront selon les ordinateurs ou la configuration des paramètres du système d'exploitation hôte ou de la JVM. Pour des résultats prévisibles, transmettez un fuseau horaire à ce DateTimeconstructeur. Choisissez le nom de fuseau horaire approprié pour votre intention. Par exemple, DateTimeZone.forID( "America/Montreal" )ou DateTimeZone.UTC.
Basil Bourque
Ce code pourrait être plus bref. Pas besoin de convertir en java.util.Date pour obtenir et passer des millisecondes depuis l' époque . Demandez simplement à l' DateTimeobjet ses millisecondes depuis l'époque. Remplacez .toDate().getTime()par .getMillis().
Basil Bourque
@BasilBourque Selon les circonstances, vous voudrez peut-être omettre le fuseau horaire pour obtenir des résultats prévisibles. "Dans votre fuseau horaire actuel" peut être un résultat parfaitement raisonnable et prévisible. Pourquoi coder en dur un fuseau horaire ou demander à vos utilisateurs de définir manuellement un fuseau horaire alors que leur ordinateur a déjà un fuseau horaire défini? Je serais certainement très surpris si une application sur mon ordinateur commençait à produire des dates ajustées au fuseau horaire Amérique / Montréal.
dan carter
@dancarter L'omission du fuseau horaire facultatif est source de confusion. L'omission soulève l'ambiguïté de (a) le programmeur avait-il l'intention de s'appuyer sur la valeur implicite par défaut ou (b) le programmeur n'a-t-il pas pris en compte les problèmes de fuseau horaire (ce qui est trop courant). Si vous voulez en effet utiliser le fuseau horaire par défaut actuel de la JVM, dites-le explicitement en appelant DateTimeZone.getDefault()et en passant le résultat comme argument facultatif. (Au fait, idem pour Locale.getDefault(), même problème sur l'ambiguïté des arguments optionnels.)
Basil Bourque
-1

Une réponse plus générale serait d'importer java.util.Date, puis lorsque vous devez définir un timestampégal à la date actuelle, il suffit de le définir égal à new Date().

CSquid
la source
parce que ** Date ("chaîne"); ** est obsolète
Ashish Ratan