Reputation: 3535
I have a Date object in Java stored as Java's Date type.
I also have a Gregorian Calendar created date. The gregorian calendar date has no parameters and therefore is an instance of today's date (and time?).
With the java date, I want to be able to get the year, month, day, hour, minute, and seconds from the java date type and compare the the gregoriancalendar date.
I saw that at the moment the Java date is stored as a long and the only methods available seem to just write the long as a formatted date string. Is there a way to access Year, month, day, etc?
I saw that the getYear()
, getMonth()
, etc. methods for Date
class have been deprecated. I was wondering what's the best practice to use the Java Date instance I have with the GregorianCalendar
date.
My end goal is to do a date calculation so that I can check that the Java date is within so many hours, minutes etc of today's date and time.
I'm still a newbie to Java and am getting a bit puzzled by this.
Upvotes: 283
Views: 684561
Reputation: 340090
check that the Java date is within so many hours, minutes etc of today's date and time
Use java.time classes, never legacy classes. Convert as needed.
For a java.util.Date
object:
Duration.between(
myJavaUtilDate.toInstant() ,
Instant.now()
)
.abs()
.toNanos()
>
Duration.ofHours( 36 ).toNanos()
For a java.util.GregorianCalendar
object:
Duration.between(
myGregorianCalendar.toZonedDateTime().toInstant() ,
Instant.now()
)
.abs()
.toNanos()
>
Duration.ofHours( 36 ).toNanos()
java.util.Date
versus GregorianCalendar
Firstly, be aware of two Date
classes: java.util.Date
& java.sql.Date
. Apparently you had the first one in mind.
You said:
With the java date, I want to be able to get the year, month, day, hour, minute, and seconds from the java date type and compare the the gregoriancalendar date.
Let's be clear on what java.util.Date
& GregorianCalendar
classes each represent. They both represent a moment, a specific point on the timeline. But they have different perspectives on that moment.
java.util.Date
GregorianCalendar
Defining these terms:
Both java.util.Date
and GregorianCalendar
(and Calendar
, SimpleDateFormat
, etc.) are terribly flawed. Never use them. They have been supplanted by the modern java.time classes built into Java 8 and later.
Legacy class | Modern class |
---|---|
java.util.Date |
java.time.Instant |
java.util.GregorianCalendar |
java.time.ZonedDateTime |
When handed an object of either legacy class, immediately convert. Use the new conversion methods added to the old classes .
Instant instan = myJavaUtilDate.toInstant() ;
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;
If handed a Calendar
object, most likely that object is actually a GregorianCalendar
. Test with instanceOf
to verify, then cast.
if( myCalendar instanceOf GregorianCalendar )
{
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
}
Back to your Question:
I want to get Year, Month, Day, etc from Java Date to compare with Gregorian Calendar date in Java. Is this possible?
Keep in mind that for any given moment, the time-of-day and the date(!) vary around the globe by time zone. For any moment, it will be “tomorrow” in Tokyo Japan while simultaneously “yesterday” in Toledo Ohio US.
Hopefully you can see how tricky is your Question. You can get the date & time from your java.util.Date
but do you want the date & time as seen in UTC (at the clock a the Royal Observatory)? Or do you want to adjust that moment to get the date and time-of-day as seen from the time zone as was used in your GreporianCalendar
(now a ZonedDateTime
)? Both are valid desires, so let's cover each of them.
To extract the year, month, and day from our Instant
object, we have to take an extra step. The Instant
class is the basic-building block of java.time. For more features and flexibility, we need to convert from Instant
to java.time.OffsetDateTime
. In doing so we must specify the offset to use. Since our goal here is to view the date & time from the point of view of UTC (offset of zero), we use the constant ZoneOffset.UTC
representing an offset of zero.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Now we can get the year, month, and date.
int yearX = odt.getYear() ;
int monthX = odt.getMonthValue() ;
int dayX = odt.getDayOfMonth() ;
Or perhaps you just want to extract the entire date as a LocalDate
object.
LocalDate ldX = odt.toLocalDate() ;
Now let's get the same values from our ZonedDateTime
object.
int yearY = zdt.getYear() ;
int monthY = zdt.getMonthValue() ;
int dayY = zdt.getDayOfMonth() ;
Or extract a LocalDate
.
LocalDate ldY = zdt.toLocalDate() ;
Now let's try the other approach, adjusting our moment as seen in UTC (an Instant
or java.util.Date
) to a particular time zone.
To use the same time zone as was used in our ZonedDateTime
(originally a GregorianCalendar
), we simply interrogate to extract a ZoneId
object.
ZoneId z = zdt.getZone() ;
Then apply to our Instant
object to get another ZonedDateTime
object.
ZonedDateTime zdt2 = instant.atZone( z ) ;
Now you can extract the year, month, day from zdt2
using the same way we did from zdt
in code above.
You said:
My end goal is to do a date calculation so that I can check that the Java date is within so many hours, minutes etc of today's date and time.
Well, you should have said so up front! All the work we did extracting year, month, & day from our objects is irrelevant. The java.time classes can easily calculate the span of time between two moments.
Let's capture the current moment, as seen in UTC.
Instant now = Instant.now() ;
To represent a span of time on the scale of hours-minutes-seconds as you requested, use Duration
class.
First, we do a comparison using the Instant
object we converted from a java.util.Date
.
Duration duration = Duration.between( instant , now ) ;
You can ask isNegative
or isPositive
to see if the direction between those two moments is going into the past or towards the future.
Second, we do a comparison with the ZonedDateTime
object we converted from a GregorianCalendar
object. To do this, we can adjust from our time zone to UTC by extracting an Instant
from ZonedDateTime
.
Duration duration = Duration.between( zdt.toInstant() , now ) ;
You asked "is within so many hours, minutes etc". So define a Duration
to specify your limit.
Duration limit = Duration.ofHours( 36 ) ;
Test.
if ( duration.toNanos() > limit.toNanos() ) { … beyond limit … }
You might want to add a call to Duration#abs
to handle negative and positive durations in the same manner.
if ( duration.abs().toNanos() > limit.abs().toNanos() ) { … beyond limit … }
Upvotes: 2
Reputation: 62683
With Java 8 and later, you can convert the Date object to a LocalDate object and then easily get the year, month and day.
import java.util.Date;
import java.time.LocalDate
import java.time.ZoneId
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int day = localDate.getDayOfMonth();
Note that getMonthValue()
returns an int value from 1 to 12.
Upvotes: 129
Reputation: 8368
Use something like:
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.
Beware, months start at 0, not 1.
Edit: Since Java 8 it's better to use java.time.LocalDate rather than java.util.Calendar. See this answer for how to do it.
Upvotes: 619
Reputation: 4318
You could do something like this, it will explain how the Date
class works.
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");
}
Upvotes: 14
Reputation: 101
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!";
}
Upvotes: 3
Reputation: 1106
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());
EDIT: The output for date
= Fri Jun 15 09:20:21 CEST 2018
is:
DAY FRIDAY
MONTH JUNE
YEAR 2018
Upvotes: 14
Reputation: 1666
It might be easier
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);
Upvotes: 4
Reputation: 4797
@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(the calendar solution) is ten times faster. Now you have yyyy MM dd 00 00 00, and then compare using date.compare
Upvotes: 2
Reputation: 3647
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);
}
Upvotes: 9