Quiero obtener Año, Mes, Día, etc. de Java Date para compararlo con la fecha del calendario gregoriano en Java. es posible?

231

Tengo un objeto Date en Java almacenado como tipo de fecha de Java.

También tengo una fecha de creación del calendario gregoriano. La fecha del calendario gregoriano no tiene parámetros y, por lo tanto, es una instancia de la fecha (¿y la hora?) De hoy.

Con la fecha de Java, quiero poder obtener el año, mes, día, hora, minuto y segundos del tipo de fecha de Java y comparar la fecha del calendario gregoriano.

Vi que en este momento la fecha de Java se almacena como una larga y los únicos métodos disponibles parecen simplemente escribir la larga como una cadena de fecha formateada. ¿Hay alguna forma de acceder a Año, mes, día, etc.?

Vi que los getYear(), getMonth()métodos, etc., para Datehan sido desaprobados clase. Me preguntaba cuál es la mejor práctica para usar la instancia de Java Date que tengo con la GregorianCalendarfecha.

Mi objetivo final es hacer un cálculo de fecha para poder verificar que la fecha de Java esté dentro de tantas horas, minutos, etc. de la fecha y hora de hoy.

Todavía soy un novato en Java y estoy un poco desconcertado por esto.

daveb
fuente
1
Hey, lo que sea que uses, no lo uses Date.getYear(). Sufre de problemas (que no sé). Date.getYear()Una vez analicé mi fecha el 30/06/2017 y devolvió mi año como 117. Vea dónde aterrizó, hace dos mil años. Pero cuando imprimo simplemente el objeto de fecha, la salida estaba bien, pero no Date.getYear();.
Seenivasan
FYI: Está utilizando clases problemáticas de fecha y hora antiguas que ahora son heredadas, suplantadas por las clases modernas de java.time.
Basil Bourque

Respuestas:

545

Use algo como:

Date date; // your date
// Choose time zone in which you want to interpret your Date
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
// etc.

Cuidado, los meses comienzan en 0, no en 1.

Editar : desde Java 8 es mejor usar java.time.LocalDate en lugar de java.util.Calendar . Vea esta respuesta para saber cómo hacerlo.

Florent Guillaume
fuente
44
Puede usar cal.add(Calendar.DAY_OF_MONTH, -48)para hacer aritmética diurna en objetos de calendario. Y puede comparar dos objetos de calendario usando cal.compareTo(anotherCal).
Florent Guillaume
1
¡Brillante, salud Florent! ¿Significa lo anterior que el Calendario devolverá el año y el día actualizados, segundos, minutos y segundos cuando se usen los métodos de obtención del calendario? Dave
daveb
11
Tenga en cuenta que el mes comienza con 0 y no con 1 (es decir, enero = 0). docs.oracle.com/javase/6/docs/api/java/util/Calendar.html#MONTH
Steve Kuo
10
¿Por qué JAVA es tan inconveniente?
Kimchi Man
3
Porque la fecha y el calendario son viejos y están mal diseñados. Java 8 tiene objetos de datos / tiempo mucho mejores, consulte oracle.com/technetwork/articles/java/…
Florent Guillaume
88

Con Java 8 y versiones posteriores, puede convertir el objeto Date en un objeto LocalDate y luego obtener fácilmente el año, el mes y el día.

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int year  = localDate.getYear();
int month = localDate.getMonthValue();
int day   = localDate.getDayOfMonth();

Tenga en cuenta que getMonthValue()devuelve un valor int de 1 a 12.

Ortomala Lokni
fuente
10
Ahora es 2016, creo que usar LocalDateJava 8 es la mejor solución que le ahorra tiempo, usar otra solución Calendary Dateestá lleno de problemas.
AnnieFromTaiwan
2
Gran respuesta: definitivamente es mejor usar java.time y evitar las viejas clases problemáticas de fecha y hora. Además, observe cómo esta respuesta aborda sabiamente el problema de la zona horaria. Para cualquier momento, la fecha varía en todo el mundo por zona horaria.
Basil Bourque
1
Desafortunadamente API nivel 26+ para Android.
Wiktor Kalinowski
14

Podrías hacer algo como esto, explicará cómo funciona la Dateclase.

String currentDateString = "02/27/2012 17:00:00";
SimpleDateFormat sd = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date currentDate = sd.parse(currentDateString);

String yourDateString = "02/28/2012 15:00:00";
SimpleDateFormat yourDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

Date yourDate = yourDateFormat.parse(yourDateString);

if (yourDate.after(currentDate)) {
    System.out.println("After");
} else if(yourDate.equals(currentDate)) {
    System.out.println("Same");
} else {
    System.out.println("Before");
}
javaCity
fuente
Hola JavaCity, gracias por esto. Esto es muy útil. En este momento estoy tratando de evitar el análisis de una cadena de fecha. Sin embargo, necesitaré hacer este análisis más adelante cuando haga que los usuarios de mi aplicación configuren año, día y mes. Iba a construir una cadena para analizar en SimpleDateFormat. Lo anterior es muy útil para ver esto en acción. Mi fecha Java fue creada como una fecha y hora desde su creación hace un día. Ahora estoy buscando comparar con la fecha de calendario gregoriano que se ha instanciado hoy. Sincero agradecimiento
daveb
8
Corrija el código ... en minúscula mmindica minutos, en mayúscula MMsignifica mes del año.
YoYo
12
    Date date = new Date();

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");

    System.out.println("DAY "+simpleDateFormat.format(date).toUpperCase());

    simpleDateFormat = new SimpleDateFormat("MMMM");
    System.out.println("MONTH "+simpleDateFormat.format(date).toUpperCase());

    simpleDateFormat = new SimpleDateFormat("YYYY");
    System.out.println("YEAR "+simpleDateFormat.format(date).toUpperCase());

EDITAR: La salida para date= Fri Jun 15 09:20:21 CEST 2018es:

DAY FRIDAY
MONTH JUNE
YEAR 2018
Az.MaYo
fuente
Si hubiera puesto al menos el resultado, la gente podría decidir si esto podría ser útil para ellos o no sin tener que ejecutar el código.
SantiBailors
6
private boolean isSameDay(Date date1, Date date2) {
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    boolean sameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
    boolean sameMonth = calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
    boolean sameDay = calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
    return (sameDay && sameMonth && sameYear);
}
evya
fuente
3
    Date queueDate = new SimpleDateFormat("yyyy-MM-dd").parse(inputDtStr);
    Calendar queueDateCal = Calendar.getInstance();
    queueDateCal.setTime(queueDate);
    if(queueDateCal.get(Calendar.DAY_OF_YEAR)==Calendar.getInstance().get(Calendar.DAY_OF_YEAR))
{
    "same day of the year!";
 }
rabi
fuente
1
Se espera que las respuestas sobre Stack Overflow tengan cierta discusión y explicación, no solo fragmentos de código. Y su código definitivamente podría usar alguna explicación.
Basil Bourque
1
Para su información, las antiguas clases de fecha y hora 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. Ver Tutorial de Oracle .
Basil Bourque
2
@Test
public void testDate() throws ParseException {
    long start = System.currentTimeMillis();
    long round = 100000l;
    for (int i = 0; i < round; i++) {
        StringUtil.getYearMonthDay(new Date());
    }
    long mid = System.currentTimeMillis();
    for (int i = 0; i < round; i++) {
        StringUtil.getYearMonthDay2(new Date());
    }
    long end = System.currentTimeMillis();
    System.out.println(mid - start);
    System.out.println(end - mid);
}

public static Date getYearMonthDay(Date date) throws ParseException {
    SimpleDateFormat f = new SimpleDateFormat("yyyyyMMdd");
    String dateStr = f.format(date);
    return f.parse(dateStr);
}

public static Date getYearMonthDay2(Date date) throws ParseException {
    Calendar c = Calendar.getInstance();
    c.setTime(date);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.HOUR_OF_DAY, 0);
    return c.getTime();
}
public static int compare(Date today, Date future, Date past) {
    Date today1 = StringUtil.getYearMonthDay2(today);
    Date future1 = StringUtil.getYearMonthDay2(future);
    Date past1 = StringUtil.getYearMonthDay2(past);
    return today.compare // or today.after or today.before
}

getYearMonthDay2 (la solución de calendario) es diez veces más rápido. Ahora tiene aaaa MM dd 00 00 00, y luego compare usando date.compare

Tiina
fuente
2

Puede ser más fácil

     Date date1 = new Date("31-May-2017");
OR
    java.sql.Date date1 = new java.sql.Date((new Date()).getTime());

    SimpleDateFormat formatNowDay = new SimpleDateFormat("dd");
    SimpleDateFormat formatNowMonth = new SimpleDateFormat("MM");
    SimpleDateFormat formatNowYear = new SimpleDateFormat("YYYY");

    String currentDay = formatNowDay.format(date1);
    String currentMonth = formatNowMonth.format(date1);
    String currentYear = formatNowYear.format(date1);
Abdur Rahman
fuente
-2

Montar con cuidado comenzar desde 0 no 1. Y también usar calendario como pm, así que tenga mucho cuidado cuando use horas y minutos.

Date your_date;
Calendar cal = Calendar.getInstance(); 
cal.setTime(your_date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MINUTE);

harun ugur
fuente
1
Es mejor usar el java.time moderno que suplanta estas problemáticas clases antiguas heredadas que se muestran aquí. Ver respuesta correcta
Basil Bourque
Gracias por la respuesta y sugerencia. Es muy mejor
harun ugur