首页 文章

DateFormat格式方法不会向特定TimeZone显示已解析的日期

提问于
浏览
1

我通过SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(DateinString)将日期字符串转换为Date .
这里不是转换为UTC而是转换为我的本地TimeZone . 我通过DateFormat的格式化方法显示这个解析日期来检查它 .

所以我必须重新格式化回UTC.Now当我试图通过相同的格式方法将此解析日期显示给UTC TimeZone时,它仍然显示在本地TimeZone中 . 以下是我将解析日期格式化为UTC的代码

Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTime(alreadyParsedDateTime); // 
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(cal.getTime()));

我的示例日期字符串是"2015-12-23T15:00:00-0800"
解析后--readyParsedDateTime.toString():: Thu Dec 24 04:30:00 IST 2015
解析后 - System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss") . format(alreadyParsedDateTime)):: 2015-12-24T04:30:00

在上面提到的重新格式化解析日期为UTC - System.out.println(new SimpleDateFormat(“yyyy-MM-dd'T'HH:mm:ss”) . format(cal.getTime())): :2015-12-24T04:30:00

预计日期格式为:: 2015-12-23T23:00:00

我不知道为什么格式方法不能以预期的方式工作或者有任何技巧可以做同样的事情 . 请帮忙..

2 回答

  • 0

    tl;博士

    UTC中的当前时刻 .

    Instant.now()        // Capture current moment in UTC.
        .toString()      // Generate string in standard ISO 8601 format.
    

    2018-02-11T22:13:28.650328Z

    调整到另一个时区 .

    instant.atZone(      // Apply a `ZoneId` to `Instant` object to get a `ZonedDateTime` object.
        ZoneId.of( "Pacific/Auckland" )
    ).toString()
    

    2018-02-12T11:13:28.650328 13:00 [太平洋/奥克兰]

    或者将当前时刻直接捕捉到该区域 .

    ZonedDateTime.now(   // Capture current moment as seen on the wall-clock time of the people in a particular region.
        ZoneId.of( "Pacific/Auckland" )
    ).toString()         // Generate string in standard ISO 8601 format, wisely extended by appending the name of the time zone in square brackets.
    

    2018-02-12T11:13:28.650328 13:00 [太平洋/奥克兰]

    详情

    Answer by Grodriguez是正确但过时的 .

    java.time

    现代方法使用java.time类来取代麻烦的旧遗留日期时间类 .

    您的输入字符串符合ISO 8601格式标准 . 在解析/生成字符串时,java.time类默认使用这些格式 . 因此无需指定格式化模式 .

    Instant类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分的最多九(9)位数) .

    捕获UTC中的当前时刻 .

    Instant instant = Instant.now() ;  // Current moment in UTC.
    

    要通过另一个区域(时区)的人使用的挂钟时间镜头查看同一时刻,请应用ZoneId以获取ZonedDateTime对象 .

    ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
    ZonedDateTime zdt = instant.atZone( z ) ;
    

    请注意,我们在这里使用智能对象,而不是愚蠢的字符串 . 不要将日期时间对象与仅以文本方式表示其值的字符串混淆 .

    如果要生成标准ISO 8601格式的String,请调用 toString 方法 .

    String outputA = instant.toString() ;
    String outputB = zdt.toString() ;
    

    要生成其他格式的字符串,请使用DateTimeFormatterDateTimeFormatterBuilder 类 . Stack Overflow上都广泛介绍了这两者,因此请搜索更多信息 .


    关于java.time

    java.time框架内置于Java 8及更高版本中 . 这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat .

    现在位于maintenance modeJoda-Time项目建议迁移到java.time类 .

    要了解更多信息,请参阅Oracle Tutorial . 并搜索Stack Overflow以获取许多示例和解释 . 规格是JSR 310 .

    如果JDBC driver符合JDBC 4.2或更高版本,则可以直接与数据库交换java.time对象 . 不需要字符串或java.sql . *类 .

    从哪里获取java.time类?

    ThreeTen-Extra项目使用其他类扩展了java.time . 该项目是未来可能添加到java.time的试验场 . 您可以在此处找到一些有用的类,例如IntervalYearWeekYearQuartermore .

  • 2

    这里有两个不同的主题;解析和格式化 .

    1.解析

    SimpleDateFormat.parse() 将尝试从提供的日期字符串中解析时区 . 如果要解析的日期字符串不包含显式时区,则将使用 SimpleDateFormat 对象上的"default"时区 . 您可以使用 setTimeZone() 方法设置默认时区 . 请参阅SimpleDateFormat.parse()DateFormat.setTimeZone()的API文档以供参考 .

    下面是一个示例,显示解析如何受 setTimeZone() 设置的时区影响:

    String dateString = "2015.12.10 13:58:18";
    
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        sdf1.setTimeZone(TimeZone.getTimeZone("GMT"));
        Date date1 = sdf1.parse(dateString);
    
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        sdf2.setTimeZone(TimeZone.getTimeZone("EST"));
        Date date2 = sdf2.parse(dateString);
    
        // Shows that the parsing honours time zone -- will print:
        // Thu Dec 10 14:58:18 CET 2015 (original date was parsed as GMT)
        // Thu Dec 10 19:58:18 CET 2015 (original date was parsed as EST)
        System.out.println(date1);
        System.out.println(date2);
    

    2.格式化

    假设日期已被正确解析,那么问题在于格式化 . 您需要为用于格式化的实际 SimpleDateFormat 对象设置时区 . 我修改了你的代码来执行此操作,现在它将打印出你所使用的内容:

    Calendar cal = Calendar.getInstance();
        cal.setTime(alreadyParsedDateTime);
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        sdf3.setTimeZone(TimeZone.getTimeZone("UTC"));
    
        // Prints: 2015-12-23T23:00:00 for your example date string
        System.out.println(sdf3.format(cal.getTime()));
    

相关问题