SimpleDateFormat parse returns wrong value

最后都变了- 提交于 2019-12-11 02:47:59

问题


I have this code:

public static String formatMinSecOrHourMinSec(final String length) {
        try {
            final SimpleDateFormat hhmmss = new SimpleDateFormat("HH:mm:ss", Locale.GERMAN);
            final Date date = hhmmss.parse(length);
            final GregorianCalendar gc0 = new GregorianCalendar(Locale.GERMAN);
            gc0.setTime(date);
            if(gc0.getTimeInMillis() >= 3600 * 1000){
                return hhmmss.format(gc0.getTime());
            }else{
                final SimpleDateFormat mmss = new SimpleDateFormat("mm:ss");
                return mmss.format(gc0.getTime());                    
            }
        } catch (final ParseException e) {
            LOGGER.debug("Konnte die Länge nicht parsen: " + length + "\n" + e);
            return length;
        }
    }

I estimate that it returns 01:29:00 if length is set to 01:29:00 but it returns 29:00. This is because gc0.getTimeInMillis() returns one hour less (3600 * 1000) than expected. What am I doing wrong ?


回答1:


this is because java.util.Date is using your default time zone. (print time in ms from date and you will see). To fix it try:

final SimpleDateFormat hhmmss = new SimpleDateFormat("HH:mm:ss");
hhmmss.setTimeZone(TimeZone.getTimeZone("UTC"));



回答2:


tl;dr

Do not conflate a span-of-time with a time-of-day. Two different concepts deserve two different classes. A span-of-time is represented by the Duration (or Period) class.

Duration
.ofHours( 1 )
.plusMinutes( 29 ) 

…or…

Duration
.parse( "PT1H29M" ) 

Wrong classes

First, you are using inappropriate classes. Apparently you are trying to track a span-of-time but are using time-of-day to do so. A span and a time are two different concepts. Mixing the two leads to ambiguity, confusion, and errors.

Second, you are using terrible old classes that were supplanted years ago by the java.time classes. Never use SimpleDateFormat, GregorianCalendar, etc.

Span-of-time

The correct class for a span-of-time in the range of hours-minutes-seconds is Duration. For a range of years-months-days, use Period.

You can instantiate your Duration from numbers of hours and minutes.

Duration d = Duration.ofHours( 1 ).plusMinutes( 29 ) ; 

Or you can parse a string in standard ISO 8601 format, PnYnMnDTnHnMnS.

Duration d = Duration.parse( "PT1H29M" ) ;

Date-Time math

You can do math with date-time values. Perhaps you want to know when is an hour and twenty-nine minutes from now.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;  
ZonedDateTime now = ZonedDateTime.now( z ) ; // Capture the current moment as seen though the wall-clock time used by the people of some particular region.
ZonedDateTime later = now.plus( d ) ;  // Add a span-of-time to determine a later moment (or an earlier moment if the `Duration` is negative). 

About java.time

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

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.



来源:https://stackoverflow.com/questions/19515385/simpledateformat-parse-returns-wrong-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!