在我的 Node JS
服务器上使用 moment.js
库:
moment().utc().format("YYYY-MM-DD HH:mm:ss.SSS")
我得到的当前时间字符串为:
2017-08-02 11:57:52.616Z
在 Android 上,我使用了以下代码。
Date myDate = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(myDate);
Date time = calendar.getTime();
SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String dateAsString = outputFmt.format(time);
输出是:
2017-08-02 22:58:46.163Z
我该如何解决这个问题?时差似乎在 11 小时左右。
最佳答案
如果您想要 UTC 格式的当前日期,您必须在 SimpleDateFormat
上设置时区,而不是在 Calendar
上。而且你不需要创建一个Calendar
,你可以直接使用一个Date
:
SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateAsString = outputFmt.format(new Date()); // current date/time
上面的 X
模式是在 JDK 7 中引入的,因此如果您使用的是 JDK <= 6,则必须放置文字 Z
:
SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateAsString = outputFmt.format(new Date());
首先尝试使用 X
,因为最好输出正确的时区而不是硬编码的 Z
(因为如果您将时区更改为另一个时区, Z
将是错误的,因为它使用了 only when the date/time is in UTC )。
旧类(Date
、Calendar
和SimpleDateFormat
)有lots of problems和 design issues ,并且它们正在被新的 API 取代。
对于 Android,您可以使用 ThreeTen Backport ,Java 8 的新日期/时间类的一个很好的反向移植。您还需要 ThreeTenABP让它工作(更多关于如何使用它的信息 here )。
如果你想要 UTC 的当前日期,你可以使用 org.threeten.bp.Instant
类(代表一个 UTC 时刻):
String dateAsString = Instant.now().toString();
dateAsString
变量的值将类似于 2017-08-02T19:21:22.271Z
。
如果您只使用 UTC 值,Instant
类就足够了。但是,如果您想使用其他时区,则必须使用 org.threeten.bp.ZonedDateTime
:
// current time in UTC
dateAsString = ZonedDateTime.now(ZoneOffset.UTC).toString();
// current time in another timezone
dateAsString = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")).toString();
第二种情况将产生不同的输出(例如 2017-08-03T01:05:06.631+05:30[Asia/Kolkata]
),因为它使用的时区不是 UTC。不过,您可以使用 org.threeten.bp.format.DateTimeFormatter
更改它:
DateTimeFormatter fmt = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
dateAsString = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")).format(fmt);
这将导致 2017-08-03T01:06:19.131+05:30
。您还可以使用 DateTimeFormatter.ofPattern("pattern")
创建另一种格式,将 pattern
替换为相应的模式字母(check the javadoc 了解更多详细信息)。
请注意,他的 API 使用 IANA timezones names (始终采用 Region/City
格式,例如 Asia/Kolkata
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 IST
),因为它们是 ambiguous and not standard .
您可以通过调用 ZoneId.getAvailableZoneIds()
获取可用时区列表(并选择最适合您系统的时区)。
您还可以通过 ZoneId.systemDefault()
使用系统的默认时区,但这可以在不通知的情况下更改,即使在运行时也是如此,因此最好明确使用特定的时区。
关于android - UTC 时间不匹配 - Java 与 Node JS 上的 Moment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45467513/