我想将这张GMT时间戳转换为格林威治标准时间13:
2011-10-06 03:35:05
我尝试过大约100种不同的DateFormat,TimeZone,Date,GregorianCalendar等组合来尝试做这个非常基本的任务 .
这段代码完成了我对CURRENT TIME的要求:
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));
String newZealandTime = formatter.format(calendar.getTime());
但我想要的是设定时间而不是使用当前时间 .
我发现任何时候我都尝试设置这样的时间:
calendar.setTime(new Date(1317816735000L));
使用本地机器的TimeZone . 这是为什么?我知道当“new Date()”返回UTC 0时间时,为什么当你设置Time以毫秒为单位时,它不再假设时间是UTC?
有可能:
-
设置对象的时间(日历/日期/时间标准)
-
(可能)设置初始时间戳的时区(calendar.setTimeZone(...))
-
使用新的TimeZone格式化时间戳(formatter.setTimeZone(...)))
-
返回具有新时区时间的字符串 . (formatter.format(calendar.getTime()))
在此先感谢您的帮助:D
14 回答
For me, the simplest way to do that is:
了解计算机时间的工作原理非常重要 . 有了这个说我同意,如果创建一个API来帮助您像实时一样处理计算机时间,那么它应该以允许您像实时一样对待它的方式工作 . 在大多数情况下都是这种情况,但有一些重要的疏忽需要注意 .
无论如何我离题!如果您有UTC偏移(最好在UTC中工作而不是GMT偏移),您可以计算时间(以毫秒为单位)并将其添加到时间戳中 . 请注意,SQL时间戳可能与Java时间戳不同,因为计算时间的过程并不总是相同的 - 这取决于数据库技术和操作系统 .
我建议您使用System.currentTimeMillis()作为时间戳,因为这些可以在java中更一致地处理,而不必担心将SQL时间戳转换为Java Date对象等 .
要计算您的偏移量,您可以尝试这样的事情:
我希望这是有帮助的!
与往常一样,我建议您阅读有关Java日期和时间的this article,以便您了解它 .
基本的想法是“在引擎盖下”,自纪元以来,一切都以UTC毫秒完成 . 这意味着如果您在不使用时区的情况下进行操作最简单,除了用户的字符串格式 .
因此,我会跳过你建议的大部分步骤 .
设置对象的时间(日期,日历等) .
在格式化程序对象上设置时区 .
从格式化程序返回一个字符串 .
或者,您可以使用Joda time . 我听说它是一个更直观的日期时间API .
tl;博士
如果输入
1317816735000L
...如果输入
2011-10-06 03:35:05
...java.time
问题和大多数答案使用最早版本的Java过时的旧日期时间类 . 事实证明,这些旧课程很麻烦,令人困惑 . 避免他们 . 而是使用java.time类 .
ISO 8601
您的输入字符串几乎是标准ISO 8601格式 . 只需用
T
替换中间的SPACE即可 .在解析/生成字符串时,java.time类默认使用这些标准格式 . 因此无需指定格式化模式 .
LocalDateTime
现在解析为LocalDateTime因为输入缺少有关UTC或时区偏移的任何信息 .
LocalDateTime
没有偏移或时区的概念,因此它不代表时间轴上的实际时刻 .ZoneOffset
您似乎在说,从业务环境中您知道此字符串的意图是表示比UTC早13个小时的时刻 . 所以我们实例化一个ZoneOffset .
OffsetDateTime
应用它来获取OffsetDateTime对象 . 这成为时间轴上的实际时刻 .
ZoneId
但是你提到了新西兰 . 所以你有一个特定的时区 . 时区是与UTC的偏移量加上一组用于处理诸如夏令时(DST)等异常的规则 . 所以我们可以指定
ZoneId
到ZonedDateTime
而不是仅仅偏移 .指定proper time zone name . 切勿使用3-4字母缩写,如
EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!) . 例如,Pacific/Auckland
.ZonedDateTime
应用
ZoneId
.您可以轻松调整到另一个区域时间轴上的时刻 .
从时代算起
我强烈建议不要将日期时间值作为纪元的计数处理,例如从UTC 1970年开始的毫秒数 . 但如果必须,请从这样的数字创建一个
Instant
.然后根据需要分配如上所示的时区,以远离UTC .
您的
1_317_816_735_000L
的值是:2011-10-05T12:12:15Z
(2011年10月5日星期三12:12:15 GMT)2011-10-06T01:12:15+13:00[Pacific/Auckland]
(2011年10月6日星期四01:12:15在新西兰奥克兰举行) .生成字符串
要以标准ISO 8601格式生成字符串,只需调用
toString
. 请注意ZonedDateTime
明智地通过在方括号中附加时区名称来扩展标准格式 .对于其他格式,请搜索DateTimeFormatter类的Stack Overflow . 已经多次覆盖 .
指定FormatStyle和Locale .
关于java.time
java.time框架内置于Java 8及更高版本中 . 这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date,Calendar和SimpleDateFormat .
Joda-Time项目现在位于maintenance mode,建议迁移到java.time类 .
要了解更多信息,请参阅Oracle Tutorial . 并搜索Stack Overflow以获取许多示例和解释 . 规格是JSR 310 .
您可以直接与数据库交换java.time对象 . 使用JDBC driver符合JDBC 4.2或更高版本 . 不需要字符串,不需要
java.sql.*
类 .从哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10以及之后
内置 .
具有捆绑实现的标准Java API的一部分 .
Java 9增加了一些小功能和修复 .
Java SE 6和Java SE 7
在ThreeTen-Backport中,大部分java.time功能都被反向移植到Java 6&7 .
Android
更新版本的Android捆绑java.time类的实现 .
对于早期的Android(<26),ThreeTenABP项目适应ThreeTen-Backport(如上所述) . 见How to use ThreeTenABP… .
ThreeTen-Extra项目使用其他类扩展java.time . 该项目是未来可能添加到java.time的试验场 . 您可以在这里找到一些有用的类,例如Interval,YearWeek,YearQuarter和more .
看一下,我不认为Java中的时区是GMT 13.所以我认为你必须使用:
(如果有更改“GMT”到该时区并删除第二行代码)
要么
如果您想设置特定的时间/日期,您还可以使用:
解决方案实际上非常简单(纯粹,简单的Java):
输出是:
Joda-Time
java.util.Date/Calendar类是一团糟,应该避免 .
更新:Joda-Time项目处于维护模式 . 该团队建议迁移到java.time类 .
以下是使用Joda-Time 2.3库的答案 . 很容易 .
如示例代码中所述,我建议您尽可能使用命名时区,以便您的编程可以处理Daylight Saving Time(DST)和其他异常 .
如果你在字符串的中间放置了
T
而不是空格,你可以跳过前两行代码,处理格式化程序来解析字符串 . DateTime构造函数可以采用ISO 8601格式的字符串 .转储这些 Value ......
跑的时候......
我试过这段代码
得到这个结果
我们可以使用偏移值来处理这个问题
测试代码段:
输出:1387353270742 1387335270742
我们可以从给定日期获得UTC / GMT时间戳 .
它将根据传递的日期返回UTC时间 .
我希望这会有助于其他人 . 谢谢!!
A quick way is :
产量
NEW DATE: 2015-07-02T16:51:46
一些简单的方法 . 一个重要的事情要记住,Date不会维护时区,它只是
long millis
数字,因为它在这里处理 .TimezoneServer就像
TimeZone timeZoneServer = TimeZone.getTimeZone("GMT+1")
您的方法无需任何修改即可运行