Parsing error for date field

前端 未结 2 1360
独厮守ぢ
独厮守ぢ 2020-12-12 05:40

I want to parse a date in YYYY-MM-DD format to YYYYMMDD. If I use the following function, it returns me a YYYYMMDD format but with a d

相关标签:
2条回答
  • 2020-12-12 06:04

    Not sure if the Question was meant for java.util.Date (a date plus time-of-day) or a java.sql.Date (a date-only). In both cases, you should be using the modern java.time classes rather than the troublesome legacy date-time classes.

    Some other java.sql.Date questions are linked as duplicates of this one. So I handle both classes (sql & util) here.

    java.util.Date

    The legacy java.util.Date class represents a moment on the timeline in UTC. This means a date with a time-of-day. The trick is that your input string is for a date-only value. You can first parse your string as a date-only value, then assign a time-of-day if desired.

    Your input string complies with the standard ISO 8601 format of YYYY-MM-DD. The java.time classes default to the standard formats when parsing/generating strings. So no need to specify a formatting pattern.

    LocalDate ld = LocalDate.parse( "2013-05-16" ) ;
    

    For a time-of-day, you probably want the first moment of the day. Do not assume the first moment is 00:00:00. In some time zones an anomaly such as Daylight Saving Time (DST) may cause a day to start at a different time such as 01:00:00. To account for such anomalies, we must specify a time zone in determining the first moment of the day.

    Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

    ZoneId z = ZoneId.of( "America/Montreal" ) ;
    

    Apply that zone in asking java.time to determine the first moment of the day. We produce a ZonedDateTime object as the result.

    ZonedDateTime zdt = ld.atStartOfDay( z ) ;
    

    If you desire a specific time of day, apply a LocalTime object. Keep in mind that your time-of-day may not be valid on that particular date for that particular zone. For example, you may be specifying a time-of-day occurring during a DST cutover. In such a case, the ZonedDateTime class has a policy for adjusting to accommodate. Be sure to read the documentation to understand that policy and the resulting behavior.

    LocalTime lt = LocalTime.of( 12 , 0 ) ; 
    ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;  // Time-of-day may be adjusted as needed.
    

    java.sql.Date

    No need to use java.sql.Date. That class is replaced by LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.

    JDBC drivers that comply with JDBC 4.2 can deal directly with java.time types by calling:

    • PreparedStatement::setObject
      myPrepStmt.setObject( … , myLocalDate ) ;
    • ResultSet::getObject
      LocalDate ld = myResultSet.getObject( … , LocalDate.class );

    For presentation of the LocalDate to the user, generate a String for display in your user-interface. Use a DateTimeFormatter to automatically localize. To localize, specify:

    • FormatStyle to determine how long or abbreviated should the string be.
    • Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

    Example:

    Locale l = Locale.CANADA_FRENCH ; 
    DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( l );
    String output = zdt.format( f );
    

    You can go the other direction as well, parsing an input string to get a date.

    LocalDate ld = LocalDate.parse( input , f ) ;
    

    Trap for the exception thrown if the user’s input is faulty or unexpected.

    try{ 
        LocalDate ld = LocalDate.parse( input , f ) ;
        myPrepStmt.setObject( … , ld ) ;
    } catch ( DateTimeParseException e ) {
        … // Handle the error condition of faulty/unexpected input by user.
    }
    

    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.

    Where to obtain the java.time classes?

    • Java SE 8, Java SE 9, and later
      • Built-in.
      • 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
      • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • Android
      • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
      • 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.

    0 讨论(0)
  • 2020-12-12 06:13

    A SimpleDateFormat should be capable of achieving what you're after. Be very careful with the format marks, D and d mean different things

    String oldDateString = "2013-05-16";
    System.out.println(oldDateString );
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse(oldDateString);
    System.out.println(date);
    String newDateString = new SimpleDateFormat("yyyyMMdd").format(date);
    System.out.println(newDateString);
    

    (Also, beware of Y and y :P)

    This outputs

    2013-05-16
    Thu May 16 00:00:00 EST 2013
    20130516
    

    For me...

    0 讨论(0)
提交回复
热议问题