-5

我尝试从字符串中解析日期,但是当我打印它时,它显示一个错误的日期。我的代码:

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;

public class Main {
    public static void main(String args[]) {
        String some_date = "2017-12-31";
        Calendar cal_aux = GregorianCalendar.getInstance();
        System.out.println("set calendar: " + Integer.parseInt(some_date.substring(0, 4))
                + Integer.parseInt(some_date.substring(5, 7))
                + Integer.parseInt(some_date.substring(8, 10)));
        cal_aux.set(Integer.parseInt(some_date.substring(0, 4)),
                Integer.parseInt(some_date.substring(5, 7)),
                Integer.parseInt(some_date.substring(8, 10)));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("sdf calendar: " + sdf.format(cal_aux.getTime()));
    }
}

控制台输出:

set calendar: 20171231
sdf calendar: 2018-01-31 12:51:02

为什么当我使用简单的日期格式时,我得到的是 2018 而不是 2017?

4

2 回答 2

2

避免现在被 java.time 类取代的遗留日期时间类。有问题的遗留类有许多设计错误。一个这样的错误是将月份计算为 0-11 而不是 1-12。这种疯狂的计数正在破坏您的代码。

不要将日期时间值作为字符串进行操作。使用对象。

对于该仅日期值,请使用LocalDate.

LocalDate ld = LocalDate.parse( "2017-12-31" )  ;  // Or LocalDate.now() for today's date.

使用DateTimeFormatter.

String output = ld.format( DateTimeFormatter.BASIC_ISO_DATE ) ;

20171231

如果需要,分配一天中的时间。

LocalTime lt = LocalTime.of( 6 , 15 ) ;
LocalDateTime ltd = LocalDateTime.of( ld , lt ) ;

如果您想要一个实际的时刻,即时间线上的一个特定点,请应用一个时区。

ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
于 2017-11-08T17:25:21.403 回答
1

首先,您设置了错误的日期,因为月份范围是 0-11。当您在月份字段中设置 12 时,是 2018 年 1 月而不是 2017 年 12 月。

其次,您可以简化程序,将输入字符串解析为格式化日期,并将此日期解析为输出格式化字符串。这是一个例子:

String input = "20171231";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

try {
    System.out.println(outputFormat.format(inputFormat.parse(input)));
} catch (ParseException e) {
    // Log error
}
于 2017-11-07T21:59:28.900 回答