户县规划建设和住房保障局网站,做牙齿的招聘网站,营销型网站建设怎么收费,宝塔有WordPress遇到的问题#xff1a;系统时间与数据库时间不一致#xff0c;系统时间是8:20#xff0c;存到数据库里是0:20。第一直觉是时区不同导致的。先看一段代码#xff1a;Java代码public static void main(String[] args) {//System.out.println(TimeZone.getDefault());SimpleDa…遇到的问题系统时间与数据库时间不一致系统时间是8:20存到数据库里是0:20。第一直觉是时区不同导致的。先看一段代码Java代码public static void main(String[] args) {//System.out.println(TimeZone.getDefault());SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);Calendar c Calendar.getInstance();//System.out.println(c.getTime());System.out.println(sdf.format(c.getTime()));System.out.println(c.getTimeInMillis());TimeZone.setDefault(TimeZone.getTimeZone(GMT5:00));sdf.setTimeZone(TimeZone.getDefault());//System.out.println(c.getTime());//System.out.println(c.getTime().getTimezoneOffset());System.out.println(sdf.format(c.getTime()));System.out.println(c.getTimeInMillis());}输出结果2011-11-25 10:33:2113221884017962011-11-25 07:33:211322188401796这说明时间的显示是由时区决定的时间所表示的距标准时间毫秒数是绝对的不会随时区不同而改变。理解这一点很重要。那么数据库里的时间也应该有个时区概念那到底是如何处理的呢一直这么认为的时间在数据库里实际存的是毫秒数。那我们在客户端看到的时间一定是经过数据库格式化以后的。但结果不完全是这样的下面我们要讨论数据库中的两个时间类型 datetime 和 timestamp 。网上有文称datetime - 存储日期和时间部分精确到秒没有时区信息timestamp - 时间戳存储日期、时间和时区信息秒值精确到小数点后6位注意这里的时间戳在sqlserver中根本就不是时间他只记录相对时间的先后不记录具体时间。我认为应该叫做数据版本号。首先在sqlserver中测试select getdate()执行结果跟想像的一样操作系统的时区如何修改他都能随之变化他肯定获得了系统的时区信息然后对当前毫秒数格式化。把系统时区恢复到GMT8:00创建一个测试表并插入两条数据create table TEST_TIMEZONE(tid int,time1 datetime ,time2 datetime);insert into TEST_TIMEZONE values(1,getdate(),getdate());insert into TEST_TIMEZONE values(2,getdate(),getdate());select * from TEST_TIMEZONE;这时数据库查询结果为1 2011-11-25 10:47:23.750 2011-11-25 10:47:23.7502 2011-11-25 10:47:27.513 2011-11-25 10:47:27.513现在修改系统时区为GMT5:00再插入两条数据并修改第一条数据insert into TEST_TIMEZONE values(3,getdate(),getdate());insert into TEST_TIMEZONE values(4,getdate(),getdate());update TEST_TIMEZONE set time1getdate() where tid1;select * from TEST_TIMEZONE;这时数据库查询结果为1 2011-11-25 07:50:20.373 2011-11-25 10:47:23.7502 2011-11-25 10:47:27.513 2011-11-25 10:47:27.5133 2011-11-25 07:50:15.920 2011-11-25 07:50:15.9204 2011-11-25 07:50:18.500 2011-11-25 07:50:18.500因为datetime没有时区信息只有年月日时分秒所以保存的是几点就是几点两次操作差了3个小时。select t.*,t.time2-t.time1 from TEST_TIMEZONE t where t.tid1我们再看时间戳类型sqlserver一个表只能有一个时间戳列而且时间戳列不用操作在数据行插入或更新时自动更新。新建测试表create table TEST_TIMEZONE2(tid int,time1 timestamp);insert into TEST_TIMEZONE2(tid) values(1);insert into TEST_TIMEZONE2(tid) values(2);insert into TEST_TIMEZONE2(tid) values(3);select * from TEST_TIMEZONE2;查询结果1 0x000000000000200A2 0x000000000000200B3 0x000000000000200Cupdate TEST_TIMEZONE2 set tid4 where tid3;select * from TEST_TIMEZONE2;查询结果1 0x000000000000200A2 0x000000000000200B4 0x000000000000200E这个时间戳主要用在处理并发问题上做为数据是否已被修改的凭证可以提高并发性能。 再次明确sqlserver的时间戳不是具体时间。恢复一下时区到GMT8:00都不知道现在几点了。接下来在mysql做个测试select now()修改系统时区对查询结果没有影响这与sqlserver不同。修改时区后重启mysql再执行有效果了。说明mysql在启动时记录了系统时区而不是实时的读取系统时区。恢复时区到GMT8:00新建 表create table TEST_TIMEZONE(tid int,time1 datetime ,time2 timestamp ,time3 timestamp);插入数据insert into TEST_TIMEZONE(tid) values(1);insert into TEST_TIMEZONE(tid) values(2);insert into TEST_TIMEZONE values(3,now(),now(),now());insert into TEST_TIMEZONE values(4,now(),now(),now());select * from TEST_TIMEZONE查询结果Mysql允许多个timestamp列但只有第一列会自动更新默认值 为CURRENT_TIMESTAMP。恢复时区到GMT5:00重启动mysql执行查询结果说明datetime的时间不随系统时区而变化timestamp会随系统时区变化而变化也sqlserver完全不同。Mysql在timestamp字段记录的是毫秒数并且按初始的系统时区格式化后显示。另外对oracle现在没有测试环境。结论Datatime类型只保存年月日时分秒信息不含时区。Timestamp时间戳不同数据库有不同的实现不要用做业务列更不能作为索引或键使用他会自动被更新。