开发者

Joda Time subtracting 24 hours from an instance of MutableDateTime, I would like to know why

I do not understand why MutableDateTime.setDate() is setting the time to "yesterday" 开发者_运维技巧(see the log timestamp hours - it is 20:28). Is this timezone related? Do I need to set something on the formatter?

I would expect that after calling setDate with "10/27/2010", the date would be the same as the parsed date 00:00 EDT 10/27/10, instead of 20:28 EDT 10/26/10. This is 24 hours ago from "now".

What am I missing here, or how should I edit the code to get the desired result? I am new to Joda Time, and would like to solve this mystery.

DateTimeFormatter dateFormatterJ = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTimeFormatter timestampFormatJ = DateTimeFormat.forPattern("HH:mm zzz MM/dd/yy");

MutableDateTime startDate = new MutableDateTime();

log.info("parsed date " + 
    timestampFormatJ.print(dateFormatterJ.parseMutableDateTime(startDateString)));

startDate.setDate((dateFormatterJ.parseMutableDateTime(startDateString)));

log.info("startDate: " + timestampFormatJ.print(startDate));

In this case, startDateString is simply "10/27/2010".

here is the log output:

10-27 20:28:55 INFO parsed date: 00:00 EDT 10/27/10
10-27 20:28:55 INFO startDate: 20:28 EDT 10/26/10

Thanks


The simple answer would be, because the javadoc says so.

public void setDate(ReadableInstant instant)

Set the date from another instant. The time part of this object will be unaffected.

Parameters: instant - an instant to copy the date from, time part ignored

Throws: IllegalArgumentException - if the object is invalidobject is invalid

When Joda says 'Date' it means the human meaning of the word Date. "The year-month-day portion of this value", not the logical equivalent of a java.util.Date. (the whole point of joda being to introduce some natural, sensible, semantics to handling date and time.)

EDIT: To answer your 'how to fix' question, simply do:

MutableDateTime startDate = new MutableDateTime(dateFormatterJ.parseMutableDateTime(startDateString));

Or else manually zero out the time portions of course.

EDIT 2: Hmm, I apparently did not read carefully enough, this is only half of the answer. Will check.

EDIT 3: well this bugged me so much that I took a minute to look for it.

public void setDate(final ReadableInstant instant) {
    long instantMillis = DateTimeUtils.getInstantMillis(instant);
    Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
    DateTimeZone zone = instantChrono.getZone();
    if (zone != null) {
        instantMillis = zone.getMillisKeepLocal(**DateTimeZone.UTC**, instantMillis);
    }
    setDate(instantMillis);
}

For some reason, it's rolling your absolute time forward into UTC before setting the date. So you give it 10/27/2010 00:00 EDT and it sets the absolute magnitude of time to the number of milliseconds that represent 10/27/2010 00:00 UTC, which of course is only 6 or 7 PM the day before. Then it finds the EDT date value of that to be 10/26.

Couldn't say if that's somehow intended or if it's a bug that's been there for 2 years or what.)


When parsing a string that does not contain a GMT offset or time-zone ID, you must do one of three things:

  • do nothing, and accept that the string is parsed in the default time zone
  • specify the time zone to parse in using withZone() on the formatter
  • use parseLocalDate() instead of parseMutableDateTime()

The last is the preferred solution, as it correctly parses the data that was actually input, which was a date without time, offset or zone.

Using parseLocalDate() in the test code correctly parses the date.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜