Convert string to appropriate date with timezone java

后端 未结 2 1001
忘了有多久
忘了有多久 2021-01-12 12:54

I am Having Date with it\'s timezone, I want to convert it to another Timezone, E.g. I have Date \'3/15/2013 3:01:53 PM\' which is in TimeZone \'GMT-06:00\'. I want to conve

相关标签:
2条回答
  • 2021-01-12 13:21

    You need TWO format objects, one for parsing and another one for printing because you use two different timezones, see here:

    // h instead of H  because of AM/PM-format
    DateFormat parseFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
    Date dt = null;
    try {
      dt = parseFormat.parse("3/15/2013 3:01:53 PM -06:00");
    }catch (ParseException e) {
      e.printStackTrace();
    } 
    
    DateFormat printFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
    printFormat.setTimeZone(TimeZone.getTimeZone("GMT-05")); 
    String newDateString = printFormat.format(dt);
    System.out.println(newDateString);
    

    Output: 3/15/2013 04:01:53 PM -05:00

    If you want HH:mm:ss (24-hour-format) then you just replace

    hh:mm:ss aaa 
    

    by

    HH:mm:ss
    

    in printFormat-pattern.


    Comment on other aspects of question:

    A java.util.Date has no internal timezone and always refers to UTC by spec. You cannot change it inside this object. A timezone conversion is possible for the formatted string, however as demonstrated in my code example (you wanted to convert to zone GMT-05).

    The question then switches to the new requirement to print the Date-object in ISO-format using UTC timezone (symbol Z). This can be done in formatting by replacing the pattern with "yyyy-MM-dd'T'HH:mm:ssXXX" and explicitly setting the timezone of printFormat to GMT+00. You should clarify what you really want as formatted output.

    About java.util.GregorianCalendar: Setting the timezone here is changing the calendar-object in a programmatical way, so it affects method calls like calendar.get(Calendar.HOUR_OF_DAY). This has nothing to do with formatting however!

    0 讨论(0)
  • 2021-01-12 13:36

    tl;dr

    OffsetDateTime.parse( 
        "3/15/2013 3:01:53 PM -06:00" , 
        DateTimeFormatter.ofPattern( "M/d/yyyy H:mm:ss a XXX" )
    ).withOffsetSameInstant( 
        ZoneOffset.of( -5 , 0 ) 
    )
    

    2013-03-15T15:01:53-06:00

    java.time

    The Answer by Hochschild is correct but uses outdated classes. The troublesome old date-time classes bundled with the earliest versions of Java have been supplanted by the modern java.time classes.

    Parse your input string as a OffsetDateTime as it contains an offset-from-UTC but not a time zone.

    String input = "3/15/2013 3:01:53 PM -06:00";
    DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/yyyy h:mm:ss a XXX" );
    OffsetDateTime odt = OffsetDateTime.parse( input , f );
    

    odt.toString(): 2013-03-15T15:01:53-06:00

    Tip: Save yourself some hassle and use the ISO 8601 formats when exchanging date-time data as text. The java.time classes use these standard formats by default when parsing/generating strings.

    Apparently you want to see the same moment as viewed by the people elsewhere using a different offset-from-UTC.

    ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ;
    OffsetDateTime odt2 = odt.withOffsetSameInstant( offset ) ;
    

    We see the offset changes from 6 to 5, and the hour-of-day changes accordingly from 15 to 16. Same simultaneous moment, different wall-clock time.

    odt2.toString(): 2013-03-15T16:01:53-05:00

    Generating strings

    I want Date in "yyyy-MM-dd HH:mm:ss" format where HH is in 24 hour.

    I suggest you always include some indication of the offset or zoneunless your are absolutely certain the user understands from the greater context.

    Your format is nearly in standard ISO 8601 format. You could define your own formatting pattern, but I would just do string manipulation to replace the T in the middle with a SPACE.

    String output = odt2.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " ) ;
    

    2013-03-15 16:01:53


    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.

    With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.

    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
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android, 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.

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