首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将时区通过DateTimeFormatter传递到DateTimeFormatterBuilder时是否丢失?

将时区通过DateTimeFormatter传递到DateTimeFormatterBuilder时是否丢失?
EN

Stack Overflow用户
提问于 2016-01-15 21:19:57
回答 1查看 361关注 0票数 0

我需要使用几种日期格式来解析一个日期,假设一个特定的时区,然后将它输出到另一个时区(即UTC)。我本来希望DateTimeFormatterBuilder能帮上忙,但似乎解析器和打印机上附加的时区信息丢失了/被忽略了吗?

见测试和输出:

代码语言:javascript
复制
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import org.junit.Test;

public class JodaBuilderTest {


@Test
public void aTestOfTimeZoneRetentionOfFormattersPassedToBuilder() throws    Exception {     

    String [] parsePatterns = new String [] { "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy" };
     String printPattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ";
     String inputString = "08/03/2015 01:01:01";

    DateTimeZone tz = DateTimeZone.forOffsetHours(-3);
    DateTimeParser[] parsers = new DateTimeParser[parsePatterns.length];
    for (int index = 0; index < parsePatterns.length; index++) {

        parsers[index] = DateTimeFormat.forPattern(parsePatterns[index]).withZone(tz).getParser();
    }
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
      .append(DateTimeFormat.forPattern(printPattern).withZoneUTC().getPrinter(), parsers);
    DateTimeFormatter parser = builder.toFormatter();

    DateTimeZone parserdtz = parser.getZone();
    System.out.println("parserdtz: " + parserdtz);
    DateTime dt = parser.parseDateTime(inputString);
    System.out.println("parser zone is " + dt.getZone());
    String dtout = dt.toString();
    System.out.println("expecting UTC-3: 2015-08-03T01:01:01.000-03:00");
    System.out.println("got:\t\t" + dtout);
    String dtoutFmt = dt.toString(parser);
    System.out.println("expecting UTC: 2015-08-03T04:01:01.000-00:00");
    System.out.println("got:\t\t" + dtoutFmt);
    org.junit.Assert.assertEquals("2015-08-03T04:01:01.000-00:00", dtoutFmt);

}
}

输出如下

代码语言:javascript
复制
parserdtz: null
parser zone is America/New_York
expecting UTC-3: 2015-08-03T01:01:01.000-03:00
got:        2015-08-03T01:01:01.000-04:00
expecting UTC: 2015-08-03T04:01:01.000-00:00
got:        2015-08-03T01:01:01.000-04:00

因此,它似乎忽略了解析器上的UTC-3集和打印机上的UTC集,并默认为系统区域(EDT)。我是错过了什么,还是这是我所期待的行为?我唯一的办法就是不使用建筑商吗?我也不能在parser上设置区域,即DateTimeFormatter parser = builder.toFormatter().withZone(DateTimeZone.forOffsetHours(-3));,因为这将覆盖打印机。我想我可以为打印机创建一个单独的格式化程序,但是打印机参数对生成器的作用是什么呢?我应该把它设置为空吗?感觉不太对劲。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-22 14:23:06

以下是一些澄清:

DateTimeParserDateTimePrinter实例根据特定的格式模式解析/打印DateTime。但是,时区和区域设置不是打印机/解析器实例的一部分。它们是在运行时提供的,以个案为基础。见DateTimePrinter.printTo的签名

代码语言:javascript
复制
void printTo(StringBuffer buf,
             long instant,
             Chronology chrono,
             int displayOffset,
             DateTimeZone displayZone, // zone provided at runtime
             Locale locale)

至于打印机-它可以读取任何时区,所以用一个不相关的配置它。

请记住来自DateTimePrinter/Parser javadocs的片段:

用于创建/解析日期时间文本表示的内部接口。

因此,打印机/解析器本身没有内部设置的时区。您可以删除打印机/解析器上的withZone(tz)/withZoneUTC()配置,因为它们无论如何都不会更改任何内容。

然而,DateTimeFormatter已经做到了。当涉及时区时,这是您应该使用的顶级API。如果在格式化程序上设置时区X,它将能够读取任何时区字符串,但是创建的DateTime实例将被转换为时区X。同样,当打印任何DateTime实例(在任何时区中)时,它将被打印为转换为时区X。如果确实试图将字符串解析为-03:00时区,则需要一个DateTimeFormatter实例,当您想要在UTC中打印它时,需要一个不同的格式化程序实例。

因此,拥有原始的formatter (从parser重命名),您可以这样做

代码语言:javascript
复制
DateTime dt = formatter.withZone(DateTimeZone.forID("-03:00")).parseDateTime(inputString);

和印刷方面:

代码语言:javascript
复制
String dtoutFmt = dt.toString(formatter.withZoneUTC());

我确信,如果您对变量使用了相关的名称--使用formatter作为DateTimeFormatter实例,以避免与实际DateTimeParser的混淆,这会更加清楚一些。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34820021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档