简体   繁体   English

java GregorianCalendar添加小时奇怪的行为

[英]java GregorianCalendar adding hour strange behavior

I have a problem with GregorianCalendar so if you please can help me out with it. 我的GregorianCalendar有问题,所以请您帮我解决。 First I'll give you my code: 首先,我给你我的代码:

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;
}

Let me explain what is happening. 让我解释一下发生了什么。 I have a GUI with + and - button. 我有一个带有+和-按钮的GUI。 When someone press + it add one hour, or if - is pressed then take one hour. 当有人按下+时,会增加一小时;如果按下-,则需要一小时。

Now example, time is 23:00 and I press +, it is everything ok and it jumps to 00:00 of the next day. 现在举个例子,时间是23:00,我按+,就可以了,它跳到了第二天的00:00。 Problems are on 12:00. 问题在12:00。 If it is 12:00 and I press + it goes to 1:00 and that goes on and on. 如果是12:00,然后按+,则转到1:00,然后继续。 It doesn't move to the next day even after 2x12 hours or 21465x12 hours. 即使经过2x12小时或21465x12小时,它也不会移动到第二天。 Moving backward is a little better if I can say so. 如果可以这样说,向后移动会更好一些。 When it is 00:00 and I press - it changes to yesterday 23:00 (also date changes). 当它是00:00时,我按-它更改为昨天23:00(日期也更改)。 If I then press + it changes also one day forward (so to today in this case). 如果我再按+,则它也会在一天前更改(在这种情况下,更改为今天)。

What have I done wrong or what more should I write to my code? 我做错了什么,或者应该写些什么?

Thanks for your help guys. 感谢您的帮助。

Your date format is wrong... 您的日期格式有误...

You're using hh , which is a representation of the "Hour in am/pm (1-12)" , so a time of 1pm is been converted to 1am instead. 您使用的是hh ,它表示“小时在am / pm(1-12)中” ,因此将1pm的时间转换为1am。

You should be using HH which is aa representation of the "Hour in day (0-23)" . 您应该使用HH ,它表示“一天中的小时(0-23)”

Either that, or you need supply a date/time format with the am/pm marker... 要么,要么您需要提供带有am / pm标记的日期/时间格式...

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

Instead of relying on String date/time values, you should be passing in and back a Date object, leave the formatting for the display. 而不是依赖于String日期/时间值,您应该传入和传回Date对象,并保留显示格式。

tl;dr tl; dr

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

Using java.time 使用java.time

The Answer by MadProgrammer is correct: Wrong code used in formatting pattern. MadProgrammer答案是正确的:格式化模式中使用的代码错误。 But there is an even easier and better approach. 但是,有一种更轻松,更好的方法。

You are using troublesome old date-time classes now supplanted by the java.time classes. 您正在使用麻烦的旧日期时间类,而现在却被java.time类所取代。

Your input format in almost in standard ISO 8601 format. 您的输入格式几乎采用标准的ISO 8601格式。 Just replace the SPACE in middle with a T . 只需将中间的SPACE替换为T

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

The java.time classe use ISO 8601 formats by default. 默认情况下,java.time类使用ISO 8601格式。 So need to specify a formatting pattern at all, so no formatting codes to get wrong. 因此,根本不需要指定格式格式,因此没有格式代码会出错。

LocalDateTime ldt = LocalDateTime.parse( input );

We parse as a LocalDateTime because the input lacks information about offset-from-UTC or time zone. 我们将其解析为LocalDateTime因为输入缺少有关UTC偏移量或时区的信息。 If this value was meant for UTC, apply an offset to get an OffsetDateTime . 如果此值用于UTC,则应用偏移量以获得OffsetDateTime

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

If meant for some time zone, transform into a ZonedDateTime . 如果要用于某个时区,请转换为ZonedDateTime

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

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old date-time classes such as java.util.Date , .Calendar , & java.text.SimpleDateFormat . 这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendarjava.text.SimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to java.time. 现在处于维护模式Joda-Time项目建议迁移到java.time。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use… ). 大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,并进一步适应的AndroidThreeTenABP (见如何使用...... )。

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more. 您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuarter等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM