我正在将字符串“ 11/15/2020”解析为一个日期。我需要将时区设置为EDT,但是此日期更改为11/14/2020。我假设是因为我在CST中,所以正在从以下时间中删除该小时时间差:Sun Nov 15 00:00:00 CST 2020,这成为前一天。
我想设置时区而不修改日期。我该怎么做呢?仅增加一个小时是不够的。
dateFormat dataFormat = new SimpleDateFormat("MM/dd/yy");
dataFormat.setTimeZone(TimeZone.getTimeZone(Constants.EDT_TZN));
答案 0 :(得分:2)
我想设置时区而不修改日期。
仅日期的值(例如2020年11月15日)没有时区的概念。您无需担心时区。
您使用的是可怕的日期时间类,而这些类早已被JSR 310中定义的 java.time 类取代了。永远不要使用SimpleDateFormat
,Date
或{ {1}}。
Calendar
在Java中,没有日期和日期的纯日期值由LocalDate
类表示。
LocalDate
请参阅此code run live at IdeOne.com。
ld.toString:2020-11-15
也许您确实想要片刻,而不只是约会。我认为那意味着您想要一天的第一刻。
不要假设一天从00:00:00开始。诸如夏令时(DST)之类的异常表示一天可能在01:00:00之类的时间开始。让 java.time 确定在特定时区的特定日子开始的时间。
以String input = "11/15/2020" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
的格式指定proper time zone name,例如Continent/Region
,America/Montreal
或Africa/Casablanca
。切勿使用2-4个字母的缩写,例如Pacific/Auckland
,EST
,EDT
或CST
,因为它们不是真实的时区,不是真实的时区。标准化,甚至不是唯一的(!)。例如,IST
可以像中国的标准时间一样方便地用作美国的中央标准时间。
CST
zdt.toString():2020-11-15T00:00-05:00 [美国/蒙特利尔]
通常最好在UTC中存储和交换时刻。要从我们指定的时区调整为UTC,请从ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
中提取一个Instant
。根据定义,ZonedDateTime
始终使用UTC。
Instant
instant.toString():2020-11-15T05:00:00Z
以标准ISO 8601格式生成文本。最后的Instant instant = zdt.toInstant() ;
表示UTC,并发音为“ Zulu”。
instant.toString():2020-11-15T05:00:00Z
如果必须与尚未更新为 java.time 的旧代码进行互操作,则可以来回转换。查看添加到旧类中的新Z
/ to…
方法。
旧类from…
尽管名称错误,但与Date
等效,均代表UTC时刻。 Instant
使用的是纳秒级而非毫秒级的更精细分辨率。
Instant
…和…
Date d = java.util.Date.from( instant ) ;
请注意, Instant instant = d.toInstant() ;
方法会撒谎,并应用当前的默认时区。尽管用心良苦,但实际上这是很令人困惑的。避免此类的许多原因之一。
答案 1 :(得分:1)
Java中的时间(根据Date对象和System.currentTimeMillis)定义为格林尼治标准时间1970年1月1日00:00:00之后的毫秒数。 TimeZone所做的所有设置都是将偏移量本地化为特定(Java)时间的小时数。
因此,您有三种选择: