国家本地TZD格式的纪元时间戳

时间:2018-05-03 15:24:08

标签: java datetime timezone dst country-codes

我有时代的时间戳和国家。我想将时间戳转换为具有夏令时(TZD)格式的时区区域的给定国家/地区本地时间戳,如下所示

yyyy-mm-ddThh:MM:ssTZD
e.g. 2018-02-25T22:36:23+0100

Timestamp : 1525370235
Country : NLD (ISO alpha-3 code)

我如何用Java实现这一目标?

更新1

我正在使用这种转换,但不确定它是正确还是错误。有人可以让我知道这是转换的核心方式

Locale locale = new Locale("NLD");
Date date = new Date(1525381190 * 1000L);
    SimpleDateFormat dateFormatCN = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ", locale);

 //Output : 2018-05-03T01:59:50-0700

2 个答案:

答案 0 :(得分:1)

  

这是转换的核心方式

不,不是。我看到了以下问题。

  • 整个事情是不可能的,因为许多国家跨越几个时区。这意味着,从国家/地区代码中您无法知道要选择的时区。由于当地时间因时区而异,因此在这些情况下无法打印正确的时间。跨越多个时区的国家包括但不限于加拿大,美国,墨西哥,格陵兰,巴西,厄瓜多尔,俄罗斯,印度尼西亚,基里巴斯 - 甚至荷兰,您的示例国家。请注意,人口最多的一些国家/地区位于列表中,因此,如果您的数据代表了世界人口,那么您可能经常会遇到此问题。请参阅this list: List of time zones by country
  • 区域设置和时区是两个不同的东西,虽然或多或少都与地方无关,但没有任何直接关系。因此,获取正确的区域设置对您没有帮助。您还可以看到您的打印输出具有UTC偏移-0700,其中夏季阿姆斯特丹的正确偏移量为+0200。
  • {[TextQuestion, DropDown, Checkbox].map((Component, i) => <Component key={i} questionInfo={...} />} 不会为您提供荷兰的有效区域设置。 new Locale("NLD")构造函数的参数是一个语言标记,如荷兰语为Locale(String),英语为nl。三个字母的国家/地区代码无效。
  • 因此,如果您只想做一些您要问的工作,您需要访问一些可以将国家/地区代码转换为国家/地区和国家/地区的数据库或数据库。我不知道这里有一个好的选择,但我希望有一些这样的数据库可用。

java.time

最后,请勿使用enSimpleDateFormat。这些课程已经过时且设计不佳。为荷兰大陆格式化您的纪元时间戳值的现代正确方法是:

Date

打印:

  

2018-05-03T19:57:15 + 02:00

如果您需要 ZoneId zone = ZoneId.of("Europe/Amsterdam"); String nldTime = Instant.ofEpochSecond(1_525_370_235L) .atZone(zone) .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); System.out.println(nldTime); 中没有冒号的偏移量,请使用+0200

如果您想在荷兰的加勒比海地区找到阿姆斯特丹,请使用America / Kralendijk时区。然后结果是DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXX")

答案 1 :(得分:-1)

iso格式https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3中没有实际的Oracle时区。

所以,我建议您在ISO区域和Oracle时区之间进行映射https://www.mkyong.com/java/java-display-list-of-timezone-with-gmt/

所以,我的问题解决方案如下:

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class IsoToOracleDate {

static Map<String, String> timezones = new HashMap<String, String>(){{
   put("NLD","Europe/Amsterdam");
   put("RUS","Europe/Moscow");
   put("USA","America/New_York");
}};

public static void main(String[] args) {
    String zone = timezones.get("NLD");
    ZoneId zoneId = ZoneId.of(zone);
    long epochMilli = 1525370235 * 1000L;
    LocalDateTime dt = Instant.ofEpochMilli(epochMilli).atZone(zoneId).toLocalDateTime();
    ZonedDateTime zdt = ZonedDateTime.of(dt, zoneId);
    System.out.println(zdt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
}

输出:

  

2018-05-03T19:57:15 + 02:00

您有 timezones 变量中的时区映射。

从映射 ZoneId zoneId = ZoneId.of(zone);

创建ZoneId(oracle)

根据您的区域从 epochMilli 创建LocalDateTime dt 并将其转换为ZonedDateTime zdt

然后使用预定义格式DateTimeFormatter.ISO_OFFSET_DATE_TIME

格式化 zdt