当java.util.Date
正在将"01/01/1901"
解析为Date
对象时,Java API会将日期转换为“01/01/1901 0:08:39”
而不是“01/01/1901 0:00:00”
,这仅发生在马来西亚时区。
这种情况正在发生,因为1901年马来西亚决定将他的时区与槟城,马六甲和新加坡同步,因此他们增加了8分39秒。 Java知道这一点,因此会自动为日期对象添加分钟和秒数(因为在马来西亚,01/01/1991日期不存在00:00:00小时)。
马来西亚TZ改变: https://www.timeanddate.com/time/change/malaysia/kuala-lumpur?year=1901
Java来源:
public class SimpleDateFormatExample {
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
// Locale for formatter
Locale malaysianLocale = new Locale("ms", "MY");
// Default date and time format for Malaysia
DateFormat defaultMalaysianFormatter = DateFormat.getDateTimeInstance(
DateFormat.DEFAULT, DateFormat.DEFAULT, malaysianLocale);
// This step is crucial
TimeZone malaysianTimeZone= TimeZone.getTimeZone("Asia/Kuala_Lumpur");
defaultMalaysianFormatter.setTimeZone(malaysianTimeZone);
try {
format.setTimeZone(malaysianTimeZone);
Date a = format.parse("01/01/1901");
String t = defaultMalaysianFormatter.format(a);
System.out.println(t);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
示例java输出:
01 Januari 1901 12:08:39 AM
在Oracle数据库TO_date
中,函数的工作方式不同,我们认为Oracle数据库不考虑时区,因此在通过SQL查询发送时,它不会检索正确的值。
Oracle Sql Source:
ALTER SESSION SET TIME_ZONE='Asia/Kuala_Lumpur';
select to_date('19010101 00:00:00','YYYYMMDD HH24:MI:SS') from dual;
示例Oracle输出:
01-JAN-01 00:00:00
此问题特定于马来西亚时区和1901 01/01
为什么Java和Oracle数据库的行为方式不同?
答案 0 :(得分:2)
评论太长了:
DATE
数据类型没有位置或时区。如果您需要,则需要使用TIMESTAMP WITH TIME ZONE
数据类型:
ALTER SESSION SET TIME_ZONE='Asia/Kuala_Lumpur';
SELECT FROM_TZ(
CAST(
DATE '1901-01-01' + INTERVAL '08:39' MINUTE TO SECOND
AS TIMESTAMP
),
'Asia/Kuala_Lumpur'
)
FROM DUAL;
输出:
1901-01-01 00.09.04.000000000 ASIA/KUALA_LUMPUR
指定1900-01-01 00:00:00
和1900-01-01 00:08:38
之间的任何值都会给ORA-01878: specified field not found in datetime or interval
,因为Oracle知道它是无效的日期/时间/时区组合。
为什么输出为00:09:04
而非00:08:39
是另一个问题......
您还可以使用ANSI时间戳文字:
SELECT TIMESTAMP '1901-01-01 00:08:39 Asia/Kuala_Lumpur' FROM DUAL;