Como criar Date Object com valores em java

96

Preciso de um objeto de data para a data de 11/02/2014. Não posso criar diretamente assim,

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

Então estou fazendo o seguinte,

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

Existe alguma maneira fácil de criar objeto de data em java?

Banukobhan Nagendram
fonte
7
O que não é fácil em sua abordagem?
giorashc
3
"Existe alguma maneira fácil". O que te faz pensar que não é tão fácil quanto pode ser? Horários e datas são muito mais complicados do que você imagina. Existem vários calendários e vários fusos horários.
Raedwald
5
Uma linha como Date myDate = new GregorianCalendar(2014, 2, 11).getTime();,?
Elliott Frisch
2
Cuidado ao usar um zero à esquerda em um literal inteiro, conforme visto nesta pergunta 02,. Em Java, isso significa um número octal (base 8) em vez de um número decimal (base 10).
Basil Bourque
2
Para sua informação, as classes de data e hora terrivelmente problemáticas como java.util.Date, java.util.Calendare java.text.SimpleDateFormatagora são legadas , suplantadas pelas classes java.time construídas no Java 8 e posterior. Veja o Tutorial da Oracle .
Basil Bourque de

Respostas:

111

Pegadinha: passar 2 como mês pode dar um resultado inesperado: na API do calendário, o mês é baseado em zero. 2 na verdade significa março.

Não sei o que é uma maneira "fácil" que você está procurando, pois sinto que usar o Calendário já é fácil o suficiente.

Lembre-se de usar constantes corretas para o mês:

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

Outra maneira é usar DateFormat, que geralmente tenho um utilitário como este:

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

para que eu possa simplesmente escrever

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

Outra alternativa que prefiro: não use mais o Java Date / Calendar. Mude para JODA Time ou Java Time (também conhecido como JSR310, disponível em JDK 8+). Você pode usar LocalDatepara representar uma data, que pode ser facilmente criada por

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
fonte
1
.toTime()não existe. Deveria ser .getTime()(ver Java Docs )
0xJoKe
Desculpe um erro de digitação. Embora eu ache que OP já sabe o método correto para chamar: P
Adrian Shum
Tenho certeza que você está certo. Mas para aqueles (como eu) que têm que pesquisar sempre que é necessário, é irritante. Obrigado por corrigir :)
0xJoKe
1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) deve serreturn new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks
Boa pegada. Não sei porque cometi tal erro. Consertando
Adrian Shum de
36

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Se você insiste em usar a terrível java.util.Dateclasse velha , converta das classes java.time modernas .

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.   

Detalhes

Se você quiser "fácil", deve usar o novo pacote java.time no Java 8 em vez das classes notoriamente problemáticas java.util.Date & .Calendar empacotadas com Java.

java.time

A estrutura java.time construída no Java 8 e posterior suplanta as antigas classes java.util.Date/.Calendar problemáticas.

Somente data

insira a descrição da imagem aqui

Uma LocalDateclasse é oferecida por java.time para representar um valor apenas de data sem qualquer hora do dia ou fuso horário. Você precisa de um fuso horário para determinar uma data, já que um novo dia amanhece mais cedo em Paris do que em Montreal, por exemplo. A ZoneIdaula é para fusos horários.

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

Despejar para o console:

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

hoje: 26/11/2015 na zona: Ásia / Cingapura

Ou use um método de fábrica para especificar o ano, mês, dia.

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

localData: 11/02/2014

Ou passe um número de mês de 1 a 12 em vez de um DayOfWeekobjeto enum.

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

Fuso horário

insira a descrição da imagem aqui

A LocalDatenão tem significado real até que você o ajuste em um fuso horário. Em java.time, aplicamos um fuso horário para gerar um ZonedDateTimeobjeto. Isso também significa uma hora do dia, mas a que horas? Normalmente faz sentido ir com o primeiro momento do dia. Você pode pensar que significa a hora 00:00:00.000, mas nem sempre é verdade por causa do horário de verão (DST) e talvez outras anomalias. Em vez de presumir essa hora, pedimos a java.time para determinar o primeiro momento do dia chamando atStartOfDay.

Especifique um nome próprio fuso horário no formato continent/region, como America/Montreal, Africa/Casablanca, ou Pacific/Auckland. Nunca utilize o 3-4 letras, como ESTou ISTcomo eles são não zonas verdadeiros tempo, não padronizados, e nem mesmo única (!).

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

zdt: 2014-02-11T00: 00 + 08: 00 [Ásia / Cingapura]

UTC

insira a descrição da imagem aqui

Para trabalho de back-end (lógica de negócios, banco de dados, armazenamento e troca de dados), geralmente usamos o fuso horário UTC . Em java.time, a Instantclasse representa um momento na linha do tempo em UTC. Um objeto Instant pode ser extraído de um ZonedDateTime chamando toInstant.

Instant instant = zdt.toInstant();

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

Converter

Você deve evitar usar java.util.Dateclasses inteiramente. Mas se você deve interoperar com o código antigo ainda não atualizado para java.time , você pode converter e para trás. Procure novos métodos de conversão adicionados às classes antigas.

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

…e…

Instant instant = d.toInstant() ;

Tabela de todos os tipos de data e hora em Java, tanto modernos quanto legados


Sobre java.time

A estrutura java.time é construída em Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e SimpleDateFormat.

Para saber mais, consulte o Tutorial Oracle . E pesquise no Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .

Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de cordas, não há necessidade de java.sql.*classes. Hibernate 5 e JPA 2.2 suportam java.time .

Onde obter as classes java.time?


ATUALIZAÇÃO: A biblioteca Joda-Time agora está em modo de manutenção e recomenda a migração para as classes java.time . Estou deixando esta seção para história.

Joda-Time

Por um lado, Joda-Time usa uma numeração sensata, mas fevereiro 2não 1. Outra coisa, um Joda-Time DateTime realmente conhece seu fuso horário atribuído, ao contrário de java.util.Date que parece ter fuso horário, mas não tem.

E não se esqueça do fuso horário. Caso contrário, você obterá o padrão do 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 );

Despejar para console ...

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

Quando executado ...

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

Conversão

Se você precisar converter para java.util.Date para usar com outras classes…

java.util.Date date = dateTimeSingapore.toDate();
Basil Bourque
fonte
4
Apenas um comentário. A prática de prefixar zeros em campos como new DateTime( 2014, 02, 11, 0, 0, timeZone );provavelmente não é preferível. Embora funcione neste caso, mas não será compilado para agosto e setembro se você estiver passando 08e 09como prefixar um int literal com 0 significa apresentação octal. Ele até lhe dará valores inesperados de anos anteriores 1000, por exemplo, new DateTime( 0100, 02, 01, 0, 0, timeZone );que alguém pode esperar que seja 100 AD, mas na verdade é 64 AD
Adrian Shum
@AdrianShum Caramba! Eu nunca soube que um pequeno erro de digitação inocente como um zero à esquerda em um literal inteiro pudesse ter um efeito colateral tão desagradável. Obrigado.
Basil Bourque
2
Caro Down-Voter, deixe uma crítica junto com seu voto.
Basil Bourque
"Se você insiste em usar a velha e terrível classe java.util.Date". Muitos provedores não oferecem servidores tomcat que rodam em Java além do JDK7, então, enquanto eu adoraria usar as coisas mais recentes, alguns estão presos na merda antiga por causa de outros ...
KimvdLinde
@KimvdLinde Releia minha resposta com mais atenção. Olhe as balas. Encontre as palavras “Java SE 6 e Java SE 7”.
Basil Bourque de
15

Acho que a melhor forma seria usando um SimpleDateFormatobjeto.

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2014-02-11";
Date dateObject = sdf.parse(dateString); // Handle the ParseException here
edubriguenti
fonte
Y .. E certifique-se de nunca usar YYYY - use yyyy - especialmente se fizer isso ao contrário com o formato em vez de analisar. Você obtém alguns resultados estranhos !!! Veja aqui: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK
12

Do Java8:

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

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

Tente isto

 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
fonte
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
fonte
As classes terríveis Calendare terríveis SimpleDateFormatforam suplantadas anos atrás pelas classes java.time . Sugerir seu uso em 2018 é um conselho ruim.
Basil Bourque de
Esta resposta não aborda os detalhes desta questão.
Basil Bourque de
1
Por “níveis de API”, suponho que você quer dizer Android. Mas esta não é uma questão específica do Android. Além disso, a maior parte da funcionalidade java.time é portada para Java 6 e 7 no projeto ThreeTen-Backport . Adaptado para Android no projeto ThreeTenABP . Portanto, não há necessidade de usar aquelas classes de data e hora legadas horríveis. As classes java.time são radicalmente melhores.
Basil Bourque de
Obrigado por este comentário. Esta biblioteca fornece funções como diferença de data e hora.
Syed Danish Haider
1
Sim. Pesquise o Stack Overflow para ver as muitas perguntas e respostas existentes sobre este tópico. E veja o projeto ThreeTen-Extra também (não adaptado para o Android anterior).
Basil Bourque de
0

Maneiras mais simples:

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
fonte
Deve-se evitar o primeiro, pois a java.sql.Dateclasse que você está usando é mal projetada e está muito desatualizada. Eu recomendo usar LocalDatecomo na segunda linha. Meu hábito é LocalDate.of(2000, Month.JANUARY, 1)que acho um pouco mais claro de ler.
Ole VV
e isso porque a resposta contém a declaração LocalDate, não apenas perguntou o objeto Date (não obsoleto e usado às vezes) ...
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
fonte
O formatador SimpleDateFormat pode ser usado para formatar a data conforme nós. e, em seguida, analisar dentro do objeto Date. O programa acima mostra como obter dias da semana informando qualquer data.
Ankush
-5

Acho que sua data vem do php e foi escrita para html (dom) ou? Eu tenho uma função php para preparar todas as datas e carimbos de data / hora. Isso retorna uma formação que é necessária.

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

este formato pode ser usado em js para criar uma nova data ...

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

O que vou dizer é, faça sua própria função para embrulhar, que torna sua vida mais fácil. Você pode usar minha função como amostra, mas está incluído em meu cms, você não pode copiar e colar 1 para 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
fonte
2
Por que você está respondendo a uma pergunta sobre Java com mais de 2 anos de idade com uma resposta em PHP?
Alan Hay