如何根据时区输入以及时区和夏令时帐户更改日期?

时间:2015-06-03 10:44:09

标签: java date jodatime apache-commons-lang

我需要根据用户提供的两个字符串创建一个新的Java Date:日期(例如“1.1.2015”)和一天中的某个时间(例如“23:00”)。首先,用户输入日期,该日期被发送到服务器并被解析为Date(在用户的时区中将时间设置为午夜)。在此之后,用户输入发送到服务器的时间,并且需要创建新的Date,将第一个Date实例中的日期与新时间的日期相结合用户输入。

示例:假设服务器的时区是UTC,用户的时区是UTC-2。用户在日期字段中输入“1.1.2015”,该字段在服务器中被解释为2:00 1.1.2015 UTC(1月1日UTC时间凌晨2:00,即用户时区的午夜)。然后用户在时间字段(24小时制)中输入“23:00”。这需要在服务器中解释为1:00 2.1.2015 UTC(1月2日凌晨1:00)。

我们使用Apache Commons FastDateFormat将字符串转换为Dates,反之亦然,并使用Joda Time进行日期操作。结果需要是一个普通的旧Java日期。我试图将现有的Date实例与用户的时间输入结合起来,如下所示:

Date datePart= ...; // The date parsed from the first user input
FastDateFormat timeFormat = ...;
DateTimeZone userTimeZone = DateTimeZone.forTimeZone(timeFormat.getTimeZone());
String userTimeInput = ...; // The time of day from the user

MutableDateTime dateTime = new MutableDateTime(datePart, DateTimeZone.UTC);
Date newTime = timeFormat.parse(userTimeInput);
dateTime.setTime(new DateTime(newTime, DateTimeZone.UTC));

// Determine if the date part needs to be changed due to time zone adjustment
long timeZoneOffset = userTimeZone.getOffset(dateTime);
long newMillisOfDay = dateTime.getMillisOfDay();
if (newMillisOfDay + timeZoneOffset > 24 * 60 * 60 * 1000) {
    dateTime.addDays(-1);
} else if (newMillisOfDay + timeZoneOffset < 0) {
    dateTime.addDays(1);
}

Date newServerDate = dateTime.toDate();

像这样更改现有Date的时间有点问题。以上不起作用;如果用户多次更改时间,则每次都可能进行+/- 1天调整。此外,上述代码不考虑DST。如果datePart在DST中,则我们的示例用户输入的时间应视为UTC-1。使用FastDateFormat并仅解析时间时,日期将设置为纪元,这意味着用户输入的时间将始终视为UTC-2。这将导致结果偏移一小时。

如何根据给定的时间调整服务器中的Date并正确考虑时区和夏令时?

1 个答案:

答案 0 :(得分:0)

我在评论中使用Jon的建议解决了这个问题。我仍然需要Date,所以我无法开始使用Joda Time。然而,我确实从FastDateFormat和MutableDateTime转移到这个特定的用例。谢谢你的提示!解决方案如下所示:

Date datePart= ...;           // The date parsed from the first user input
String userTimeInput = ...;   // The time of day from the user
Locale userLocale = ...;
DateTimeZone userTimeZone = ...;

DateTime dateInUserTimeZone = new DateTime(datePart, userTimeZone);
DateTimeFormatter formatter = DateTimeFormat.shortTime().withLocale(userLocale);
LocalTime time = formatter.parseLocalTime(userTimeInput);

Date newDate = dateInUserTimeZone.withTime(time.getHourOfDay(), time.getMinuteOfHour(),
        time.getSecondOfMinute(), time.getMillisOfSecond()).toDate();