我正在尝试将日期转换为以下时区,但结果并不像预期的那样 - 我得到的要求是说例如从PMST到EST的转换输出应该少2小时。
PMST,NST,AST,EST,CST,MST,PST,AKST,HAST
String inputDate = "2017/04/30 08:10";
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
LocalDateTime local = LocalDateTime.parse(inputDate, sourceFormatter);
ZonedDateTime zoned = local.atZone(TimeZone.getTimeZone("PMST").toZoneId());
ZonedDateTime requiredZone = zoned.withZoneSameInstant(TimeZone.getTimeZone("EST").toZoneId());
System.out.println(requiredZone);
输出 - 2017-04-30T03:10-05:00
所以你知道你的输入“本地日期”是在PMST时区。
String localDateTimeString = "2017/04/30 08:10";
但是你应该注意到上面没有你所知道的时区信息。因此,您需要将该信息添加到String中。
但我们现在所拥有的只是一个String
,所以首先我们必须决定我们将使用的日期时间格式,它必须是TimeZone意识到的,
DateTimeFormatter dateTimeWithZoneFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm Z");
这里,Z
表示TimeZone偏移量。我们知道PMST
是UTC-0300
,所以我们需要将这些信息添加到我们的本地时间字符串中,
String dateTimeString = "2017/04/30 08:10" + " -0300";
现在,我们可以使用我们的日期时间格式器来读取它,
ZonedDateTime dateTimeInPMST = ZonedDateTime.parse(dateTimeString, dateTimeWithZoneFormatter);
而且,现在我们可以在任何我们想要的时区获取日期,
ZonedDateTime dateTimeInEST = dateTimeInPMST.withZoneSameInstant(TimeZone.getTimeZone("EST").toZoneId());
编辑1 ::
获取时区的偏移量(比如EST
)
int offsetInSeconds = TimeZone.getTimeZone("EST").getRawOffset() / 1000;
ZoneOffset zoneOffset = ZoneOffset.ofTotalSeconds(offsetInSeconds);
String zoneOffsetString = zoneOffset.toString();
// "-05:30"
请注意:
中的-05:30
,我们将不得不改变我们的DateTimeFormat
以适应这种情况,
DateTimeFormatter dateTimeWithZoneFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm ZZZ");
现在,您可以将其添加到任何dateTimeString,
public String makeOffsetAwareDateTimeString(String dateTimeString, String timezone) {
int offsetInSeconds = TimeZone.getTimeZone(timezone).getRawOffset() / 1000;
ZoneOffset zoneOffset = ZoneOffset.ofTotalSeconds(offsetInSeconds);
String zoneOffsetString = zoneOffset.toString();
return dateTimeString + " " + zoneOffsetString;
}
这适合我。修改需要哪个区域。
public class ZonedDateTime {
private static final String DATE_FORMAT = "dd/M/yyyy hh:mm:ss a";
public static void main(String[] args) {
String dateInString = "26/12/2017 10:15:55 AM";
LocalDateTime ldt = LocalDateTime.parse(dateInString, DateTimeFormatter.ofPattern(DATE_FORMAT));
ZoneId newYokZoneId = ZoneId.of("America/New_York");
ZonedDateTime nyDateTime =ldt.atZone(newYokZoneId);
System.out.println("Date (New York) : " + nyDateTime);
DateTimeFormatter format = DateTimeFormatter.ofPattern(DATE_FORMAT);
System.out.println("Date (New York) : " + format.format(nyDateTime));
}
}
使用此查找所有区域。
TreeSet<String> sortedZones = new TreeSet<>(ZoneId.getAvailableZoneIds());
for (String zone : sortedZones) {
System.out.println(zone);
}
切勿使用媒体中常见的3-4个字母缩写,例如CST
,IST
和EST
。这些不是真正的时区,不是标准化的,甚至不是唯一的(!)。
continent/region
相反,确定您想要的真实时区。 Time zones have names格式为continent/region
,如America/Montreal
和Africa/Casablanca
以及Pacific/Auckland
。
改变您的输入以符合ISO 8601标准格式。
String input = "2017/04/30 08:10".replace( " " , "T" ) ;
解析为LocalDateTime
,因为您的输入缺少从UTC或时区偏移的指示。
LocalDateTime ldt = LocalDateTime.parse( input ) ;
如果您确定它是用于此输入,请应用时区。
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.withZoneSameInstant( z ) ;