我有一个日期作为字符串 - 15Sep20162040
,我必须将其格式化为另一种格式,时区为2016-09-15T20:40:00+0400
。
我做了如下操作:
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class DateFormatExample {
private static SimpleDateFormat offsetDateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZ");
private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
"ddMMMyyyyHHmm");
public static void main(String[] args) throws ParseException {
String date = "15Sep20162040";
String result = offsetDateFormat.format(dateFormatter.parse(date));
System.out.println(result); // 2016-09-15T20:40:00+0400
}
}
现在,我必须根据时区差异修改输出,例如,如果差异为+0100
,则输出应类似于:2016-09-15T20:40:00+0100
,如果差异为-0200
,则输出应类似as:2016-09-15T20:40:00-0200
。
我怎样才能实现它?
答案 0 :(得分:4)
您可以使用SimpleDateFormat
setTimeZone
方法,如下所示:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class DateFormatExample {
private static SimpleDateFormat offsetDateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZ");
private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
"ddMMMyyyyHHmm");
public static void main(String[] args) throws ParseException {
String date = "15Sep20162040";
String result = offsetDateFormat.format(dateFormatter.parse(date));
System.out.println(result); // 2016-09-15T20:40:00+0400
offsetDateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8:00"));
result = offsetDateFormat.format(dateFormatter.parse(date));
System.out.println(result);
}
}
如果您只是想在result
结束时更改时区,请尝试以下操作:
String offset = "GMT-8:00";
String date = "15Sep20162040";
date = date+" "+offset;
SimpleDateFormat dateFormatter2 = new SimpleDateFormat("ddMMMyyyyHHmm Z");
SimpleDateFormat offsetDateFormat2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
offsetDateFormat2.setTimeZone(TimeZone.getTimeZone(offset));
String result = offsetDateFormat2.format(dateFormatter2.parse(date));
System.out.println(result);
希望这有帮助。
答案 1 :(得分:2)
ZonedDateTime zdt =
LocalDateTime.parse ( "15Sep20162040" ,
DateTimeFormatter.ofPattern ( "ddMMMyyyyHHmm" )
.withLocale( Locale.English )
)
.atZone ( ZoneId.of ( "America/Puerto_Rico" ) );
2016-09-15T20:40-04:00 [美国/波多黎各]
zdt.atZone( ZoneId.of ( "Pacific/Auckland" ) ) // Same moment viewed through different wall-clock time
2016-09-16T12:40 + 12:00 [太平洋/奥克兰]
避免使用麻烦的旧日期时间类,现在由java.time类取代。
定义格式化模式以匹配您的输入字符串。
String input = "15Sep20162040";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "ddMMMyyyyHHmm" ).withLocale ( Locale.ENGLISH );
顺便说一句,这是一个日期时间字符串的可怕格式。它假设英语,滥用英语,月份名称的缩写不正确,并且令人困惑和含糊不清。而是在将日期时间值序列化为文本时使用标准ISO 8601格式。
将输入字符串解析为LocalDateTime
,因为它缺少有关offset-from-UTC或时区的任何信息。
LocalDateTime ldt = LocalDateTime.parse ( input , f );
了解没有偏移或时区,此LocalDateTime
对象没有实际意义。它代表了许多可能的时刻,但不是时间轴上的特定点。例如,新西兰奥克兰的中午与加尔各答印度的中午时差不同,这是法国巴黎的中午时刻。
您指明此日期时间是UTC时间后{4}小于offset-from-UTC的时刻(-04:00)。接下来,我们应用ZoneOffset
来获取OffsetDateTime
对象。
提示:始终在您的offset-from-UTC字符串中包含冒号和分钟以及填充零。虽然ISO 8601标准不要求,但通用软件库和协议期望更全面的格式化。
ZoneOffset offset = ZoneOffset.ofHours( -4 );
OffsetDateTime odt = ldt.atOffset( offset );
如果在您的上下文中您知道时区而不仅仅是偏移量,请使用ZoneId
来实例化ZonedDateTime
对象。时区是偏移量加上用于处理Daylight Saving Time (DST)等异常的一组规则。
以continent/region
的格式指定proper time zone name。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Puerto_Rico" );
ZonedDateTime zdt = ldt.atZone( z );
关于更改补偿,你的问题最近还不清楚。如果您的目标是通过各个时区的各种镜头查看日期时间,则可以通过创建新的ZonedDateTime
对象轻松进行调整。为每个时区分配不同的时区。
请注意,所有这些日期时间对象(zdt,zKolkata和zAuckland)代表同一时刻,即时间轴上的相同点。每个呈现不同的wall-clock time,但相同的同时时刻。
ZoneId zKolkata = ZoneId.of ( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant ( zKolkata );
ZoneId zAuckland = ZoneId.of ( "Pacific/Auckland" );
ZonedDateTime zdtAuckland = zdt.withZoneSameInstant ( zAuckland );
System.out.println ( "input: " + input + " | ldt: " + ldt + " | odt: " + odt + " | zdt: " + zdt + " | zdtKolkata " + zdtKolkata + " | zdtAuckland: " + zdtAuckland );
转储到控制台。
输入:15Sep20162040 | ldt:2016-09-15T20:40 | odt:2016-09-15T20:40-04:00 | zdt:2016-09-15T20:40-04:00 [America / Puerto_Rico] | zdtKolkata 2016-09-16T06:10 + 05:30 [亚洲/加尔各答] | zdtAuckland:2016-09-16T12:40 + 12:00 [太平洋/奥克兰]
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
。
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。
大部分java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP(见How to use…)。
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
等。