如何在Java 1.6中将UTC日期转换为本地日期

如何在Java 1.6中将UTC日期转换为本地日期,java,datetime,timezone,java-6,Java,Datetime,Timezone,Java 6,我从XML文件中获得一个带有UTC时间戳的字符串,如下所示: 2019-05-24T00:59:55.1-05:00 我使用下面的方法将字符串转换为日期 private Date getUTC2JavaDateB(String dateStr) { String dateS = dateStr; String timePattern = ""; Date d = null; SimpleDateFormat formatter = null; i

我从XML文件中获得一个带有UTC时间戳的字符串,如下所示:

2019-05-24T00:59:55.1-05:00
我使用下面的方法将字符串转换为日期

    private Date getUTC2JavaDateB(String dateStr) {
    String dateS = dateStr;
    String timePattern = "";
    Date d = null;
    SimpleDateFormat formatter = null;
    if (dateS.length() >= 19) {
        dateS = dateS.substring(0, 19);
    }
    timePattern = "yyyy-MM-dd'T'hh:mm:ss";
    formatter = new SimpleDateFormat(timePattern);
    d = formatter.parse(dateS, new ParsePosition(0));

    return d;
}
现在我的问题来了。我想把它从UTC转换成当地时间

我在其他一些线程中发现了一些代码片段,但它们对我来说还不起作用

    private Date toLocalTimeStamp(Date date) {
    try {

        DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone()));

        return currentTFormat.format(date);
    } catch (Exception ex) {
        return date;
    }
}
我得到的异常字符串无法转换为日期-这对我来说很清楚。但是现在如何将字符串转换为日期呢?我将UTC转换为本地日期的方法正确吗


非常感谢您的帮助!:-

您的字符串上已经有时区指示器。如果由于某种原因而无法使用Java 6,请参见,您可以轻松地稍微更新字符串,然后使用以下命令对其进行完整解析,包括时区:

三百一十个后场 我在Java1.7.067上运行了这个程序。输出为:

2019-05-24T07:59:55.100+02:00[欧洲/哥本哈根]

我自己没有安装Java1.6,但运行该程序至少证明它不需要Java1.8。我敢说它也将在您的Java1.6上运行。你只需要在你的项目中添加三个十端口。使用底部的链接

ThreeTen Backport是java.time(现代java日期和时间API)到Java6和Java7的后端口

我正在利用这样一个事实,即您的日期时间字符串是ISO 8601格式,java.time中的类解析并打印为默认格式。您可能知道,字符串末尾的-05:00是UTC偏移量,意味着比UTC晚5小时,因此00:59:55.1对应于05:59:55.1 UTC

即使在Java1.6上,也不需要使用Date和SimpleDataFormat。这些类的设计总是很糟糕,尤其是后者是出了名的麻烦。所以不要考虑使用它们。

如果可以,请指定时区 ZoneId.systemDefault为您提供JVM的时区设置。这应该是您要求的“本地时区”,但很脆弱,因为程序的另一部分或在同一JVM中运行的任何其他程序可以随时更改该设置。如果您有办法知道正确的时区,那么最好明确地指定它。例如:

    ZonedDateTime dateTimeInMyTimeZone
            = dateTime.atZoneSameInstant(ZoneId.of("Africa/Algiers"));
2019-05-24T06:59:55.100+01:00[非洲/阿尔及尔]

你怎么了? 首先,我怀疑你的期望是错误的。这两种转换方法都返回一个日期,但日期不能有时区,因此没有任何用处。约会是一个时间点,不多不少。与日期相反,java.time提供了OffsetDateTime,带有UTC偏移的日期和时间,以及ZonedDateTime,带有时区的日期和时间

格式模式字符串中的小写hh不正确。这是从凌晨1点到下午12点的一小时。字符串中的小时是24小时制,从00点到23点。对于这一点,您需要在第二个方法中使用大写的HH

接下来,您将不分析字符串的UTC偏移量,因此可能会获取错误的时间SimpleDataFormat在本例中使用默认时区。在您的示例中,您还忽略了小数点1,这是一个引入小于1秒的错误的细节。SimpleDataFormat无法正确解析秒上的一个小数,因为它只支持三个小数

链接 解释如何使用java.time。 ,其中首次描述了java.time。 ,java.time的后端口到JSR-310的Java6和Java7。 ,Android版Three Ten Backport ,解释得非常透彻。
如果您停留在Java6上,并且没有最近的时间处理库Joda time、310 backport

使用XML数据处理方法 您试图解析的日期是ISO-8601格式的,这是XML日期时间数据类型使用的格式

JAXB实现附带了Java6,它提供了许多XML处理工具,包括解析ISO8601日期类型。这里特别感兴趣的是

因此,这将为您提供一个java.util.Date:

然后,您将能够在感兴趣的区域中显示和格式化

    // What is the UTC hour of 00:59:55.1 at -5 offset ?
    SimpleDateFormat utc = new SimpleDateFormat("HH:mm");
    utc.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(utc.format(date)); // --> 05:59

    // What would it be in Paris ?
    SimpleDateFormat paris = new SimpleDateFormat("HH:mm");
    paris.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
    System.out.println(paris.format(date)); // -> 07:59 Paris is UTC+2 in the summer, so it's OK.

该时间戳不是UTC格式。在GMT-05:00,有时被称为东部标准时间。你为什么使用Java6?它已经严重过时了。它在将近八年前被Java7取代。目前的版本是11,尽管出于许可的原因,有些人使用9或10。这不仅仅是一个无聊的问题,Java 8添加了Java.time包,它比Java.lang.Date及其相关内容更有用。试着看看joda时间库,或者如果你可以升级jdk,你可以使用LocalDate类joda时间是一个不错的建议,@GJCode,但joda时间处于维护模式。IMHO,java.time的后端口,将是一个更好的建议。time是现代的java日期和时间API,内置于Java8中,因此它也是未来的证明。无论如何,值得考虑的是,将日期和简化格式远远抛在后面,它们总是设计得很糟糕。这是一种过时的时尚
ed日期既没有时区也没有UTC偏移量,所以你的问题没有完全的意义。例如,请参阅,Java 1.4中引入了.assert。是的,目前我一直使用Java 6,但由于在我的应用程序的下一个版本中讨论了许可问题,我将更新到Java 8。提供XML的开发人员告诉我,XML中的时间戳是UTC格式的,尽管正如您所指出的,它们包含一个时区指示器。完全是一团糟,但现在我不得不忍受它。@Malawirel-它们不是,但希望上面的内容能帮助你处理它们-在此之前,我将更新到Java8,以便有更多的理由使用ThreeTen Backport。升级后,您可以更改导入语句,然后重新测试,这样您就可以使用内置的java.time,并且可以再次跳过对后端口的依赖关系。只是我的2øre…
    ZonedDateTime dateTimeInMyTimeZone
            = dateTime.atZoneSameInstant(ZoneId.of("Africa/Algiers"));
java.util.Date date = DatatypeFactory.newInstance()
  .newXMLGregorianCalendar("2019-05-24T00:59:55.1-05:00")
  .toGregorianCalendar()
  .getTime()
    // What is the UTC hour of 00:59:55.1 at -5 offset ?
    SimpleDateFormat utc = new SimpleDateFormat("HH:mm");
    utc.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(utc.format(date)); // --> 05:59

    // What would it be in Paris ?
    SimpleDateFormat paris = new SimpleDateFormat("HH:mm");
    paris.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
    System.out.println(paris.format(date)); // -> 07:59 Paris is UTC+2 in the summer, so it's OK.