Cómo crear un objeto de fecha con valores en Java

91

Necesito un objeto de fecha para la fecha 2014-02-11. No puedo crearlo directamente así,

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

Así que estoy haciendo lo siguiente

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

¿Hay alguna manera fácil de crear un objeto de fecha en java?

Banukobhan Nagendram
fuente
7
¿Qué no es fácil en tu enfoque?
giorashc
3
"¿Hay alguna manera fácil?". ¿Qué te hace pensar que no es tan fácil como puede ser? Los horarios y las fechas son mucho más complicados de lo que piensas. Hay varios calendarios y varias zonas horarias.
Raedwald
5
¿Una línea como Date myDate = new GregorianCalendar(2014, 2, 11).getTime();?
Elliott Frisch
2
Tenga cuidado de usar un cero en un literal entero como se ve en esta pregunta, 02. En Java, eso significa un número octal (base 8) en lugar de un número decimal (base 10).
Basil Bourque
2
Para su información, las clases de fecha y hora antiguas terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Consulte el tutorial de Oracle .
Basil Bourque

Respuestas:

108

Entendido: pasar 2 como mes puede dar un resultado inesperado: en Calendar API, el mes se basa en cero. 2 en realidad significa marzo.

No sé cuál es la forma "fácil" que está buscando, ya que creo que usar Calendar ya es bastante fácil.

Recuerde usar las constantes correctas para el mes:

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

Otra forma es hacer uso de DateFormat, que generalmente tengo una utilidad como esta:

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

para que pueda simplemente escribir

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

Otra alternativa más que prefiero: ya no use Java Date / Calendar. Cambie a JODA Time o Java Time (también conocido como JSR310, disponible en JDK 8+). Puede utilizar LocalDatepara representar una fecha, que puede crear fácilmente mediante

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
fuente
1
.toTime()no existe. Debería ser .getTime()(ver Java Docs )
0xJoKe
Lo siento un error tipográfico. Aunque creo que OP ya conoce el método correcto para llamar: P
Adrian Shum
Estoy bastante seguro de que tienes razón. Pero para aquellos (como yo) que tienen que buscarlo cada vez que lo necesitan es molesto. Gracias por arreglar :)
0xJoKe
1
return new SimpleDateFormat("yyyy-mm-dd").parse(date) debería serreturn new SimpleDateFormat("yyyy-MM-dd").parse(date)
aks
Buena atrapada. No sé por qué cometí tal error. Arreglando
Adrian Shum
34

tl; dr

LocalDate.of( 2014 , 2 , 11 )

Si insiste en usar la terrible java.util.Dateclase antigua , convierta de las clases modernas 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.   

Detalles

Si quiere "fácil", debería utilizar el nuevo paquete java.time en Java 8 en lugar de las notoriamente problemáticas clases java.util.Date y .Calendar incluidas con Java.

java.time

El java.time marco integrado en Java 8 y posteriores suplanta las problemáticas clases antiguas java.util.Date/.Calendar.

Solo fecha

ingrese la descripción de la imagen aquí

LocalDateJava.time ofrece una clase para representar un valor de solo fecha sin ninguna hora del día ni zona horaria. Necesita una zona horaria para determinar una fecha, ya que un nuevo día amanece antes en París que en Montreal, por ejemplo. La ZoneIdclase es para zonas horarias.

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

Volcado a la consola:

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

hoy: 2015-11-26 en zona: Asia / Singapur

O utilice un método de fábrica para especificar el año, mes, día.

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

localDate: 2014-02-11

O pase un número de mes del 1 al 12 en lugar de un DayOfWeekobjeto de enumeración.

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

Zona horaria

ingrese la descripción de la imagen aquí

A LocalDateno tiene un significado real hasta que lo ajusta a una zona horaria. En java.time, aplicamos una zona horaria para generar un ZonedDateTimeobjeto. Eso también significa una hora del día, pero ¿a qué hora? Por lo general, tiene sentido ir con el primer momento del día. Puede pensar que eso significa la hora 00:00:00.000, pero no siempre es cierto debido al horario de verano (DST) y quizás a otras anomalías. En lugar de asumir ese momento, le pedimos a java.time que determine el primer momento del día llamando atStartOfDay.

Especificar un nombre de zona horaria correcta en el formato de continent/region, por ejemplo America/Montreal, Africa/Casablancao Pacific/Auckland. Nunca use la abreviatura de 3-4 letras como ESTo ISTya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

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

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

UTC

ingrese la descripción de la imagen aquí

Para el trabajo de back-end (lógica comercial, base de datos, almacenamiento e intercambio de datos) usualmente usamos la zona horaria UTC . En java.time, la Instantclase representa un momento en la línea de tiempo en UTC. Un objeto Instant se puede extraer de un ZonedDateTime llamando toInstant.

Instant instant = zdt.toInstant();

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

Convertir

Debes evitar usar java.util.Dateclass por completo. Pero si debe interoperar con un código antiguo que aún no se ha actualizado para java.time , puede convertir de un lado a otro. Busque nuevos métodos de conversión agregados a las clases antiguas.

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

…y…

Instant instant = d.toInstant() ;

Tabla de todos los tipos de fecha y hora en Java, tanto modernos como heredados


Acerca de java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, y SimpleDateFormat.

Para obtener más información, consulte el tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a java.time clases .

Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No se necesitan cuerdas, no se necesitan java.sql.*clases. Hibernate 5 y JPA 2.2 admiten java.time .

¿Dónde obtener las clases java.time?


ACTUALIZACIÓN: La biblioteca Joda-Time ahora está en modo de mantenimiento y aconseja la migración a las clases java.time . Dejo esta sección para la historia.

Joda-Time

Por un lado, Joda-Time usa una numeración sensata, por lo que febrero 2no lo es 1. Otra cosa, Joda-Time DateTime realmente conoce su zona horaria asignada a diferencia de un java.util.Date que parece tener una zona horaria pero no la tiene.

Y no olvide la zona horaria. De lo contrario, obtendrá el valor predeterminado de 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 );

Volcar a la consola…

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

Cuando se ejecuta ...

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

Conversión

Si necesita convertir a java.util.Date para usar con otras clases ...

java.util.Date date = dateTimeSingapore.toDate();
Albahaca Bourque
fuente
4
Solo un comentario. new DateTime( 2014, 02, 11, 0, 0, timeZone );Probablemente no sea preferible la práctica de prefijar ceros en los campos como . Aunque funciona en este caso, no se compilará para agosto y septiembre si está pasando 08y 09como prefijo de un literal int con 0 significa presentación octal. Incluso le dará valores inesperados durante años antes 1000, por ejemplo, new DateTime( 0100, 02, 01, 0, 0, timeZone );que uno puede esperar que sea 100AD pero en realidad es 64AD
Adrian Shum
@AdrianShum ¡Ay! Nunca supe que un pequeño error tipográfico inocente como un cero inicial en un literal entero pudiera tener un efecto secundario tan desagradable. Gracias.
Basil Bourque
2
Estimado votante en contra, deje una crítica junto con su voto.
Basil Bourque
"Si insistes en usar la terrible clase java.util.Date". Muchos proveedores no ofrecen servidores tomcat que se ejecuten en Java más allá de JDK7, por lo que, aunque me encantaría usar las cosas más nuevas, algunos están atrapados en la vieja mierda debido a otros .....
KimvdLinde
@KimvdLinde Vuelve a leer mi respuesta con más atención. Mira las balas. Busque las palabras "Java SE 6 y Java SE 7".
Basil Bourque
14

Creo que la mejor forma sería utilizar un SimpleDateFormatobjeto.

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "2014-02-11";
Date dateObject = sdf.parse(dateString); // Handle the ParseException here
edubriguenti
fuente
Y .. Y asegúrese de no usar nunca YYYY - use yyyy - especialmente si hace esto al revés con formato en lugar de analizar. ¡¡¡Obtienes resultados extraños !!! Ver aquí: code.sololearn.com/c0EYUAOc92uQ/#java
JGFMK
9

Desde Java8:

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

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

Prueba esto

 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
fuente
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
fuente
Las clases terrible Calendary SimpleDateFormatfueron suplantadas hace años por las clases java.time . Sugerir su uso en 2018 es un mal consejo.
Basil Bourque
Esta respuesta no aborda los detalles de esta pregunta.
Basil Bourque
1
Por "niveles de API" supongo que te refieres a Android. Pero esta no es una pregunta específica de Android. Además, la mayor parte de la funcionalidad de java.time está adaptada a Java 6 y 7 en el proyecto ThreeTen-Backport . Más adaptado a Android en el proyecto ThreeTenABP . Entonces, no hay necesidad de usar esas horribles clases de fecha y hora heredadas. Las clases java.time son radicalmente mejores.
Basil Bourque
Gracias por este comentario ¿Esta biblioteca proporciona funciones como diferencia de fecha y diferencia de tiempo?
Syed Danish Haider
1
Si. Busque Stack Overflow para las muchas preguntas y respuestas existentes sobre este tema. Y vea también el proyecto ThreeTen-Extra (no actualizado a los primeros Android).
Basil Bourque
0

Maneras más 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
fuente
Uno debe evitar el primero, ya que la java.sql.Dateclase que está utilizando está mal diseñada y obsoleta. Recomiendo usar LocalDatecomo en la segunda línea. Mi hábito es LocalDate.of(2000, Month.JANUARY, 1)que lo encuentro un poco más claro de leer.
Ole VV
y eso debido a que la respuesta contiene la declaración LocalDate, no solo se preguntó el objeto Date (no está en desuso y se usa a veces) ...
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
fuente
El formateador SimpleDateFormat se puede utilizar para formatear la fecha de acuerdo con nosotros. y luego analizar dentro del objeto de fecha. El programa anterior muestra cómo obtener los días de la semana dando cualquier fecha.
Ankush
-5

Creo que su fecha proviene de php y está escrita en html (dom) o? Tengo una función php para preparar todas las fechas y marcas de tiempo. Esto devuelve una formación que se necesita.

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

este formato se puede usar en js para crear una nueva fecha ...

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

Lo que voy a decir es, haz tu propia función para envolver, que te haga la vida más fácil. Puedes usar mi func como muestra pero está incluido en mis cms no puedes copiar y pegar 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();
}
Paykoman
fuente
2
¿Por qué responde una pregunta de Java de más de 2 años con una respuesta en PHP?
Alan Hay