Come creare un oggetto data con valori in java


96

Ho bisogno di un oggetto data per la data 11/02/2014. Non posso crearlo direttamente in questo modo,

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

Quindi sto facendo come segue,

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

C'è un modo semplice per creare un oggetto data in java?


7
Cosa non è facile nel tuo approccio?
giorashc

3
"C'è un modo semplice". Cosa ti fa pensare che non sia così facile come può essere? Gli orari e le date sono molto più complicati di quanto potresti pensare. Sono disponibili più calendari e più fusi orari.
Raedwald

5
Una riga come Date myDate = new GregorianCalendar(2014, 2, 11).getTime();,?
Elliott Frisch

2
Evitare di usare uno zero in un letterale intero come visto in questa domanda, 02. In Java, ciò significa un numero ottale (base 8) anziché un numero decimale (base 10).
Basil Bourque

2
Cordiali saluti, le vecchie classi data-ora terribilmente problematiche come java.util.Date, java.util.Calendare java.text.SimpleDateFormatsono ora legacy , soppiantate dalle classi java.time incorporate in Java 8 e versioni successive. Vedi Tutorial di Oracle .
Basil Bourque

Risposte:


111

Gotcha: passare 2 come mese può dare risultati imprevisti: nell'API di Calendar, il mese è a base zero. 2 in realtà significa marzo.

Non so quale sia un modo "facile" che stai cercando perché ritengo che utilizzare Calendar sia già abbastanza facile.

Ricorda di usare le costanti corrette per il mese:

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

Un altro modo è utilizzare DateFormat, che di solito ho un'utilità come questa:

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

così posso semplicemente scrivere

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

Un'altra alternativa che preferisco: non usare più Java Date / Calendar. Passa a JODA Time o Java Time (noto anche come JSR310, disponibile in JDK 8+). È possibile utilizzare LocalDateper rappresentare una data, che può essere facilmente creata da

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()non esiste. Dovrebbe essere .getTime()(vedi Java Docs )
0xJoKe

Mi dispiace un errore di battitura. Anche se penso che OP conosca già il metodo corretto per chiamare: P
Adrian Shum

Abbastanza sicuro che tu abbia ragione. Ma per quelli (come me) che devono cercarlo ogni volta che è necessario è fastidioso. Grazie per il fissaggio :)
0xJoKe

1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) dovrebbe esserereturn new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks

Buona pesca. Non so perché ho fatto un tale errore. Risolvendolo
Adrian Shum

36

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Se insisti nell'usare la terribile vecchia java.util.Dateclasse, converti dalle moderne classi java.time .

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.   

Dettagli

Se vuoi "facile", dovresti usare il nuovo pacchetto java.time in Java 8 invece delle notoriamente fastidiose classi java.util.Date e .Calendar in bundle con Java.

java.time

Il framework java.time integrato in Java 8 e versioni successive sostituisce le vecchie e problematiche classi java.util.Date/.Calendar.

Solo data

inserisci qui la descrizione dell'immagine

Una LocalDateclasse è offerta da java.time per rappresentare un valore di sola data senza alcuna ora del giorno o fuso orario. Hai bisogno di un fuso orario per determinare una data, poiché un nuovo giorno sorge prima a Parigi che a Montréal, ad esempio. La ZoneIdclasse è per i fusi orari.

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

Scarica su console:

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

oggi: 2015-11-26 nella zona: Asia / Singapore

Oppure utilizzare un metodo di fabbrica per specificare l'anno, il mese, il giorno.

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

localDate: 2014-02-11

Oppure passa un mese numero 1-12 anziché un DayOfWeekoggetto enum.

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

Fuso orario

inserisci qui la descrizione dell'immagine

A LocalDatenon ha alcun significato reale fino a quando non lo si regola in un fuso orario. In java.time, applichiamo un fuso orario per generare un ZonedDateTimeoggetto. Ciò significa anche un'ora del giorno, ma a che ora? Di solito ha senso andare con il primo momento della giornata. Potresti pensare che significhi l'ora 00:00:00.000, ma non sempre è vero a causa dell'ora legale (DST) e forse di altre anomalie. Invece di supporre quell'ora, chiediamo a java.time di determinare il primo momento della giornata chiamando atStartOfDay.

Specificare un nome proprio fuso orario nel formato continent/region, come ad esempio America/Montreal, Africa/Casablancao Pacific/Auckland. Non usare mai il 3-4 lettera sigla come ad esempio ESTo ISTcome sono non fusi orari veri e propri, non standardizzati, e nemmeno unico (!).

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

zdt: 2014-02-11T00: 00 + 08: 00 [Asia / Singapore]

UTC

inserisci qui la descrizione dell'immagine

Per il lavoro di back-end (logica aziendale, database, archiviazione e scambio di dati) usiamo solitamente il fuso orario UTC . In java.time, la Instantclasse rappresenta un momento sulla timeline in UTC. Un oggetto Instant può essere estratto da un ZonedDateTime chiamando toInstant.

Instant instant = zdt.toInstant();

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

Convertire

Dovresti evitare di usare java.util.Datecompletamente la classe. Ma se devi interagire con il vecchio codice non ancora aggiornato per java.time , puoi eseguire la conversione avanti e indietro. Cerca nuovi metodi di conversione aggiunti alle vecchie classi.

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

…e…

Instant instant = d.toInstant() ;

Tabella di tutti i tipi di data e ora in Java, sia moderni che legacy


Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Per saperne di più, vedere il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Il progetto Joda-Time , ora in modalità di manutenzione , consiglia la migrazione alle classi java.time .

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizza un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.*classi. Hibernate 5 e JPA 2.2 supportano java.time .

Dove ottenere le classi java.time?


AGGIORNAMENTO: La libreria Joda-Time è ora in modalità di manutenzione e consiglia la migrazione alle classi java.time . Lascio questa sezione per la storia.

Joda-Time

Per prima cosa, Joda-Time utilizza una numerazione ragionevole, quindi febbraio 2non lo è 1. Un'altra cosa, un Joda-Time DateTime conosce veramente il fuso orario assegnato a differenza di un java.util.Date che sembra avere un fuso orario ma non lo fa.

E non dimenticare il fuso orario. Altrimenti otterrai l'impostazione predefinita della 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 );

Scarica su console ...

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

Quando corri ...

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

Conversione

Se è necessario convertire in un java.util.Date per l'uso con altre classi ...

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

4
Solo un commento. La pratica di anteporre gli zeri nei campi come new DateTime( 2014, 02, 11, 0, 0, timeZone );probabilmente non è preferibile. Anche se funziona in questo caso, ma, non verrà compilato per agosto e settembre se stai passando 08e 09come prefisso un int letterale con 0 significa presentazione ottale. Ti darà anche valori inaspettati per anni prima 1000, ad esempio new DateTime( 0100, 02, 01, 0, 0, timeZone );che ci si può aspettare che sia 100 d.C. ma in realtà è 64 d.C.
Adrian Shum

@AdrianShum Yikes! Non ho mai saputo che un piccolo errore di battitura innocente come uno zero iniziale su un intero letterale potesse avere un effetto collaterale così sgradevole. Grazie.
Basil Bourque,

2
Caro Down-Voter, lascia una critica insieme al tuo voto.
Basil Bourque

"Se ti ostini a usare la terribile vecchia classe java.util.Date". Molti provider non offrono server Tomcat che girano su Java oltre JDK7, quindi, anche se mi piacerebbe usare le cose più recenti, alcuni sono bloccati alla vecchia merda a causa di altri .....
KimvdLinde

@ KimvdLinde Rileggi la mia risposta con più attenzione. Guarda i proiettili. Trova le parole "Java SE 6 e Java SE 7".
Basil Bourque

15

Penso che il modo migliore sarebbe usare un SimpleDateFormatoggetto.

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

Y .. E assicurati di non usare mai YYYY - usa yyyy - specialmente se lo fai al contrario con il formato invece di analizzare. Ottieni risultati strani !!! Vedi qui: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK

12

Da Java8:

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

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

2

Prova questo

 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();
}

Le classi terribili Calendare SimpleDateFormatsono state soppiantate anni fa dalle classi java.time . Suggerirne l'uso nel 2018 è un consiglio scadente.
Basil Bourque

Questa risposta non affronta le specifiche di questa domanda.
Basil Bourque

1
Con "livelli API" presumo tu intenda Android. Ma questa non è una domanda specifica per Android. Inoltre, la maggior parte delle funzionalità java.time è stata sottoposta a back port su Java 6 e 7 nel progetto ThreeTen-Backport . Ulteriormente adattato ad Android nel progetto ThreeTenABP . Quindi, non c'è bisogno di usare quelle orribili classi data-ora legacy. Le classi java.time sono radicalmente migliori.
Basil Bourque

Grazie per questo commento Questa libreria fornisce funzioni come la differenza di data e le differenze di orario.
Syed Danish Haider

1
Sì. Cerca in Stack Overflow le numerose domande e risposte esistenti su questo argomento. E guarda anche il progetto ThreeTen-Extra (non trasferito sui primi Android).
Basil Bourque

0

Modi più semplici:

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

Si dovrebbe evitare il primo poiché la java.sql.Dateclasse che si sta utilizzando è mal progettata e obsoleta da tempo. Consiglio di usare LocalDatecome nella seconda riga. La mia abitudine è LocalDate.of(2000, Month.JANUARY, 1)che lo trovo un po 'più chiaro da leggere.
Ole VV

e questo perché la risposta contiene la dichiarazione LocalDate, non solo l'oggetto Date richiesto (non deprecato e usato a volte) ...
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));
    }
}

Il formattatore SimpleDateFormat può essere utilizzato per formattare la data secondo noi. e quindi analizzare all'interno dell'oggetto Date. Il programma sopra mostra come ottenere i giorni della settimana fornendo qualsiasi data.
Ankush,

-5

Penso che la tua data provenga da php e sia scritta in html (dom) o? Ho una funzione php per preparare tutte le date e i timestamp. Questo restituisce una formazione necessaria.

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

questo formato può essere utilizzato su js per creare una nuova data ...

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

Quello che dirò è, rendi la tua una funzione da avvolgere, che renderà la tua vita più facile. Puoi usare la mia funzione come campione ma è inclusa nel mio cms non puoi copiare e incollare 1 a 1 :)

    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
Perché stai rispondendo a una domanda Java di > 2 anni con una risposta in PHP?
Alan Hay
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.