java GregorianCalendar添加小时奇怪的行为

时间:2013-01-10 23:05:04

标签: java calendar gregorian-calendar

我有GregorianCalendar的问题所以如果你愿意,可以帮我解决它。首先,我会给你我的代码:

private String changeClock(String day, String clock, int change) {
    String time="";
    DateFormat df=new SimpleDateFormat("yyyy-MM-dd hh:mm");
    try {
        Date d=df.parse(day+" "+clock);
        GregorianCalendar g=new GregorianCalendar();
        g.setTime(d);
        g.add(GregorianCalendar.HOUR_OF_DAY, change);
        time=g.get(GregorianCalendar.YEAR)+"-"
                +(g.get(GregorianCalendar.MONTH)+1)+"-"
                +g.get(GregorianCalendar.DAY_OF_MONTH)+" "
                +g.get(GregorianCalendar.HOUR_OF_DAY)+":"
                +g.get(GregorianCalendar.MINUTE);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return time;
}

让我解释一下发生了什么。我有一个带+和 - 按钮的GUI。当有人按+时加一小时,或者按 - 然后按一小时。

现在的例子,时间是23:00,我按+,一切都好,跳到第二天的00:00。问题是在12:00。如果是12:00,我按+它会转到1:00然后继续。即使在2x12小时或21465x12小时之后,它也不会移动到第二天。 如果我能说的话,向后移动会好一些。当它是00:00并且我按 - 它变为昨天23:00(也是日期变化)。如果我然后按+它也会在前一天发生变化(在这种情况下也是今天)。

我做错了什么或者我还应该写些什么?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

您的日期格式错误...

您正在使用hh,它代表“上午/下午(1-12)小时”,因此下午1点的时间已转换为凌晨1点

你应该使用HH代表“一天中的小时(0-23)”

或者你需要使用am / pm标记提供日期/时间格式......

使用DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm");DateFormat df=new SimpleDateFormat("yyyy-MM-dd hh:mm a");

您应该传入和返回String对象,而不是依赖Date日期/时间值,而是保留显示的格式。

答案 1 :(得分:0)

TL;博士

LocalDateTime.parse( 
    "2016-01-02 12:34:56".replace( " " , "T" ) 
)

使用java.time

Answer by MadProgrammer是正确的:格式化模式中使用的代码错误。但是有一种更简单,更好的方法。

您正在使用现在由java.time类取代的麻烦的旧日期时间类。

您的输入格式几乎采用标准ISO 8601格式。只需用T替换中间的SPACE即可。

String input = "2016-01-02 12:34:56".replace( " " , "T" );

java.time classe默认使用ISO 8601格式。因此需要指定格式化模式,因此没有格式化代码出错。

LocalDateTime ldt = LocalDateTime.parse( input );

我们解析为LocalDateTime,因为输入缺少有关UTC或时区偏移量的信息。如果此值适用于UTC,请应用偏移量以获得OffsetDateTime

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );

如果用于某个时区,请转换为ZonedDateTime

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( z );

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendar和& java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP(见How to use…)。

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter等。