Bagaimana membuat Objek Tanggal dengan nilai di java

91

Saya membutuhkan objek tanggal untuk tanggal 2014-02-11. Saya tidak bisa langsung membuatnya seperti ini,

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

Jadi saya melakukan seperti berikut,

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

Apakah ada cara mudah untuk membuat objek tanggal di java?

Banukobhan Nagendram
sumber
7
Apa yang tidak mudah dalam pendekatan Anda?
giorashc
3
"Apakah ada cara yang mudah". Apa yang membuat Anda berpikir bahwa itu tidak semudah mungkin? Waktu dan tanggal jauh lebih rumit dari yang mungkin Anda pikirkan. Ada banyak kalender dan beberapa zona waktu.
Raedwald
5
Satu baris seperti Date myDate = new GregorianCalendar(2014, 2, 11).getTime();,?
Elliott Frisch
2
Berhati-hatilah menggunakan nol di depan dalam literal integer seperti yang terlihat dalam Pertanyaan ini 02,. Di Jawa, itu berarti angka oktal (basis 8) daripada angka desimal (basis 10).
Basil Bourque
2
FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque

Jawaban:

108

Gotcha: melewati 2 sebagai bulan dapat memberi Anda hasil yang tidak terduga: di API Kalender, bulan berbasis nol. 2 sebenarnya berarti Maret.

Saya tidak tahu cara "mudah" apa yang Anda cari karena menurut saya menggunakan Kalender sudah cukup mudah.

Ingatlah untuk menggunakan konstanta yang benar untuk bulan:

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

Cara lain adalah dengan menggunakan DateFormat, yang biasanya saya gunakan seperti ini:

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

sehingga saya bisa langsung menulis

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

Alternatif lain yang saya sukai: Jangan gunakan Tanggal / Kalender Java lagi. Beralih ke Waktu JODA atau Waktu Java (alias JSR310, tersedia dalam JDK 8+). Anda dapat menggunakan LocalDateuntuk mewakili tanggal, yang dapat dibuat dengan mudah oleh

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);
Adrian Shum
sumber
1
.toTime()tidak ada. Seharusnya .getTime()(lihat Java Docs )
0xJoKe
Maaf salah ketik. Meskipun saya pikir OP sudah mengetahui metode yang tepat untuk menelepon: P
Adrian Shum
Cukup yakin Anda benar. Tetapi bagi mereka (seperti saya) yang harus mencarinya setiap kali dibutuhkan itu mengganggu. Terima kasih telah memperbaiki :)
0xJoKe
1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) harusreturn new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks
Tangkapan yang bagus. Tidak tahu mengapa saya melakukan kesalahan seperti itu. Memperbaiki itu
Adrian Shum
34

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Jika Anda bersikeras untuk menggunakan java.util.Dateclass lama yang mengerikan , ubah dari class java.time modern .

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.   

Detail

Jika Anda ingin "mudah", Anda harus menggunakan paket java.time baru di Java 8 daripada kelas java.util.Date & .Calendar yang terkenal menyusahkan yang digabungkan dengan Java.

java.time

The java.time kerangka dibangun ke Jawa 8 dan kemudian supplants kelas java.util.Date/.Calendar tua merepotkan.

Tanggal saja

masukkan deskripsi gambar di sini

Sebuah LocalDatekelas yang ditawarkan oleh java.time untuk mewakili nilai tanggal-satunya tanpa waktu-of-hari atau zona waktu. Anda memang membutuhkan zona waktu untuk menentukan tanggal, karena hari baru terbit lebih awal di Paris daripada di Montréal misalnya. The ZoneIdkelas untuk zona waktu.

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

Buang ke konsol:

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

hari ini: 2015-11-26 di zona: Asia / Singapura

Atau gunakan metode pabrik untuk menentukan tahun, bulan, hari.

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

localDate: 2014-02-11

Atau berikan nomor bulan 1-12 daripada DayOfWeekobjek enum.

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

Zona waktu

masukkan deskripsi gambar di sini

A LocalDatetidak memiliki arti yang sebenarnya sampai Anda menyesuaikannya menjadi zona waktu. Di java.time, kami menerapkan zona waktu untuk menghasilkan ZonedDateTimeobjek. Itu juga berarti waktu dalam sehari, tapi jam berapa? Biasanya masuk akal untuk pergi dengan momen pertama hari itu. Anda mungkin berpikir itu berarti waktu 00:00:00.000, tetapi tidak selalu benar karena Daylight Saving Time (DST) dan mungkin anomali lainnya. Alih-alih mengasumsikan waktu itu, kami meminta java.time untuk menentukan momen pertama hari itu dengan menelepon atStartOfDay.

Tentukan nama zona waktu yang tepat dalam format continent/region, seperti America/Montreal, Africa/Casablanca, atau Pacific/Auckland. Jangan pernah menggunakan singkatan 3-4 huruf seperti ESTatau ISTkarena itu bukan zona waktu yang sebenarnya, tidak standar, dan bahkan tidak unik (!).

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

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

UTC

masukkan deskripsi gambar di sini

Untuk pekerjaan back-end (logika bisnis, database, penyimpanan & pertukaran data) kami biasanya menggunakan zona waktu UTC . Di java.time, Instantkelas mewakili momen di timeline dalam UTC. Objek Instan dapat diekstraksi dari ZonedDateTime dengan memanggil toInstant.

Instant instant = zdt.toInstant();

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

Mengubah

Anda harus menghindari penggunaan java.util.Datekelas sepenuhnya. Tetapi jika Anda harus beroperasi dengan kode lama yang belum diperbarui untuk java.time , Anda dapat mengonversi bolak-balik. Lihat metode konversi baru yang ditambahkan ke kelas lama.

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

…dan…

Instant instant = d.toInstant() ;

Tabel semua jenis tanggal-waktu di Jawa, baik modern maupun lawas


Tentang java.time

The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date, Calendar, & SimpleDateFormat.

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasinya adalah JSR 310 .

Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .

Anda dapat bertukar objek java.time langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu string, tidak perlu java.sql.*kelas. Hibernate 5 & JPA 2.2 mendukung java.time .

Dimana mendapatkan kelas java.time?


UPDATE: Perpustakaan Joda-Time sekarang dalam mode pemeliharaan, dan menyarankan migrasi ke kelas java.time . Saya meninggalkan bagian ini untuk sejarah.

Waktu Joda

Untuk satu hal, Joda-Time menggunakan penomoran yang masuk akal sehingga Februari 2tidak 1. Hal lain, Joda-Time DateTime benar-benar mengetahui zona waktu yang ditetapkan tidak seperti java.util.Date yang tampaknya memiliki zona waktu tetapi tidak.

Dan jangan lupa zona waktunya. Jika tidak, Anda akan mendapatkan default 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 );

Buang ke konsol…

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

Saat lari…

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

Konversi

Jika Anda perlu mengonversi ke java.util.Date untuk digunakan dengan kelas lain…

java.util.Date date = dateTimeSingapore.toDate();
Basil Bourque
sumber
4
Hanya satu komentar. Praktik memberi awalan nol di bidang seperti new DateTime( 2014, 02, 11, 0, 0, timeZone );mungkin tidak disukai. Meskipun berfungsi dalam kasus ini, tetapi, itu tidak akan dikompilasi untuk Agustus dan September jika Anda lewat 08dan 09sebagai awalan int literal dengan 0 berarti presentasi oktal. Ini bahkan akan memberi Anda nilai yang tidak terduga selama bertahun-tahun sebelumnya 1000, misalnya new DateTime( 0100, 02, 01, 0, 0, timeZone );seseorang mungkin mengharapkannya menjadi 100AD tetapi sebenarnya 64AD
Adrian Shum
@AdrianShum Astaga! Saya tidak pernah tahu kesalahan kecil yang tidak bersalah seperti nol di depan pada literal integer dapat memiliki efek samping yang begitu buruk. Terima kasih.
Basil Bourque
2
Dear Down-Voter, tinggalkan kritik bersama dengan suara Anda.
Basil Bourque
"Jika Anda bersikeras menggunakan kelas java.util.Date lama yang mengerikan". Banyak penyedia tidak menawarkan server kucing jantan yang berjalan di Java di luar JDK7, jadi, sementara saya ingin menggunakan hal-hal yang lebih baru, beberapa terjebak di omong kosong karena yang lain .....
KimvdLinde
@KimvdLinde Tulis ulang Jawaban saya dengan lebih hati-hati. Lihat pelurunya. Temukan kata “Java SE 6 dan Java SE 7”.
Basil Bourque
14

Saya pikir cara terbaik adalah menggunakan SimpleDateFormatobjek.

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2014-02-11";
Date dateObject = sdf.parse(dateString); // Handle the ParseException here
edubriguenti
sumber
Y .. Dan pastikan untuk tidak pernah menggunakan YYYY - gunakan yyyy - terutama jika melakukan ini secara terbalik dengan format alih-alih parse. Anda mendapatkan beberapa hasil yang aneh !!! Lihat di sini: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK
9

Dari Java8:

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

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

Coba ini

 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();
Selva
sumber
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();
}
Syed Danish Haider
sumber
Kelas mengerikan Calendardan SimpleDateFormattelah digantikan tahun lalu oleh kelas java.time . Menyarankan penggunaannya pada tahun 2018 adalah saran yang buruk.
Basil Bourque
Jawaban ini tidak membahas secara spesifik dari Pertanyaan ini.
Basil Bourque
1
Yang saya maksud dengan "API level" adalah Android. Tapi ini bukan Pertanyaan khusus Android. Selain itu, sebagian besar fungsionalitas java.time di -back-port ke Java 6 & 7 dalam proyek ThreeTen-Backport . Diadaptasi lebih lanjut ke Android dalam proyek ThreeTenABP . Jadi, tidak perlu pernah menggunakan kelas waktu tanggal lama yang mengerikan itu. The java.time kelas secara radikal baik.
Basil Bourque
Terima kasih atas komentar ini Apakah perpustakaan ini menyediakan fungsi seperti perbedaan tanggal dan perbedaan waktu.
Syed Danish Haider
1
Iya. Telusuri Stack Overflow untuk banyak Tanya Jawab yang ada tentang topik ini. Dan lihat juga proyek ThreeTen-Extra (tidak di-back-port ke Android awal).
Basil Bourque
0

Cara paling sederhana:

Date date = Date.valueOf("2000-1-1");
LocalDate localdate = LocalDate.of(2000,1,1);
LocalDateTime localDateTime = LocalDateTime.of(2000,1,1,0,0);
Adam Silenko
sumber
Seseorang harus menghindari yang pertama karena java.sql.Datekelas yang Anda gunakan dirancang dengan buruk dan sudah lama usang. Saya sarankan menggunakan LocalDateseperti pada baris kedua. Kebiasaan saya adalah LocalDate.of(2000, Month.JANUARY, 1), saya merasa lebih jelas untuk membaca.
Ole VV
dan karena jawaban berisi deklarasi LocalDate, tidak hanya meminta objek Tanggal (tidak usang, dan kadang-kadang digunakan) ...
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));
    }
}
Ankush
sumber
SimpleDateFormat formatter dapat digunakan untuk memformat Tanggal menurut kami. dan kemudian mengurai di dalam Objek Tanggal. Program di atas menunjukkan bagaimana mendapatkan hari kerja dengan memberikan tanggal berapa saja.
Ankush
-5

Saya pikir tanggal Anda berasal dari php dan ditulis ke html (dom) atau? Saya memiliki fungsi php untuk mempersiapkan semua tanggal dan cap waktu. Ini mengembalikan formasi yang dibutuhkan.

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

format ini dapat digunakan di js untuk membuat Tanggal baru ...

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

Apa yang akan saya katakan adalah, buatlah fungsi Anda sendiri untuk membungkus, yang membuat hidup Anda lebih mudah. Anda dapat menggunakan func saya sebagai sampel tetapi termasuk dalam cms saya, Anda tidak dapat menyalin dan menempel 1 hingga 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();
}
Paykoman
sumber
2
Mengapa Anda menjawab pertanyaan Java > 2 tahun dengan jawaban dalam PHP?
Alan Hay