Comment créer un objet de date avec des valeurs en Java


91

J'ai besoin d'un objet de date pour la date 2014-02-11. Je ne peux pas le créer directement comme ça,

Date myDate = new Date(2014, 02, 11);

Alors je fais comme suit,

Calendar myCalendar = new GregorianCalendar(2014, 2, 11);
Date myDate = myCalendar.getTime();

Existe-t-il un moyen simple de créer un objet de date en java?


7
Qu'est-ce qui n'est pas facile dans votre approche?
giorashc

3
"Y a-t-il un moyen facile". Qu'est-ce qui vous fait penser que ce n'est pas aussi simple que possible? Les heures et les dates sont beaucoup plus compliquées que vous ne le pensez. Il existe plusieurs calendriers et plusieurs fuseaux horaires.
Raedwald

5
Une ligne comme Date myDate = new GregorianCalendar(2014, 2, 11).getTime();,?
Elliott Frisch

2
Attention aux utilisant un zéro dans un littéral entier comme on le voit dans cette question, 02. En Java, cela signifie un nombre octal (base 8) plutôt qu'un nombre décimal (base 10).
Basil Bourque du

2
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

Réponses:


108

Gotcha: passer 2 comme mois peut vous donner un résultat inattendu: dans l'API Calendar, le mois est basé sur zéro. 2 signifie en fait mars.

Je ne sais pas quelle est la manière «facile» que vous recherchez car j'estime que l'utilisation de Google Agenda est déjà assez simple.

N'oubliez pas d'utiliser les constantes correctes pour le mois:

 Date date = new GregorianCalendar(2014, Calendar.FEBRUARY, 11).getTime();

Une autre façon consiste à utiliser DateFormat, que j'ai généralement un utilitaire comme celui-ci:

 public static Date parseDate(String date) {
     try {
         return new SimpleDateFormat("yyyy-MM-dd").parse(date);
     } catch (ParseException e) {
         return null;
     }
  }

pour que je puisse simplement écrire

Date myDate = parseDate("2014-02-14");

Encore une autre alternative que je préfère: ne plus utiliser Java Date / Calendar. Passez à JODA Time ou Java Time (aka JSR310, disponible dans JDK 8+). Vous pouvez utiliser LocalDatepour représenter une date, qui peut être facilement créée par

LocalDate myDate =LocalDate.parse("2014-02-14");
// or
LocalDate myDate2 = new LocalDate(2014, 2, 14);
// or, in JDK 8+ Time
LocalDate myDate3 = LocalDate.of(2014, 2, 14);

1
.toTime()n'existe pas. Cela devrait être .getTime()(voir Java Docs )
0xJoKe

Désolé une faute de frappe. Bien que je pense que OP connaisse déjà la bonne méthode pour appeler: P
Adrian Shum

À peu près sûr que vous avez raison. Mais pour ceux (comme moi) qui doivent le chercher à chaque fois que c'est nécessaire, c'est ennuyeux. Merci d'avoir
corrigé

1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) devrait êtrereturn new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks le

Bonne prise. Je ne sais pas pourquoi j'ai fait une telle erreur. Fixing it
Adrian Shum

34

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Si vous insistez pour utiliser la terrible vieille java.util.Dateclasse, effectuez une conversion à partir des classes java.time modernes .

java.util.Date                        // Terrible old legacy class, avoid using. Represents a moment in UTC. 
.from(                                // New conversion method added to old classes for converting between legacy classes and modern classes.
    LocalDate                         // Represents a date-only value, without time-of-day and without time zone.
    .of( 2014 , 2 , 11 )              // Specify year-month-day. Notice sane counting, unlike legacy classes: 2014 means year 2014, 1-12 for Jan-Dec.
    .atStartOfDay(                    // Let java.time determine first moment of the day. May *not* start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).
        ZoneId.of( "Africa/Tunis" )   // Specify time zone as `Continent/Region`, never the 3-4 letter pseudo-zones like `PST`, `EST`, or `IST`. 
    )                                 // Returns a `ZonedDateTime`.
    .toInstant()                      // Adjust from zone to UTC. Returns a `Instant` object, always in UTC by definition.
)                                     // Returns a legacy `java.util.Date` object. Beware of possible data-loss as any microseconds or nanoseconds in the `Instant` are truncated to milliseconds in this `Date` object.   

Détails

Si vous voulez "facile", vous devriez utiliser le nouveau package java.time dans Java 8 plutôt que les classes notoirement gênantes java.util.Date et .Calendar fournies avec Java.

java.time

Le framework java.time intégré à Java 8 et versions ultérieures remplace les anciennes classes gênantes java.util.Date/.Calendar.

Date uniquement

entrez la description de l'image ici

Une LocalDateclasse est proposée par java.time pour représenter une valeur de date uniquement sans heure ni fuseau horaire. Vous avez besoin d'un fuseau horaire pour déterminer une date, car un nouveau jour se lève plus tôt à Paris qu'à Montréal par exemple. La ZoneIdclasse est pour les fuseaux horaires.

ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
LocalDate today = LocalDate.now( zoneId );

Vider dans la console:

System.out.println ( "today: " + today + " in zone: " + zoneId );

aujourd'hui: 26/11/2015 dans la zone: Asie / Singapour

Ou utilisez une méthode d'usine pour spécifier l'année, le mois, le jour.

LocalDate localDate = LocalDate.of( 2014 , Month.FEBRUARY , 11 );

localDate: 11/02/2014

Ou passez un numéro de mois 1-12 plutôt qu'un DayOfWeekobjet enum.

LocalDate localDate = LocalDate.of( 2014 , 2 , 11 );

Fuseau horaire

entrez la description de l'image ici

A LocalDaten'a aucune signification réelle tant que vous ne l'avez pas ajusté dans un fuseau horaire. Dans java.time, nous appliquons un fuseau horaire pour générer un ZonedDateTimeobjet. Cela signifie également une heure de la journée, mais à quelle heure? Il est généralement logique de suivre le premier moment de la journée. Vous pourriez penser que cela signifie l'heure 00:00:00.000, mais pas toujours vrai à cause de l'heure d'été (DST) et peut-être d'autres anomalies. Au lieu de supposer cette heure, nous demandons à java.time de déterminer le premier moment de la journée en appelant atStartOfDay.

Indiquez un nom de fuseau horaire approprié dans le format continent/region, tels que America/Montreal, Africa/Casablancaou Pacific/Auckland. N'utilisez jamais l'abréviation de 3 à 4 lettres telle que ESTou ISTcar ce ne sont pas de vrais fuseaux horaires, ni standardisés, ni même uniques (!).

ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
ZonedDateTime zdt = localDate.atStartOfDay( zoneId );

zdt: 2014-02-11T00: 00 + 08: 00 [Asie / Singapour]

UTC

entrez la description de l'image ici

Pour le travail back-end (logique métier, base de données, stockage et échange de données), nous utilisons généralement le fuseau horaire UTC . Dans java.time, la Instantclasse représente un moment sur la chronologie en UTC. Un objet Instant peut être extrait d'un ZonedDateTime en appelant toInstant.

Instant instant = zdt.toInstant();

instant: 2014-02-10T16: 00: 00Z

Convertir

Vous devriez éviter java.util.Datecomplètement d' utiliser la classe. Mais si vous devez interagir avec un ancien code non encore mis à jour pour java.time , vous pouvez effectuer une conversion d'avant en arrière. Recherchez de nouvelles méthodes de conversion ajoutées aux anciennes classes.

java.util.Date d = java.util.from( instant ) ;

…et…

Instant instant = d.toInstant() ;

Tableau de tous les types de date-heure en Java, à la fois modernes et hérités


À 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.

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

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

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. Hibernate 5 et JPA 2.2 prennent en charge java.time .

Où obtenir les classes java.time?


MISE À JOUR: La bibliothèque Joda-Time est maintenant en mode maintenance et conseille la migration vers les classes java.time . Je laisse cette section en place pour l'histoire.

Joda-Time

D'une part, Joda-Time utilise une numérotation judicieuse, donc février 2ne l' est pas 1. Une autre chose, un Joda-Time DateTime connaît vraiment son fuseau horaire attribué contrairement à un java.util.Date qui semble avoir un fuseau horaire mais pas.

Et n'oubliez pas le fuseau horaire. Sinon, vous obtiendrez la valeur par défaut de la JVM.

DateTimeZone timeZone = DateTimeZone.forID( "Asia/Singapore" );
DateTime dateTimeSingapore = new DateTime( 2014, 2, 11, 0, 0, timeZone );
DateTime dateTimeUtc = dateTimeSingapore.withZone( DateTimeZone.UTC );

java.util.Locale locale = new java.util.Locale( "ms", "SG" ); // Language: Bahasa Melayu (?). Country: Singapore.
String output = DateTimeFormat.forStyle( "FF" ).withLocale( locale ).print( dateTimeSingapore );

Vider dans la console…

System.out.println( "dateTimeSingapore: " + dateTimeSingapore );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "output: " + output );

Lors de l'exécution…

dateTimeSingapore: 2014-02-11T00:00:00.000+08:00
dateTimeUtc: 2014-02-10T16:00:00.000Z
output: Selasa, 2014 Februari 11 00:00:00 SGT

Conversion

Si vous devez convertir en java.util.Date pour une utilisation avec d'autres classes…

java.util.Date date = dateTimeSingapore.toDate();

4
Juste un commentaire. La pratique de préfixer des zéros dans les champs comme new DateTime( 2014, 02, 11, 0, 0, timeZone );n'est probablement pas préférable. Bien que cela fonctionne dans ce cas, mais, il ne se compilera pas pour août et septembre si vous passez 08et 09comme préfixer un littéral int avec 0 signifie une présentation octale. Cela vous donnera même des valeurs inattendues pour des années auparavant 1000, par exemple, new DateTime( 0100, 02, 01, 0, 0, timeZone );que l'on peut s'attendre à ce que ce soit 100AD mais en fait c'est 64AD
Adrian Shum

@AdrianShum Yikes! Je n'ai jamais su qu'une petite faute de frappe innocente comme un zéro non significatif sur un littéral entier pouvait avoir un effet secondaire aussi désagréable. Merci.
Basil Bourque

2
Cher Down-Voter, laissez une critique avec votre vote.
Basil Bourque

"Si vous insistez pour utiliser la terrible vieille classe java.util.Date". De nombreux fournisseurs n'offrent pas de serveurs tomcat fonctionnant sur Java au-delà de JDK7, donc, même si j'aimerais utiliser les nouveaux éléments, certains sont bloqués à l'ancienne à cause d'autres .....
KimvdLinde

@KimvdLinde Relisez ma réponse plus attentivement. Regardez les balles. Trouvez les mots «Java SE 6 et Java SE 7».
Basil Bourque

14

Je pense que la meilleure façon serait d'utiliser un SimpleDateFormatobjet.

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2014-02-11";
Date dateObject = sdf.parse(dateString); // Handle the ParseException here

O .. Et assurez-vous de ne jamais utiliser YYYY - utilisez yyyy - surtout si vous faites cela en sens inverse avec le format au lieu de l'analyse. Vous obtenez des résultats étranges !!! Voir ici: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK

9

Depuis Java8:

import java.time.Instant;
import java.util.Date;

Date date = Date.from(Instant.parse("2000-01-01T00:00:00.000Z"))

2

Essaye ça

 Calendar cal = Calendar.getInstance();
    Date todayDate = new Date();
    cal.setTime(todayDate);

    // Set time fields to zero
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    todayDate = cal.getTime();

1
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.ENGLISH);
//format as u want

try {
    String dateStart = "June 14 2018 16:02:37";
    cal.setTime(sdf.parse(dateStart));
    //all done
} catch (ParseException e) {
    e.printStackTrace();
}

Les classes terribles Calendaret SimpleDateFormatont été supplantées il y a des années par les classes java.time . Suggérer leur utilisation en 2018 est un mauvais conseil.
Basil Bourque

Cette réponse n'aborde pas les détails de cette question.
Basil Bourque

1
Par "niveaux d'API", je suppose que vous entendez Android. Mais ce n'est pas une question spécifique à Android. De plus, la plupart des fonctionnalités java.time sont rétroportées vers Java 6 et 7 dans le projet ThreeTen-Backport . Adapté davantage à Android dans le projet ThreeTenABP . Donc, pas besoin d'utiliser ces horribles classes de date-heure héritées. Les classes java.time sont radicalement meilleures.
Basil Bourque

Merci pour ce commentaire Cette bibliothèque fournit-elle des fonctions telles que le décalage de date et le décalage horaire.
Syed Danish Haider

1
Oui. Recherchez Stack Overflow pour les nombreuses questions et réponses existantes sur ce sujet. Et voyez aussi le projet ThreeTen-Extra (non rétroporté sur le début d'Android).
Basil Bourque

0

Les moyens les plus simples:

Date date = Date.valueOf("2000-1-1");
LocalDate localdate = LocalDate.of(2000,1,1);
LocalDateTime localDateTime = LocalDateTime.of(2000,1,1,0,0);

Il faut éviter le premier car la java.sql.Dateclasse que vous utilisez est mal conçue et obsolète depuis longtemps. Je recommande d'utiliser LocalDatecomme dans la deuxième ligne. Mon habitude est que LocalDate.of(2000, Month.JANUARY, 1)je trouve cela un peu plus clair à lire.
Ole VV le

et cela parce que la réponse contient une déclaration LocalDate, pas seulement un objet Date demandé (non obsolète et parfois utilisé) ...
Adam Silenko

-1
import java.io.*;
import java.util.*;
import java.util.HashMap;

public class Solution 
{

    public static void main(String[] args)
    {
        HashMap<Integer,String> hm = new HashMap<Integer,String>();
        hm.put(1,"SUNDAY");
        hm.put(2,"MONDAY");
        hm.put(3,"TUESDAY");
        hm.put(4,"WEDNESDAY");
        hm.put(5,"THURSDAY");
        hm.put(6,"FRIDAY");
        hm.put(7,"SATURDAY");
        Scanner in = new Scanner(System.in);
        String month = in.next();
        String day = in.next();
        String year = in.next();

        String format = year + "/" + month + "/" + day;
        Date date = null;
        try
        {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
            date = formatter.parse(format);
        }
        catch(Exception e){
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        System.out.println(hm.get(dayOfWeek));
    }
}

Le formateur SimpleDateFormat peut être utilisé pour formater la date selon nous. puis analyse à l'intérieur de l'objet Date. Le programme ci-dessus montre comment obtenir des jours de la semaine en donnant n'importe quelle date.
Ankush

-5

Je pense que votre date vient de php et est écrite en html (dom) ou? J'ai une fonction php pour préparer toutes les dates et horodatages. Ce retour une formation qui s'impose.

$timeForJS = timeop($datetimeFromDatabase['payedon'], 'js', 'local'); // save 10/12/2016 09:20 on var

ce format peut être utilisé sur js pour créer une nouvelle Date ...

<html>
   <span id="test" data-date="<?php echo $timeForJS; ?>"></span>
   <script>var myDate = new Date( $('#test').attr('data-date') );</script>
</html>

Ce que je vais dire, c'est, faites votre propre fonction à envelopper, qui rend votre vie plus facile. Vous pouvez utiliser mon func comme exemple mais est inclus dans mon cms vous ne pouvez pas 1 à 1 copier et coller :)

    function timeop($utcTime, $for, $tz_output = 'system')
{
    // echo "<br>Current time ( UTC ): ".$wwm->timeop('now', 'db', 'system');
    // echo "<br>Current time (USER): ".$wwm->timeop('now', 'db', 'local');
    // echo "<br>Current time (USER): ".$wwm->timeop('now', 'D d M Y H:i:s', 'local');
    // echo "<br>Current time with user lang (USER): ".$wwm->timeop('now', 'datetimes', 'local');

    // echo '<br><br>Calculator test is users timezone difference != 0! Tested with "2014-06-27 07:46:09"<br>';
    // echo "<br>Old time (USER -> UTC): ".$wwm->timeop('2014-06-27 07:46:09', 'db', 'system');
    // echo "<br>Old time (UTC -> USER): ".$wwm->timeop('2014-06-27 07:46:09', 'db', 'local');

    /** -- */
    // echo '<br><br>a Time from db if same with user time?<br>';
    // echo "<br>db-time (2019-06-27 07:46:09) time left = ".$wwm->timeleft('2019-06-27 07:46:09', 'max');
    // echo "<br>db-time (2014-06-27 07:46:09) time left = ".$wwm->timeleft('2014-06-27 07:46:09', 'max', 'txt');

    /** -- */
    // echo '<br><br>Calculator test with other formats<br>';
    // echo "<br>2014/06/27 07:46:09: ".$wwm->ntimeop('2014/06/27 07:46:09', 'db', 'system');

    switch($tz_output){
        case 'system':
            $tz = 'UTC';
            break;

        case 'local':
            $tz = $_SESSION['wwm']['sett']['tz'];
            break;

        default:
            $tz = $tz_output;
            break;
    }

    $date = new DateTime($utcTime,  new DateTimeZone($tz));

    if( $tz != 'UTC' ) // Only time converted into different time zone
    {
        // now check at first the difference in seconds
        $offset = $this->tz_offset($tz);
        if( $offset != 0 ){
            $calc = ( $offset >= 0  ) ? 'add' : 'sub';
            // $calc = ( ($_SESSION['wwm']['sett']['tzdiff'] >= 0 AND $tz_output == 'user') OR ($_SESSION['wwm']['sett']['tzdiff'] <= 0 AND $tz_output == 'local') ) ? 'sub' : 'add';
            $offset = ['math' => $calc, 'diff' => abs($offset)];
            $date->$offset['math']( new DateInterval('PT'.$offset['diff'].'S') ); // php >= 5.3 use add() or sub()
        }
    }

    // create a individual output
    switch( $for ){
        case 'js':
            $format = 'm/d/Y H:i'; // Timepicker use only this format m/d/Y H:i without seconds // Sett automatical seconds default to 00
            break;
        case 'js:s':
            $format = 'm/d/Y H:i:s'; // Timepicker use only this format m/d/Y H:i:s with Seconds
            break;
        case 'db':
            $format = 'Y-m-d H:i:s'; // Database use only this format Y-m-d H:i:s
            break;
        case 'date':
        case 'datetime':
        case 'datetimes':
            $format = wwmSystem::$languages[$_SESSION['wwm']['sett']['isolang']][$for.'_format']; // language spezific output
            break;
        default:
            $format = $for;
            break;
    }

    $output = $date->format( $format );

    /** Replacement
     * 
     * D = day short name
     * l = day long name
     * F = month long name
     * M = month short name
     */
    $output = str_replace([
        $date->format('D'),
        $date->format('l'),
        $date->format('F'),
        $date->format('M')
    ],[
        $this->trans('date', $date->format('D')),
        $this->trans('date', $date->format('l')),
        $this->trans('date', $date->format('F')),
        $this->trans('date', $date->format('M'))
    ], $output);

    return $output; // $output->getTimestamp();
}

2
Pourquoi répondez-vous à une question Java de > 2 ans avec une réponse en PHP?
Alan Hay
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.