我在数据库中有一个日期存储作为varchar中的long值,例如:1230748200000。 我需要通过oracle查询从中获取年份。我可以在oracle中进行操作吗?有没有一种方法可以将其转换为日期以便我能获得一年?问题是我无法使用to_char(SYSTIMESTAMP,'yyyy')或to_Date,因为我没有时间戳或日期格式的日期...而是将其作为长varchar
谢谢。
编辑: 您能为以下场景提供解决方案吗?我在我的表中有1262284398000保存为var char.so因为我说我需要得到一年我使用以下sql返回年份为2009
select
to_char(
to_date('01-JAN-1970','DD-MM-YYYY HH24:MI SS') + ( 1262284398000 / (1000*60 * 60 * 24) ) ,'YYYY')
from dual ;
但是在java代码中,相同的值会将日期返回到2010年,因此年份会变得不同,
Calendar c = Calendar.getInstance();
c.setTimeInMillis(1262284398000l);
System.out.println(c.getTime());
System.out.println(c.get(Calendar.YEAR));
哪个日期返回为Fri Jan 01 00:03:18 IST2010为什么这里有区别?
答案 0 :(得分:2)
查看here了解更多信息
select epoch_time, extract(year from epoch_time) as year
from (
select date '1970-01-01' + 1291116794/86400 as epoch_time
from dual
)
可能会出现时区等问题,因为我相信纪元时间将是UTC,但这超出了我的意愿。
此外,看起来您的值是13位数而不是10位,所以您可能只需要添加一些额外的零,即除以86400000而不是86400。
编辑:正如我上面所说....可能存在时区问题。看起来Java代码采用1970-01-01(在UTC中,应该是这样)添加偏移并将其转换为本地时间。您还需要对数据库查询执行此操作。我对Oracle如何处理时区有点不清楚,但经过一些实验后,我想出了以下示例
alter session set time_zone = 'Asia/Calcutta';
select
sessiontimezone,
to_char(to_date('01-JAN-1970','DD-MM-YYYY HH24:MI SS') +
( 1262284398000 / (1000*60 * 60 * 24) ) ,'YYYY'),
extract(year from cast(timestamp '1970-01-01 00:00:00 +00:00' at local +
numtodsinterval(1262284398000 / 1000, ' SECOND') as timestamp with time zone)),
to_char(timestamp '1970-01-01 00:00:00 +00:00' at local +
numtodsinterval(1262284398000 / 1000, ' SECOND'), 'YYYY'),
extract(year from cast(timestamp '1970-01-01 00:00:00 +00:00' at local +
numtodsinterval(1262284398000 / 1000, ' SECOND') as timestamp with local time
zone))
from dual;
在上面的例子中,前两列(在sessiontimezone之后)应该是2009年,最后两列应该是2010年。虽然这一切都是通过实验找到的,所以你的里程可能会有所不同。
答案 1 :(得分:1)
@MikeyByCrikey发布了一个很好的起点,但在将字符串值转换为日期之前,您需要回答几个问题:
一个。什么日期用'0'表示?也就是说,这个毫秒计数值从哪里开始?在@ Mikey的例子中,使用了1970年1月1日的Unix“开始”日期(也称为“纪元日期”),但是您的帖子中没有足够的信息来了解“0”日期究竟是什么。其他系统使用不同的纪元日期。例如,在运行VMS操作系统的系统上,纪元日期是1858年11月17日(恰好是Julian day 2,400,000); Windows(32位和64位版本)使用01年1月1 - 1601年(400年公历周期的第一年,这是该操作系统设计时的当前版本);和其他计算机系统使用不同的'0'日期。
B中。将字符串转换为Oracle中的数字非常简单。我只使用TO_NUMBER函数,如:
strMillisecs VARCHAR2(100) := '1230748200000';
nMilliseconds NUMBER;
nMilliseconds := TO_NUMBER(strMillisecs);
℃。一旦你到达这一点(已知'0'日期,并将字符串转换为数字),可以按如下方式提取年份:
dtEpoch_date DATE := TO_DATE('01-JAN-1970', 'DD-MON-YYYY'); -- for example
strMillisecs VARCHAR2(100) := '1230748200000';
nMilliseconds NUMBER;
dtTarget_date DATE;
nYear NUMBER;
nMillisecs_in_a_day NUMBER := 86400000;
nMilliseconds := TO_NUMBER(strMillisecs);
-- Note: there are
dtTarget_date := dtEpoch_date + (nMilliseconds / nMillisecs_in_a_day);
-- FINALLY!
nYear := TO_NUMBER(TO_CHAR(dtTarget_date, 'YYYY'));
希望这很有用。
分享并享受。
答案 2 :(得分:1)
我们希望将存储在数据库中的长值转换为中心时区的TIMESTAMP值。
这很有用。
select FROM_TZ(
TO_TIMESTAMP('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') +
NUMTODSINTERVAL( 1386655200000/1000,'SECOND'),
'UTC') at time zone 'America/Chicago'
from dual
其中1386655200000是2013年12月10日中央时区的java.util.Date的毫秒值。