How to convert UTC Date String and remove the T and Z in Java?

匆匆过客 提交于 2020-06-11 06:08:09

问题


Am using Java 1.7.

Trying to convert:

2018-05-23T23:18:31.000Z 

into

2018-05-23 23:18:31

DateUtils class:

public class DateUtils {

    public static String convertToNewFormat(String dateStr) throws ParseException {
        TimeZone utc = TimeZone.getTimeZone("UTC");
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        sdf.setTimeZone(utc);
        Date convertedDate = sdf.parse(dateStr);
        return convertedDate.toString();
    }
}

When trying to use it:

String convertedDate = DateUtils.convertToNewFormat("2018-05-23T23:18:31.000Z");
System.out.println(convertedDate);

Get the following exception:

Exception in thread "main" java.text.ParseException: Unparseable date: "2018-05-23T23:22:16.000Z"
   at java.text.DateFormat.parse(DateFormat.java:366)
   at com.myapp.utils.DateUtils.convertToNewFormat(DateUtils.java:7)

What am I possibly doing wrong?

Is there an easier way to do is (e.g. Apache Commons lib)?


回答1:


Try this. You have to use one pattern for parsing and another for formatting.

public static String convertToNewFormat(String dateStr) throws ParseException {
    TimeZone utc = TimeZone.getTimeZone("UTC");
    SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sourceFormat.setTimeZone(utc);
    Date convertedDate = sourceFormat.parse(dateStr);
    return destFormat.format(convertedDate);
}



回答2:


tl;dr

Instant.parse( "2018-05-23T23:18:31.000Z" )                // Parse this String in standard ISO 8601 format as a `Instant`, a point on the timeline in UTC. The `Z` means UTC.
.atOffset( ZoneOffset.UTC )                                // Change from `Instant` to the more flexible `OffsetDateTime`.
.format(                                                   // Generate a String representing the value of this `OffsetDateTime` object.
    DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" )   // Specify a formatting pattern as desired.
)                                                          // Returns a `String` object.

2018-05-23 23:18:31

ISO 8601

Your input string is in standard ISO 8601 format.

The java.time classes use these standard formats by default when parsing/generating strings.

The T separates the year-month-day portion from the hour-minute-second. The Z is pronounced Zulu and means UTC.

java.time

You are using troublesome old date-time classes that were supplanted years ago by the java.time classes. The Apache DateUtils is also no longer needed, as you will find its functionality in java.time as well.

Parse that input string as a Instant object. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

String input = "2018-05-23T23:18:31.000Z" ;
Instant instant = Instant.parse( input ) ;

To generate a string in another format, we need a more flexible object. The Instant class is meant to be a basic building block. Lets convert it to aOffsetDateTime`, using UTC itself as the specified offset-from-UTC.

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

Define a formatting pattern to match your desired output.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = odt.format( f ) ;

Tip: Consider using DateTimeFormatter::ofLocalized… methods to automatically localize the String generation per some Locale rather than hard-coding a formatting pattern.


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, 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 (<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.




回答3:


For others without Java 1.7 Restrictions:

Since Java 1.8 you can do it using LocalDateTime and ZonedDateTime from the package java.time

public static void main(String[] args) {
    String sourceDateTime           = "2018-05-23T23:18:31.000Z";
    DateTimeFormatter sourceFormat  = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    DateTimeFormatter targetFormat  = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    LocalDateTime dateTime          = LocalDateTime.parse(sourceDateTime, sourceFormat);
    String formatedDateTime         = dateTime.atZone(ZoneId.of("UTC")).format(targetFormat);
    System.out.println(formatedDateTime);
}

EDIT: (see Comments)

Quote from the Oracle Java documentation of LocalDateTime:

LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value "2nd October 2007 at 13:45.30.123456789" can be stored in a LocalDateTime.

This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.

the OP is asking to JUST parsing an Input String to a date-time (as year-month-day-hour-minute-second) and the Documentation says

LocalDateTime ... represents a date-time, often viewed as year-month-day-hour-minute-second

so no important information are lost here. And the part dateTime.atZone(ZoneId.of("UTC")) returns a ZonedDateTime so the ZimeZone is handled at this point again if the user needs to work with the timezone ...etc.

so don't try to force users to use the "One and Only" solution you present in your answer.




回答4:


YYYY does not match with year part. In java 7 you need yyyy.

For T, use 'T' to match it

You're also missing the faction of millsecond part: .SSS

Try this:

String dateStr="2018-05-23T23:18:31.000Z";
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(utc);
Date convertedDate = sdf.parse(dateStr);
convertedDate.toString();



回答5:


In Kotlin and using ThreeTenABP,

fun getIsoString(year: Int, month: Int, day: Int): String {
    val localTime = ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of("Z"))

    val utcTime = localTime.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC)

    val isoString = utcTime.toInstant().toString() // 1940-15-12T00:00:00Z

    val formattedIsoString = val formattedIsoString =
        Instant.parse(isoString)
            .atOffset(ZoneOffset.UTC)
            .format(DateTimeFormatter
                .ofPattern("uuuu-MM-dd'T'HH:mm:ss")) // 'T' in quotes so that it is retained.

    return formattedIsoString
}

// print it
print(getIsoString(1940, 15, 12)) // 1940-15-12T00:00:00


来源:https://stackoverflow.com/questions/50498949/how-to-convert-utc-date-string-and-remove-the-t-and-z-in-java

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