简体   繁体   中英

What is the purpose of this code? Is it just duplicating a Date?

I came across an ancient piece of code by someone who doesn't work in the company anymore.

I'm wondering what the purpose is of this calendar magic:

if (value instanceof Date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime((Date) value);
    return new Date(calendar.get(Calendar.YEAR) - 1900, calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
}

It seems to me this would return a new Date object with the same values as the original value . Is there some Calendar initialization going on that I'm missing? If the purpose is to return a new object with the same value, I would assume value.clone() does the job:

(Date) originalDate.clone()
// or
new Date(originalDate.getTime())

Version control shows the code never changed. Are there possible side effects of pulling the date through a Calendar first?

It is nothing more than an outdated way to remove hours, minutes and seconds from your initial date.

As you can see in this simple example:

Date value = new Date();
System.out.printf("Before %s%n", value);
Calendar calendar = Calendar.getInstance();
calendar.setTime(value);
System.out.printf(
    "After %s%n", 
    new Date(
        calendar.get(Calendar.YEAR) - 1900, 
        calendar.get(Calendar.MONTH), 
        calendar.get(Calendar.DAY_OF_MONTH)
    )
);

Output:

Before Thu Oct 06 11:19:26 GMT 2016
After Thu Oct 06 00:00:00 GMT 2016

The Answer by Filotto is correct, and should be accepted.

That code is trying to clear the time-of-day to 00:00:00 . But it is an abuse of the classes, ignores crucial issue of time zone, and uses the notoriously troublesome old date-time classes. Those old classes are now legacy, supplanted by the java.time classes.

The programmer probably wanted either:

  • Date-only value
  • First moment of the day

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec .

ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );

today.toString(): 2016-01-23

ZonedDateTime

For a date-time value start by getting the current date as a LocalDate object as seen above. Then call atStartOfDay to get the first moment of the day. Do not assume that first moment is the time 00:00:00 . Anomalies such as Daylight Saving Time (DST) means the first moment may be something like 01:00:00 . So let java.time determine that time-of-day.

ZonedDateTime todayStart = today.atStartOfDay( z );

today.toString(): 2016-01-23T00:00:00-05:00[America/Montreal]

Tip: Never try to determine the last moment of the day. Always use the first moment of the following day. Search Stack Overflow for "Half-Open" for more info.

Instant

Much of your work should be done in UTC . To move your ZonedDateTime into UTC, extract an Instant . The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = zdtStart.toInstant();

Conversion

You should avoid the legacy date-time classes. But if you must interoperate with some old code not yet updated to the java.time types, you can convert to/from java.time. Look for new methods added to the old classes.

java.util.GregorianCalendar gc = GregorianCalendar.from( zdtStart );
java.util.Date d = Date.from( instant );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date , .Calendar , & java.text.SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to java.time.

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations.

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use… ).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM