简体   繁体   中英

java GregorianCalendar adding hour strange behavior

I have a problem with GregorianCalendar so if you please can help me out with it. 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. 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. Problems are on 12:00. If it is 12:00 and I press + it goes to 1:00 and that goes on and on. It doesn't move to the next day even after 2x12 hours or 21465x12 hours. 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). 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.

You should be using HH which is aa representation of the "Hour in day (0-23)" .

Either that, or you need supply a date/time format with the am/pm marker...

Using either DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm"); or 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.

tl;dr

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

Using java.time

The Answer by MadProgrammer is correct: Wrong code used in formatting pattern. But there is an even easier and better approach.

You are using troublesome old date-time classes now supplanted by the java.time classes.

Your input format in almost in standard ISO 8601 format. Just replace the SPACE in middle with a T .

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

The java.time classe use ISO 8601 formats by default. 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. If this value was meant for UTC, apply an offset to get an OffsetDateTime .

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

If meant for some time zone, transform into a ZonedDateTime .

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date , .Calendar , & java.text.SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to java.time.

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations.

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… ).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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