简体   繁体   English

在 Android Studio 中使用 Java 的日期格式的正确方法是什么?

[英]Which is the correct way to use Java's date formats in Android Studio?

I am trying to build a chat app and I want to store date for every message in Firebase RealTime-Database using ServerValue.TIMESTAMP which stores date and time in milliseconds and it is server sided.我正在尝试构建一个聊天应用程序,我想使用ServerValue.TIMESTAMP在 Firebase RealTime-Database 中存储每条消息的日期,它以毫秒为单位存储日期和时间,并且它是服务器端的。 All I want to achieve is to convert milliseconds to a safe date format which will have a pattern like "Thursday, 11th November 2022, 14:42" but I read a lot of things about Java's unsafe date and format libraries.我想要实现的只是将毫秒转换为安全的日期格式,该格式将具有类似“2022 年 11 月 11 日,星期四,14:42”的模式,但我阅读了很多关于 Java 的不安全日期和格式库的内容。 My app uses FirebaseUI which is like an asynchronous way to observe/notify/listen to changes of my db so I need something that will be safe and supported from API/SDK level 21+我的应用程序使用 FirebaseUI,它就像一种异步方式来观察/通知/侦听我的数据库的变化,所以我需要一些安全的东西,并受到 API/SDK 级别 21+ 的支持

Here is my code that I currently have这是我目前拥有的代码

Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(model.sentOnDateInMilliseconds); String date = DateFormat.getDateInstance(DateFormat.FULL).format(calendar.getTime());

and I make attempts to preview the format that I want like this我尝试像这样预览我想要的格式

textView.setText(MessageFormat.format("{0} {1}:{2} {3}", date, calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.AM_PM)));

any suggestions?有什么建议么?

Avoid legacy classes避免遗留类

Never use SimpleDateFormat , Calendar , or either Date class. These legacy classes are terribly flawed with poor design decisions by people who did not understand date-time handling.切勿使用SimpleDateFormatCalendarDate class。这些遗留类存在严重缺陷,不了解日期时间处理的人做出糟糕的设计决定。

Their modern replacements are the java.time classes defined in JSR 310.它们的现代替代品是 JSR 310 中定义的java.time类。

java.time java.时间

You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.您正在使用多年前被 JSR 310 中定义的现代java.time类所取代的糟糕日期时间类。

Though not documented clearly , apparently a firebase.database.ServerValue.TIMESTAMP type represents a moment as a count of milliseconds since the epoch reference of the first moment of 1970 in UTC , 1970-01-01T00:00:00Z.虽然没有明确记录,但显然firebase.database.ServerValue.TIMESTAMP类型表示自UTC 1970 年第一个时刻 1970-01-01T00:00:00Z 的纪元参考以来的毫秒数。

java.time.Instant

The matching class in Java is java.time.Instant . Java中匹配的class为java.time.Instant

Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;

You can extract that millisecond count from an Instant .您可以从Instant中提取毫秒计数。 Beware of data loss: A Instant has a resolution of nanoseconds, so getting a count of milliseconds ignores the microseconds/nanoseconds.当心数据丢失: Instant的分辨率为纳秒,因此获取毫秒数会忽略微秒/纳秒。

Instant instant = Instant.now() ;  // Capture the current moment as seen with an offset of zero hours-minutes-seconds from UTC.
long millisSinceEpoch = instant.toEpochMilli() ;

java.time.ZonedDateTime

convert milliseconds to a safe date format which will have a pattern like "Thursday, 11th November 2022, 14:42"将毫秒转换为安全的日期格式,其格式将类似于“2022 年 11 月 11 日,星期四,14:42”

To generate text in formats other than standard ISO 8601 , we need a class more flexible than Instant .要生成标准ISO 8601以外格式的文本,我们需要一个比Instant更灵活的 class 。 And we need to adjust that moment from an offset of zero hours-minutes-seconds from UTC to a time zone (or offset) expected by the user.我们需要将该时刻从 UTC 的零时分秒偏移量调整为用户期望的时区(或偏移量)。

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

java.time.format.DateTimeFormatter

To generate text, we must specify a format.要生成文本,我们必须指定一种格式。 You can hard-code a format, or you can let java.time automatically localize.您可以硬编码格式,也可以让java.time自动本地化。 To localize, we specify a Locale to determine the human language and cultural norms needed for localization such as name of day of week.为了本地化,我们指定了一个Locale来确定本地化所需的人类语言和文化规范,例如星期几的名称。

Locale locale = Locale.UK ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ).withLocale( locale ) ;
String output = zdt.format( f ) ;

Dump to console.转储到控制台。

System.out.println( "instant = " + instant );
System.out.println( "millisSinceEpoch = " + millisSinceEpoch );
System.out.println( "output = " + output );

When run.运行时。

instant = 2022-11-18T19:27:22.561715Z
millisSinceEpoch = 1668799642561
output = Saturday, November 19, 2022 at 4:27:22 AM Japan Standard Time

Android 26+ carries an implementation of the java.time classes. Android 26+ 实现了java.time类。 For earlier Android, the latest tooling provides access to most of the java.time functionality via “API desugaring”.对于早期的 Android,最新的工具通过“API 脱糖”提供了对大部分java.time功能的访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM