在 EST 中设置日期 - Android

set date in EST - Android

我们的想法是构建一个事件(自定义 class 事件),用户可以在其中写下他希望事件发生的时间(以小时和分钟为单位)以及 select 来自 calendarView 的日期. 所以我得到他从视图中选择的日期和他希望事件开始的时间并将它们放入事件对象中。问题是,当我创建它时,它会将日期设置为 GMT-3(我的默认值),但我希望日期为 EST。由于该应用程序将主要由使用 EST 格式的人使用,如果我创建事件,它将为他们显示错误,反之亦然,如果我想为这些事件设置通知,它们将是不正确的。 有没有办法在 EST 中创建日期?

这样,如果他们在 EST 中创建一个日期并且我从我的 phone 中读取它,它会显示在我的时区中,不是吗?

tl;博士

捕获输入。

Instant instant = 
    OffsetDateTime.of( LocalDate.of( 2016 , 1 , 2 ) , 
                       LocalTime.of( 12 , 34 , 56 ) , 
                       ZoneOffset.ofHours( -3 ) 
                     )
                  .toInstant() ;

使用任何 Locale.

在任何时区生成用于演示的输出
String output = 
    instant.atZone( ZoneId.of( "Pacific/Auckland" ) )
           .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
                                     .withLocale( Locale.CANADA_FRENCH ) 
                  ) ;

使用正确的时区名称

指定 proper time zone name。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

偏移量与时区

一个offset-from-UTC is a number of hours and minutes and seconds different from UTC that a particular locality of people use in setting the time on their clocks, the wall-clock time.

一个时区是一个偏移加上一套处理异常的规则

所以 GMT-3 不是 您的时区,它是您的偏移量。您的时区可能是 America/Buenos_Aires, Antarctica/Rothera 等。

由于时区提供更多信息和更多功能,因此始终优先使用时区而不是单纯的偏移量。

提示:始终写出一个偏移量 填充零 并且 小时和分钟 以冒号分隔。 ISO 8601 标准允许其他变体,但有时在各种协议或软件系统中不受支持。所以使用 -03:00 而不是 -3.

避免遗留日期时间 类

不要使用与 Java 的最早版本捆绑在一起的臭名昭著的旧遗留 类。避免 java.util.Datejava.util.CalendarSimpleDateFormat 等。现在被 java.time 类.

取代

LocalDate & LocalTime

java.time 中的 LocalDateLocalTime 类型表示仅日期或仅时间值,并且没有时区。使用这些从您的小部件收集数据。 “本地”表示“未分区”,缺少偏移量或时区含义。

LocalDate ld = LocalDate.of( 2016 , 1 , 2 );
LocalTime lt = LocalTime.of( 12 , 34 , 56 );

OffsetDateTime

如果我们只有三个小时的偏移量而不是完整时区,请将 LocalDateLocalTime 对解释为具有 [=59] 的 OffsetDateTime 对象=]对象。

ZoneOffset offset = ZoneOffset.ofHours( -3 );
OffsetDateTime odt = OffsetDateTime.of( ld , lt , offset );

ZonedDateTime

如果我们确实有一个时区,请应用 ZoneId 以获得 ZonedDateTime

ZoneId z = ZoneId.of( "America/Buenos_Aires" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );

Instant

在 UTC 中执行大部分业务逻辑、数据存储和数据交换。仅在需要时应用偏移量或时区,例如向用户展示。

Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds

您可以从其他类型中提取一个 Instant 对象。

Instant instant = zdt.toInstant();

将时间调整到您可能需要的任何其他时区。

ZonedDateTime zdtNewYork = instant.atZone( ZoneId.of( "America/New_York" ) );
ZonedDateTime zdtParis = instant.atZone( ZoneId.of( "Europe/Paris" ) );
ZonedDateTime zdtAuckland = instant.atZone( ZoneId.of( "Pacific/Auckland" ) );

这些对象都代表同一时刻,时间轴上的同一点。它们的不同之处仅在于我们通过每个地方的镜头观看同一时刻 wall-clock time.

字符串

请记住,字符串不是日期时间值;它们是日期时间值文本的表示

所以一个日期时间对象可以生成一个你想要的任何格式的字符串。您可以指定自定义格式。但一般最好让java.time自动为你localize

要本地化,请指定:

  • FormatStyle 确定字符串的长度或缩写。
  • Locale 以确定 (a) 用于翻译日期名称、月份名称等的人类语言,以及 (b) 决定缩写、大写、标点符号等问题的文化规范.

示例:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );

注意Locale与时区正交,完全无关。您可以使用法语表示 Pacific/Auckland 分区值,或使用印度语表示 Europe/Copenhagen 分区值。

关于java.time

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

Joda-Time project, now in maintenance mode,建议迁移到java.time。

要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 中搜索许多示例和解释。

许多 java.time 功能被反向移植到 ThreeTen-Backport and further adapted to Android in ThreeTenABP (see 中的 Java 6 & 7)。

ThreeTen-Extra 项目扩展了 java.time 并增加了 类。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的 类,例如 IntervalYearWeekYearQuarter 等。