So erstellen Sie ein Datumsobjekt mit Werten in Java


88

Ich benötige ein Datumsobjekt für das Datum 2014-02-11. Ich kann es nicht direkt so erstellen,

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

Also mache ich wie folgt:

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

Gibt es eine einfache Möglichkeit, ein Datumsobjekt in Java zu erstellen?


6
Was ist in Ihrem Ansatz nicht einfach?
Giorashc

3
"Gibt es einen einfachen Weg". Was lässt Sie denken, dass das nicht so einfach ist, wie es sein kann? Zeiten und Daten sind viel komplizierter als Sie vielleicht denken. Es gibt mehrere Kalender und mehrere Zeitzonen.
Raedwald

5
Eine Zeile wie Date myDate = new GregorianCalendar(2014, 2, 11).getTime();?
Elliott Frisch

2
Achten Sie darauf, dass Sie in einem ganzzahligen Literal keine führende Null verwenden, wie in dieser Frage dargestellt 02. In Java bedeutet dies eher eine Oktalzahl (Basis-8) als eine Dezimalzahl (Basis-10).
Basil Bourque

2
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

Antworten:


103

Gotcha: Wenn Sie 2 als Monat übergeben, erhalten Sie möglicherweise ein unerwartetes Ergebnis: In der Kalender-API basiert der Monat auf Null. 2 bedeutet eigentlich März.

Ich weiß nicht, wonach Sie suchen, da ich der Meinung bin, dass die Verwendung des Kalenders bereits einfach genug ist.

Denken Sie daran, die richtigen Konstanten für den Monat zu verwenden:

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

Eine andere Möglichkeit besteht darin, DateFormat zu verwenden, das ich normalerweise wie folgt verwende:

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

damit ich einfach schreiben kann

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

Eine weitere Alternative, die ich bevorzuge: Verwenden Sie kein Java-Datum / Kalender mehr. Wechseln Sie zu JODA Time oder Java Time (auch bekannt als JSR310, verfügbar in JDK 8+). Sie können LocalDateein Datum darstellen, das einfach von erstellt werden kann

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()existiert nicht. Es sollte sein .getTime()(siehe Java Docs )
0xJoKe

Entschuldigung ein Tippfehler. Obwohl ich denke, dass OP bereits die richtige Methode zum Aufrufen kennt: P
Adrian Shum

Ich bin mir ziemlich sicher, dass Sie Recht haben. Aber für diejenigen (wie mich), die es jedes Mal nachschlagen müssen, wenn es gebraucht wird, ist es ärgerlich. Vielen Dank für die
Korrektur

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

Guter Fang. Keine Ahnung, warum ich so einen Fehler gemacht habe. Reparieren
Adrian Shum

32

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Wenn Sie darauf bestehen, die schreckliche alte java.util.DateKlasse zu verwenden, konvertieren Sie von den modernen java.time- Klassen.

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.   

Einzelheiten

Wenn Sie "einfach" möchten, sollten Sie das neue Paket java.time verwenden in Java 8 verwenden und nicht die notorisch problematischen Klassen java.util.Date & .Calendar, die mit Java gebündelt sind.

java.time

Die java.time in Java 8 und höher integrierte Framework ersetzt die problematischen alten Klassen java.util.Date/.Calendar.

Nur Datum

Geben Sie hier die Bildbeschreibung ein

LocalDateVon java.time wird eine Klasse angeboten, die einen Nur-Datum-Wert ohne Tageszeit oder Zeitzone darstellt. Sie benötigen eine Zeitzone, um ein Datum zu bestimmen, da in Paris ein neuer Tag früher beginnt als beispielsweise in Montréal. Die ZoneIdKlasse ist für Zeitzonen.

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

Dump zur Konsole:

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

heute: 26.11.2015 in Zone: Asien / Singapur

Oder verwenden Sie eine Factory-Methode, um Jahr, Monat und Tag anzugeben.

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

localDate: 11.02.2014

Oder übergeben Sie eine Monatsnummer 1-12 anstelle eines DayOfWeekAufzählungsobjekts.

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

Zeitzone

Geben Sie hier die Bildbeschreibung ein

A LocalDatehat keine wirkliche Bedeutung, bis Sie es in eine Zeitzone einstellen. In java.time wenden wir eine Zeitzone an, um ein ZonedDateTimeObjekt zu generieren . Das bedeutet auch eine Tageszeit, aber zu welcher Zeit? Normalerweise macht es Sinn, mit dem ersten Moment des Tages zu gehen. Sie könnten denken, dass dies die Zeit bedeutet 00:00:00.000, aber aufgrund der Sommerzeit (DST) und möglicherweise anderer Anomalien nicht immer wahr ist. Anstatt diese Zeit anzunehmen, bitten wir java.time, den ersten Moment des Tages durch einen Anruf zu bestimmen atStartOfDay.

Geben Sie einen richtigen Zeitzonennamen im Format continent/region, wie zum Beispiel America/Montreal, Africa/Casablancaoder Pacific/Auckland. Verwenden Sie niemals die Abkürzung mit 3-4 Buchstaben, da ESToder ISTda es sich nicht um echte Zeitzonen handelt, die nicht standardisiert und nicht einmal eindeutig (!) Sind.

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

zdt: 2014-02-11T00: 00 + 08: 00 [Asien / Singapur]

koordinierte Weltzeit

Geben Sie hier die Bildbeschreibung ein

Für Back-End-Arbeiten (Geschäftslogik, Datenbank, Datenspeicherung und -austausch) verwenden wir normalerweise die UTC- Zeitzone. In java.time Instantrepräsentiert die Klasse einen Moment auf der Zeitachse in UTC. Ein Instant-Objekt kann durch Aufrufen aus einer ZonedDateTime extrahiert werden toInstant.

Instant instant = zdt.toInstant();

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

Konvertieren

Sie sollten die Verwendung von java.util.Dateclass vollständig vermeiden . Wenn Sie jedoch mit altem Code zusammenarbeiten müssen, der für java.time noch nicht aktualisiert wurde , können Sie hin und her konvertieren. Suchen Sie nach neuen Konvertierungsmethoden, die zu den alten Klassen hinzugefügt wurden.

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

…und…

Instant instant = d.toInstant() ;

Tabelle aller Datums- und Uhrzeittypen in Java, sowohl moderne als auch ältere


Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*Klassen. Hibernate 5 und JPA 2.2 unterstützen java.time .

Woher bekomme ich die java.time-Klassen?


UPDATE: Die Joda-Time- Bibliothek befindet sich jetzt im Wartungsmodus und empfiehlt die Migration zu den Klassen java.time . Ich lasse diesen Abschnitt für die Geschichte an Ort und Stelle.

Joda-Zeit

Zum einen verwendet Joda-Time eine sinnvolle Nummerierung, der Februar also 2nicht 1. Eine andere Sache, eine Joda-Time DateTime kennt die zugewiesene Zeitzone wirklich, im Gegensatz zu einer java.util.Date, die eine Zeitzone zu haben scheint, dies aber nicht tut.

Und vergessen Sie nicht die Zeitzone. Andernfalls erhalten Sie die Standardeinstellung der 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 );

Auf die Konsole werfen ...

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

Beim Laufen…

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

Umwandlung

Wenn Sie zur Verwendung mit anderen Klassen in ein java.util.Date konvertieren müssen…

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

4
Nur ein Kommentar. Das new DateTime( 2014, 02, 11, 0, 0, timeZone );Präfixieren von Nullen in Feldern wie ist wahrscheinlich nicht vorzuziehen. Obwohl es in diesem Fall funktioniert, aber wird es nicht für August und September kompiliert , wenn Sie vorbei 08und 09als ein int wörtlichen mit 0 bedeuten Oktal Präsentation prefixing. Es gibt Ihnen sogar unerwartete Werte für Jahre zuvor 1000, z. B. new DateTime( 0100, 02, 01, 0, 0, timeZone );dass man erwarten kann, dass es 100AD ist, aber tatsächlich ist es 64AD
Adrian Shum

@AdrianShum Yikes! Ich hätte nie gedacht, dass ein unschuldiger kleiner Tippfehler wie eine führende Null in einem ganzzahligen Literal eine so schlimme Nebenwirkung haben könnte. Vielen Dank.
Basil Bourque

2
Lieber Down-Voter, hinterlasse eine Kritik zusammen mit deiner Stimme.
Basil Bourque

"Wenn Sie darauf bestehen, die schreckliche alte Klasse java.util.Date zu verwenden". Viele Anbieter bieten keine Tomcat-Server an, die über JDK7 hinaus auf Java ausgeführt werden. Obwohl ich die neueren Inhalte gerne verwenden würde, stecken einige wegen anderer bei der alten Scheiße fest .....
KimvdLinde

@KimvdLinde Lesen Sie meine Antwort noch einmal genauer durch. Schau dir die Kugeln an. Suchen Sie die Wörter "Java SE 6 und Java SE 7".
Basil Bourque

11

Ich denke, der beste Weg wäre, ein SimpleDateFormatObjekt zu verwenden.

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

Y .. Und stellen Sie sicher, dass Sie niemals JJJJ verwenden - verwenden Sie JJJJ - insbesondere, wenn Sie dies in umgekehrter Reihenfolge mit Format anstelle von Analyse tun. Sie erhalten einige seltsame Ergebnisse !!! Siehe hier: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK

9

Von Java8:

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

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

2

Versuche dies

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

Das Schreckliche Calendarund die SimpleDateFormatKlassen wurden vor Jahren durch die java.time- Klassen ersetzt. Die Verwendung im Jahr 2018 vorzuschlagen, ist ein schlechter Rat.
Basil Bourque

Diese Antwort behandelt nicht die Besonderheiten dieser Frage.
Basil Bourque

1
Mit "API-Levels" meine ich wohl Android. Dies ist jedoch keine Android-spezifische Frage. Darüber hinaus wird der größte Teil der java.time- Funktionalität im ThreeTen-Backport- Projekt auf Java 6 und 7 zurückportiert . Weiter angepasst an Android im ThreeTenABP- Projekt. Sie müssen also niemals diese schrecklichen alten Datums- und Zeitklassen verwenden. Die java.time- Klassen sind radikal besser.
Basil Bourque

Vielen Dank für diesen Kommentar. Bietet diese Bibliothek Funktionen wie Datums- und Zeitunterschiede?
Syed Danish Haider

1
Ja. Durchsuchen Sie den Stapelüberlauf nach den vielen vorhandenen Fragen und Antworten zu diesem Thema. Und sehen Sie sich auch das ThreeTen-Extra- Projekt an (nicht auf frühes Android zurückportiert ).
Basil Bourque

0

Einfachste Wege:

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

Die erste sollte vermieden werden, da die von java.sql.DateIhnen verwendete Klasse schlecht gestaltet und längst veraltet ist. Ich empfehle die Verwendung LocalDatewie in der zweiten Zeile. Meine Gewohnheit ist LocalDate.of(2000, Month.JANUARY, 1), ich finde es etwas klarer zu lesen.
Ole VV

und das, weil die Antwort die LocalDate-Deklaration enthält, nicht nur das Datumsobjekt (nicht veraltet und manchmal verwendet) ...
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));
    }
}

Der SimpleDateFormat-Formatierer kann verwendet werden, um das Datum gemäß uns zu formatieren. und dann Parsen innerhalb des Datumsobjekts. Das obige Programm zeigt, wie man Wochentage erhält, indem man ein beliebiges Datum angibt.
Ankush

-5

Ich denke dein Date kommt von PHP und ist in HTML (Dom) geschrieben oder? Ich habe eine PHP-Funktion, um alle Daten und Zeitstempel vorzubereiten. Dies gibt eine Formation zurück, die benötigt wird.

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

Dieses Format kann auf js verwendet werden, um ein neues Datum zu erstellen ...

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

Was ich sagen werde ist, machen Sie Ihre eigene Funktion zu wickeln, die Ihr Leben leichter macht. Sie können uns meine Funktion als Beispiel geben, aber in meinem CMS enthalten ist, können Sie nicht 1 zu 1 kopieren und einfügen :)

    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
Warum beantworten Sie eine> 2 Jahre alte Java- Frage mit einer Antwort in PHP?
Alan Hay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.