[英]How to set offset of a java.util.Date?
我有一个日期作为字符串15Sep20162040
,我必须将其格式化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
,则输出应类似于: 2016-09-15T20:40:00-0200
。
我该如何实现?
您可以使用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);
希望这可以帮助。
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
因为它缺少有关自UTC偏移或时区的任何信息。
LocalDateTime ldt = LocalDateTime.parse ( input , f );
请理解,没有偏移量或时区,此LocalDateTime
对象没有实际意义。 它代表许多可能的时刻,但不是时间轴上的特定点。 例如,新西兰奥克兰的中午不同于印度加尔各答的中午,这比法国巴黎的中午要早。
您指示此日期时间是一个相对于UTC偏移 UTC(-04:00)四个小时的时刻。 因此,接下来我们应用ZoneOffset
来获取OffsetDateTime
对象。
提示:始终在与UTC偏移的字符串中包含冒号,分钟和填充零。 尽管ISO 8601标准没有要求,但通用软件库和协议要求更完整的格式。
ZoneOffset offset = ZoneOffset.ofHours( -4 );
OffsetDateTime odt = ldt.atOffset( offset );
如果根据您的上下文,您知道的是时区而不是单纯的偏移量,请使用ZoneId
实例化ZonedDateTime
对象。 时区是一个偏移量以及一组用于处理异常的规则,例如夏令时(DST) 。
请以continent/region
的格式指定正确的时区名称 。 切勿使用EST
或IST
等3-4个字母的缩写,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Puerto_Rico" );
ZonedDateTime zdt = ldt.atZone( z );
关于更改偏移量,您的问题在年底时还不清楚。 如果您的目标是通过各个时区的各个镜头查看日期时间,则可以通过创建新的ZonedDateTime
对象轻松进行调整。 为每个分配不同的时区。
请注意,所有这些日期时间对象(zdt,zKolkata和zAuckland)都表示同一时刻,时间轴上的同一点。 每个代表不同的挂钟时间,但同时出现相同的时刻 。
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 [美国/波多黎各] | zdtKolkata 2016-09-16T06:10 + 05:30 [亚洲/加尔各答] | zdtAuckland:2016-09-16T12:40 + 12:00 [Pacific / Auckland]
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧日期时间类,例如java.util.Date
, .Calendar
和java.text.SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time。
要了解更多信息,请参见Oracle教程 。 并在Stack Overflow中搜索许多示例和说明。
大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,并进一步适应的Android在ThreeTenABP (见如何使用...... )。
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.