java - 我想在java中使用具有不同时区的字符串生成日期
问题描述
我的输入:2021-01-07T18:54:00.000 - UTC(TZ)
我的预期输出:
GMT +5:30 - 2021-01-08T00:24:00.000
GMT -12:00 - 2021-01-07T06:54: 00.000
Calendar calendar = Calendar.getInstance();
// This line is creating the calendar instance for the current day, I need to create calendar instance for the string which i receive from API
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
//Here you set to your timezone
sdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
String temp1 = sdf.format(calendar.getTime());
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(temp1, inputFormatter);
String formattedDate = outputFormatter.format(date);
System.out.println(formattedDate);
解决方案
我会退后一步,并建议其他可能更好的方法来做你的事情。我不了解您的大局,因此可能并非我的所有一般性建议都适用于您的情况和要求。但我认为他们很可能会这样做。
- 不要将日期和时间保留或处理为字符串。将它们作为
Instant
对象保存。当您接受字符串输入时,将其解析为Instant
. 仅当您需要提供字符串输出时,将您Instant
的转换ZonedDateTime
为适当时区的 a 并将其格式化为所需的字符串。 - 您的字符串采用 ISO 8601 格式,有利于数据交换。ISO 8601 还允许在字符串中使用 GMT 偏移量(UTC 偏移量)。我建议您和您与之通信的系统利用这种可能性来减少误解的风险。UTC 表示为
Z
,例如2021-01-07T18:54:00.000Z
。其他偏移量通常以+HH:MM
格式给出,例如2021-01-08T00:24:00.000+05:30
或2021-01-07T06:54:00.000-12:00
。 - 区分时区和与 UTC 或 GMT 的偏移量。在 Java 术语中,时区是地球上的一个地方,具有该地方的人们使用的历史、现在和已知的未来偏移量。由于偏移量在历史期间会发生变化,并且会在我们知道之前发生变化,因此对于时区中的人,使用他们的时区 ID 进行转换,而不是您认为上次检查时正确的 GMT 偏移量。以区域/城市格式指定时区,例如,
Asia/Kolkata
或Asia/Colombo
。 - 使用现代 Java 日期和时间 API java.time来处理所有日期和时间工作。
SimpleDateFormat
与您在问题中使用的旧类和您自己的答案、Calendar
和相比,使用它要好得多TimeZone
。它们设计得很糟糕,而且早已过时。你已经在使用java.time的DateTimeFormatter
路上了。就全力以赴。LocalDate
我猜这不是用户输入,因为虽然 ISO 8601 是人类可读的,但对于用户输入,您可能会得到一个更加用户友好的本地化格式。因此,我假设您从其他系统获得了 UTC 格式的 ISO 8601 字符串。转换成Instant
这样:
String sDate1="2021-01-05T00:00:00Z"; // The trailing Z means UTC
Instant inst = Instant.parse(sDate1);
System.out.println(inst);
到目前为止的输出是:
2021-01-05T00:00:00Z
请注意,我们不需要指定任何格式化程序。Instant
以 UTC 格式解析 ISO 8601 格式,尾随Z
就是这样。AnInstant
是独立于时区的时间点。
同样,我假设您需要在某个时区将字符串输出提供给另一个系统(可能是某个前端)。
ZoneId zone = ZoneId.of("Asia/Colombo");
String output = inst.atZone(zone)
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println(output);
2021-01-05T05:30:00+05:30
同样,我们不需要自己构建任何格式化程序。我只用了一个内置的。
链接
- 维基百科文章:ISO 8601
- Oracle 教程:日期时间解释如何使用 java.time。
- 政客如何改变时区偏移的最新示例:2018 年 4 月 29 日,朝鲜领导人金正恩宣布他的国家将返回 UTC+09:00,以重新调整与韩国的时钟。
推荐阅读
- excel - Vba:删除列表中未提及的excel表(列表仅包含数值)
- git - 在开发人员在 Azure 存储库中签入他/她的代码之前添加预提交检查的方法是什么
- database - 通过model_type和model_id多态多对多获取关系并对结果数据进行分页
- reactjs - 在数字海洋的反应应用程序中上传图像
- virtual-machine - 虚拟机,通过网络 USB 集线器模拟 USB
- interop - 请求票证系统是否有任何开放的导入/导出格式、DSL 或其他互操作性工具?
- flutter - 如何仅从一侧 FLUTTER 使上滑面板城市成为圆形
- python - 基于组内的对进行过滤
- sql - Redshift SQL Rolling SUM OVER last 3 ids by timestamp(每个 id 有多行)
- python - 以编程方式在 CircuitPython 中创建 digitalio.DigitalInOut 对象