Android Joda DateTime 休息一小时

Android Joda DateTime one hour off

我有一个 TimePickerDialog,它可以让用户选择一个时间。 TimePickerDialog 有一个 onTimeSet 方法,当用户完成选择时间时调用该方法。 我将参数传递给第二个方法 setTime(int hour, int minute),它保存值并显示格式化时间。 这是该方法的代码片段:

java.text.DateFormat dateFormatter = 
java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT, Locale.getDefault());

DateTime dt = new DateTime();
dt = dt.hourOfDay().setCopy(hour);
dt = dt.minuteOfHour().setCopy(minute);
String text = dateFormatter.format(dt.toDate());

问题是(有时,并非总是)小时值偏差一小时甚至两小时。我认为问题的原因与时区有关,但我不知道确切的原因是什么。我还认为问题是由 Joda DateTime 对象引起的,因为在我实施 Joda 时间之前我没有遇到任何问题,而且它也会在一小时后保存。 知道会发生什么/如何解决它吗?

对于这个答案,我使用的是 joda-time 2.7(尽管它可能适用于以前的版本)。

我还假设您的程序只关心 小时分钟(我不是 Android专家,但我看到了 TimePickerDialog 的文档,似乎是这样。

因此,如果您只处理 小时 分钟 ,则不需要使用 DateTime class(实际上你不应该在这种情况下)。

那是因为 DateTime 对象是所有日期字段的 "aware",包括日、月、年和时区。因此,当您创建一个 new DateTime() 时,它会在您的默认时区中创建一个具有当前日期和时间的新对象。如果默认时区的当前日期是夏令时(又名夏令时),您可以进行这些小时转换。

(而且我相信 Android 从设备的系统中获取默认时区,因此它可以根据设备 运行 代码而有所不同 - 至少是这样在计算机上工作,因此对于设备应该没有什么不同。

因为你不需要知道 day/month/year 和时区,你可以使用 LocalTime class (org.joda.time.LocalTime) 这是一个 class只有 小时分钟 字段(和秒,如果你愿意的话;如果你不关心秒,他们会设置为零 )。最好的部分是:这个 class 不关心时区,所以 10:00 AM 将永远是 10:00 AM.

您也不需要使用 java.text.DateFormat,因为 joda-time 有自己的格式化程序。所以代码将是这样的:

public void setTime(int hour, int minute) {
    // shortTime() is equivalent to DateFormat.SHORT
    DateTimeFormatter fmt = DateTimeFormat.shortTime().withLocale(Locale.getDefault());
    LocalTime time = new LocalTime(hour, minute);
    String text = fmt.print(time);
    System.out.println(text);
}

做一些测试(假设默认语言环境是 en_US):

setTime(9, 30); // prints 9:30 AM
setTime(10, 0); // prints 10:00 AM

PS:输出可能会因您的默认值 Locale 而异(我也相信它来自设备的系统)。如果你想要一个固定的格式(独立于语言环境),你可以使用 DateTimeFormat.forPattern("h:mm a"),这也会产生上面的输出(当你以这种方式使用格式化程序时,默认语言环境不会改变输出)。