如何设置java.util.Date的偏移量



我有一个日期作为字符串- 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

我怎样才能实现它?

您可以使用SimpleDateFormatsetTimeZone方法如下:

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);

br

ZonedDateTime zdt = 
    LocalDateTime.parse ( "15Sep20162040" , 
                          DateTimeFormatter.ofPattern ( "ddMMMyyyyHHmm" )
                                           .withLocale( Locale.English ) 
                        )
                 .atZone ( ZoneId.of ( "America/Puerto_Rico" ) );

2016 - 09 - 15 - t20:40内(美国/Puerto_Rico)

zdt.atZone( ZoneId.of ( "Pacific/Auckland" ) )  // Same moment viewed through different wall-clock time

2016 - 09 - 16 - t12:40 + 12点(太平洋/奥克兰)

使用java.time

避免麻烦的旧日期时间类,现在被java取代。时间类。

定义一个格式化模式来匹配你的输入字符串。

String input = "15Sep20162040";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "ddMMMyyyyHHmm" ).withLocale ( Locale.ENGLISH );
顺便说一下,对于日期-时间字符串来说,这是一个糟糕的格式。它以英文为假名,滥用英文,使用不正确的月名缩写,令人困惑和模棱两可。相反,在将日期-时间值序列化为文本时,使用标准的ISO 8601格式。 <标题> Un-zoned h1> 输入字符串解析为LocalDateTime,因为它缺少关于utc或时区偏移的任何信息。
LocalDateTime ldt = LocalDateTime.parse ( input , f );

请理解,如果没有偏移量或时区,这个LocalDateTime对象没有实际意义。它代表了许多可能的时刻,但不是时间线上的特定点。例如,新西兰奥克兰的中午和印度加尔各答的中午是不同的,而印度加尔各答的中午比法国巴黎的中午早。

指定offset-from-UTC

你指出这个日期时间是一个与UTC相差4小时的时刻,比UTC(-04:00)晚。因此,接下来我们应用ZoneOffset来获得OffsetDateTime对象。

提示:在您的offset-from-UTC字符串中始终包含冒号、分钟和填充零。虽然ISO 8601标准没有要求,但通用软件库和协议期望更完整的格式。

ZoneOffset offset = ZoneOffset.ofHours( -4 ); 
OffsetDateTime odt = ldt.atOffset( offset );

指定时区

如果根据上下文,您知道时区而不仅仅是偏移量,那么使用ZoneId来实例化ZonedDateTime对象。时区是一个偏移量加上一组处理异常(如夏令时)的规则。

请按照continent/region的格式指定合适的时区名称。永远不要使用3-4个字母的缩写,如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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 );

转储到控制台。

input: 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[Asia/Kolkata] | zdtAuckland: 2016-09-16T12:40+12:00[Pacific/Auckland]

关于java.time

java。时间框架内置于Java 8及以后版本中。这些类取代了麻烦的旧日期时间类,如java.util.Date, .Calendar, &java.text.SimpleDateFormat

Joda-Time项目,现在处于维护模式,建议迁移到java.time.

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获得许多示例和解释。

大部分java。时间功能向后移植到Java 6;7在ThreeTen-Backport和进一步适应Android在ThreeTenABP(见如何使用…)。

three - ten - extra项目扩展了java。有额外课程的时间。这个项目是将来可能添加到java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

最新更新