Java日期从长期返回错误的一天

时间:2016-01-24 19:03:58

标签: java android date

我正在编写Android应用,它使用DatePicker。 日期以年份monthOfYear,dayOfMonth。

的形式返回

从那里我可以格式化日期:

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date d = format.parse(year + "-" + (monthOfYear + 1) + "-" + dayOfMonth);
                String dString = d.toString().substring(0, 10) + " " +  year;
                if(startEnd) {
                    startDateText.setText(dString);
                    startDate = new Date(year, monthOfYear, dayOfMonth);
                    Log.d("Start date set- ", startDate.toString());
                } else {
                    endDateText.setText(dString);
                    endDate = new Date(year, monthOfYear, dayOfMonth);
                    Log.d("End date set- ", endDate.toString());
                }

            } catch (ParseException e) {
                Log.d("Exception- ", e.getMessage());
            }

if(startEnd)部分只是引用两个不同的文本视图,因为正在收集一系列日期。

此时数据出错了。 返回的值是正确的。例如,当我选择星期六,1月2日时,我得到的值是2016年1月1日,即年月日。

dString的值也是正确的,最终为2016年1月2日星期六。

但是,当我调用startDate.toString()时,返回的值是Sun Jan 02 00:00:00 GMT + 00:00 3916,这是休息日。

这种情况发生在每个日期,我不知道为什么。

startDate和endDate的long值通过setResult()传回,因为它们将在别处使用。从这些长值产生的日期都会在一天之内产生相同的日期。

提前感谢您提供任何帮助

2 个答案:

答案 0 :(得分:4)

如果您查看了Date javadoc,您会看到您正在呼叫的构造函数需要year-1900。因此,对于2016年,您将提供116作为年份:

new Date( 116, 0, 2 );

此外,需要指定月份0索引。因此,1月0不是1

我还应该注意到它是一个弃用的构造函数。您应该更喜欢Calendar.set(year + 1900, month, date)GregorianCalendar(year + 1900, month, date)

答案 1 :(得分:2)

accepted Answer by ulmangt是正确的。但是有一种非常简单和容易的方式。

避免旧的日期时间类

与最早版本的Java捆绑在一起的旧日期时间类是众所周知的麻烦。避免他们。

相反,请使用Joda-Time库;只需在您的项目中添加一个jar。在Java 8及更高版本中,使用内置的java.time框架(受Joda-Time启发)。

LocalDate

Joda-Time和java.time都有LocalDate类来表示没有时间且没有时区的仅限日期的值。

问题中的代码试图将日期时间值用作仅限日期的值。由于日期时间是UTC,因此速度很快。在应用当地时区时,日期可能会有所不同。

如果您的格式为" yyyy-MM-dd",则符合ISO 8601标准。默认情况下,在Joda-Time和java.time中使用该标准来解析/生成日期时间值的字符串表示。所以不需要指定解析模式。

一些Joda-Time代码。

LocalDate localDate = LocalDate.parse( "2016-01-02" );

或者您可以传递年,月和日的整数。

LocalDate localDate = new LocalDate( 2016 , 1 , 2 );

默认情况下,toString方法使用相同的ISO 8601格式。您可以使用DateTimeFormatDateTimeFormatter生成字符串时指定其他格式。搜索StackOverflow有很多例子。

如果用户界面需要,您可以查询LocalDate年份,月份和日期数字。

int year = localDate.getYear();
int monthOfYear = localDate.getMonthOfYear();
int dayOfMonth = localDate.getDayOfMonth();