Java Date and utcTimeOffset [closed]

穿精又带淫゛_ 提交于 2019-12-13 10:13:45

问题


I have a Java Date (java.util.Date) - Tue Jul 31 00:53:43 CEST 2018 and a utcTimeOffset = +0200, which says that give, date is +2 hours from UTC.

This is a legacy code and Java 8 is not an option. What I am getting is text representation of date as 20180730131847 and utcTimeOffset = +0200 from a third-party API.

I would like to convert this to Danish time. Can someone help me how to do this please.


回答1:


java.time, the modern Java date and time API

    ZoneId danishTime = ZoneId.of("Europe/Copenhagen");
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss");
    DateTimeFormatter offsetFormatter = DateTimeFormatter.ofPattern("XX");

    String dateTimeString = "20180730131847";
    String offsetString = "+0200";
    ZoneOffset offset = ZoneOffset.from(offsetFormatter.parse(offsetString));
    ZonedDateTime dateTime = LocalDateTime.parse(dateTimeString, dateTimeFormatter)
            .atOffset(offset)
            .atZoneSameInstant(danishTime);
    System.out.println("Danish time: " + dateTime);

Output from this code is:

Danish time: 2018-07-30T13:18:47+02:00[Europe/Copenhagen]

The time zone to use for Denmark is Europe/Copenhagen. While the Faroe islands and Greenland use other time zones and are in a national community (“rigsfællesskab”) with Denmark under the same queen, they are not part of Denmark proper, so can be ignored when Danish time is asked for. Since Danish summer time agrees with your example offset of +0200, in this case we get the same time out as we put in. With a date in winter, for example, this would not have been the case because Danish standard time is at offset +0100.

Java 8 is not an option

No big problem. java.time has been backported.

  • In Java 8 and later and on new Android devices (from API level 26, I’m told) the new API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310, where the modern API was first described). Link below.
  • On (older) Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. Make sure you import the date and time classes from package org.threeten.bp and subpackages.

In the backport the classes are in package org.threeten.bp with subpackages, for example org.threeten.bp.ZoneId and org.threeten.bp.format.DateTimeFormatter.

Links

  • Oracle tutorial: Date Time, explaining how to use java.time.
  • ThreeTen Backport project
  • ThreeTenABP, Android edition of ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
  • Java Specification Request (JSR) 310.



回答2:


tl;dr

Your input is in a poor format, but in this case can be parsed using the modern java.time classes. Note that unfortunate use of 3-4 letter pseudo-zone such as CEST are not standardized and are not unique so they cannot always be parsed as your intended zone.

For Java 8 and later, these classes are built-in. For Java 6 & 7, see the ThreeTen-Backport project detailed below.

ZonedDateTime.parse(    // Parse an input string as a date-time moment.
    "Tue Jul 31 00:53:43 CEST 2018" ,
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu", Locale.US )                 // Specify `Locale` to determine human language and cultural norms to be used in translation.
)                       // Returns a `ZonedDateTime` object.
.withZoneSameInstant(   // Adjust from one zone to another.
    ZoneId.of( "Europe/Copenhagen" )  // Always use `Continent/Region` time zone names, never 3-4 letter pseudo-codes such as `CEST`.
)
.toString()             // Generate a `String` with text in standard ISO 8601 format wisely extended by appending the name of the time zone in square brackets.

2018-07-31T00:53:43+02:00[Europe/Copenhagen]

java.time

This has been covered many times already, so search Stack Overflow for more discussion.

Parse

String input = "Tue Jul 31 00:53:43 CEST 2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu", Locale.US );
ZonedDateTime zdt = ZonedDateTime.parse( input , f  );

zdt.toString(): 2018-07-31T00:53:43+02:00[Europe/Paris]

Adjust

Adjust to a Denmark time zone. I will arbitrarily choose the Europe/Copenhagen. Denmark may have other zones, such as for Greenland or other parts of the kingdom.

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( "Europe/Copenhagen" ) ;
ZonedDateTime zdtCopenhagen = zdt.withZoneSameInstant( z );  // Same moment, different wall-clock time.

2018-07-31T00:53:43+02:00[Europe/Copenhagen]

Notice that on that date and hour, Paris and Copenhagen time zones shared the same offset-from-UTC, so they perceive the same time-of-day.

ISO 8601

Your input string is using a terrible format. It is difficult to parse, assumes English language, and includes redundant information.

When exchanging date-time values as text, use only the standard ISO 8601 formats.

Note that the ZonedDateTime class wisely extends that format to append the name of the time zone in square brackets. This is seen in output above.


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
    • 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.



来源:https://stackoverflow.com/questions/51949842/java-date-and-utctimeoffset

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