mysql 时间绝对值_datetime和timestamp--时间戳是绝对值,日期是相对值

遇到的问题:系统时间与数据库时间不一致,系统时间是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("GMT+5: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:21

1322188401796

2011-11-25 07:33:21

1322188401796

这说明,时间的显示是由时区决定的,时间所表示的距标准时间毫秒数是绝对的,不会随时区不同而改变。理解这一点很重要。

那么数据库里的时间也应该有个时区概念,那到底是如何处理的呢?一直这么认为的,时间在数据库里实际存的是毫秒数。那我们在客户端看到的时间一定是经过数据库格式化以后的。

但结果不完全是这样的,下面我们要讨论数据库中的两个时间类型 datetime 和 timestamp 。

网上有文称

datetime - 存储日期和时间部分,精确到秒,没有时区信息

timestamp - 时间戳,存储日期、时间和时区信息,秒值精确到小数点后6位

注意这里的时间戳,在sqlserver中根本就不是时间,他只记录相对时间的先后,不记录具体时间。我认为应该叫做数据版本号。

首先在sqlserver中测试:

select getdate()

执行结果跟想像的一样,操作系统的时区如何修改,他都能随之变化,他肯定获得了系统的时区信息,然后对当前毫秒数格式化。

把系统时区恢复到GMT+8: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.750

2     2011-11-25 10:47:27.513       2011-11-25 10:47:27.513

现在修改系统时区为GMT+5:00,再插入两条数据,并修改第一条数据

insert into TEST_TIMEZONE values(3,getdate(),getdate());

insert into TEST_TIMEZONE values(4,getdate(),getdate());

update TEST_TIMEZONE set time1=getdate() where tid=1;

select * from TEST_TIMEZONE;

这时数据库查询结果为

1     2011-11-25 07:50:20.373       2011-11-25 10:47:23.750

2     2011-11-25 10:47:27.513       2011-11-25 10:47:27.513

3     2011-11-25 07:50:15.920       2011-11-25 07:50:15.920

4     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.tid=1

我们再看时间戳类型,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     0x000000000000200A

2     0x000000000000200B

3     0x000000000000200C

update TEST_TIMEZONE2 set tid=4 where tid=3;

select * from TEST_TIMEZONE2;

查询结果:

1     0x000000000000200A

2     0x000000000000200B

4     0x000000000000200E

这个时间戳主要用在处理并发问题上,做为数据是否已被修改的凭证,可以提高并发性能。 再次明确sqlserver的时间戳不是具体时间。

恢复一下时区到GMT+8:00,都不知道现在几点了。

接下来,在mysql做个测试:

select now()

修改系统时区对查询结果没有影响,这与sqlserver不同。修改时区后,重启mysql,再执行有效果了。说明mysql在启动时记录了系统时区,而不是实时的读取系统时区。

恢复时区到GMT+8: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

查询结果

fe238025f2f22e130f1ebd597f52e7aa.png

Mysql允许多个timestamp列,但只有第一列会自动更新,默认值 为

CURRENT_TIMESTAMP。

恢复时区到GMT+5:00,重启动mysql,执行查询

442ce1f2dc385874ebc353adc532dd1f.png

结果说明datetime的时间不随系统时区而变化,timestamp会随系统时区变化而变化,也sqlserver完全不同。Mysql在timestamp字段记录的是毫秒数,并且按初始的系统时区格式化后显示。

另外对oracle现在没有测试环境。

结论:

Datatime类型只保存年月日时分秒信息,不含时区。

Timestamp时间戳,不同数据库有不同的实现,不要用做业务列,更不能作为索引或键使用,他会自动被更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python网络编程自学_五分钟搞定Python网络编程实现TCP和UDP连接

Python网络编程实现TCP和UDP连接, 使用socket模块, 所有代码在python3下测试通过。实现TCP#!/usr/bin/env python3# -*- coding: utf-8 -*-import socket# 创建一个socket:s socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接:s.connect((www.baidu.co…

java自定义线程_Java自定义线程池详解

自定义线程池的核心:ThreadPoolExecutor为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent包下,是JDK并发包的核心,比如我们熟知的Executor…

java sql 递归查询_sql server实现递归查询的方法示例

本文实例讲述了sql server实现递归查询的方法示例。分享给大家供大家参考,具体如下:有时候面对树结构的数据时需要进行递归查询,网上找了一番,参考了各位大神的文章,发现蛮简单的,当做个小笔记方便以后使用sql server 通过CTE来支持递归查询,这对查询树形…

java 垃圾回收 null_java方法中把对象置null,到底能不能加速垃圾回收

今天逛脉脉,看见匿名区有人说java中把对做置null,这种做法很菜,不能加速垃圾回收,但是我看到就觉得呵呵了,我是觉得可以加速置null对象回收的。测试的过程中,费劲的是要指定一个合理的测试堆大小&#xff0…

零基础学java web开发pdf_新手学Java Web开发.pdf

作 者 :杨磊等编著出版发行 : 北京:北京希望电子出版社 , 2010.01ISBN号 :978-7-89498-988-8页 数 : 480丛书名 : 新手学编程系列原书定价 : 49.80主题词 : 计算机编程软件,JAVA WEB中图法分类号 : TP3 ( 工业技术->…

es 映射 mysql_ElasticSearch系列02:ES基础概念详解

1、ES 简介1)定义ES是elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。Elasticsearch也使用Java开…

java 跨域上传_java后台图片跨域上传图片 文件

发送方ResponseBodyRequestMapping(value"/imgUpLoadNewOneKuaYu")public String imgUpLoadNewOneKuaYu(HttpServletRequest request) throwsIOException {String urlStr "http://localhost:9080/no-js/admin/upload";Map textMap new HashMap();Multipar…

java ajax 导入excel_Ajax asp.net 导入Excel

$("#btnUploadExcelSave").click(function () {var fileObj document.getElementById("file").files[0]; // js 获取文件对象var FileController "../FileHandler.ashx?type3"; // 接收上传文件的后台地址// FormData 对象var form new Form…

java 外卖订餐系统_java外卖订餐系统小项目

本文实例为大家分享了java外卖订餐系统的具体代码,供大家参考,具体内容如下执行结果:通过选择功能序号,执行响应的功能:代码实现:package 外卖订餐系统;/** 代码优点,使用 循环:* 显…

mysql 性能问题_mysql性能问题

性能优化的目的是什么呢?(合理利用可利用的资源)性能优化的方向:硬件方面:CPU、内存、IO、网络、硬盘、显卡软件方面:mysql这个软件内部优化,比如sql、算法,一些配置项目方面:需求设计、架构优化…

java 字符串包含某个字符_java中判断字符串中是否包含某个特定字符串的方法有哪些...

判断一个字符串是否包含某个子串的n种方法:1、startsWith()方法2、contains()方法3、indexOf方法startsWith()方法这个方法有两个变体,用于检测字符串是否以指定的前缀开始。此方法定义的语法如下:public boolean startsWith(String prefix, int toffset…

java socket 判断是否断开_Linux Socket:如何在客户端程序中检测断开的网络?

仅在调用write()函数时才能检测到未插入的以太网电缆 . 这是因为tcp堆栈的tcp重传没有你的意识 . 这是解决方案 .即使您已经为应用程序套接字设置了keepalive选项,但是如果您的应用程序一直在套接字上写入,您无法及时检测到套接字的死连接状态 . 那是因为…

java backbone_在Backbone.js中发出POST请求

我有一个RESTful服务器,它接受url编码的参数 .就我而言,发帖请求https://我的服务器:8443 / test / auth将请求标头设置为Content-Type:application / x-www-form-urlencoded并传递参数username myusername password …

java的方法调用中分不清_java中不太清晰的知识点

一、什么包需要导入,什么包不需要导入1.java.lang包的内容是自动导入的,不需要手动导入,其它必须手动导入。2.java.io.OutputStreamWrite已经是完整的类,无需再导入,而printWrite这个类,并不是调用完整的类…

纪念品分组java_纪念品分组 ——易懂、简介、技巧(Java代码)

我的思路:1、先排序2、两层循环嵌套,外面的一层从数组末尾开始,里面一层从头开始遍历,首先满足的条件就是这两个数都不能是 NULL 的,并且两个物品的价值加起来不大于最大价值,都满足之后就把两个物品都赋值…

java生命小游戏_Java修炼——飞机生存小游戏

在学习了java入门的课程之后,自己动手跟着老师写的一个小游戏,用的是Frame。总共有七个类。1.飞机游戏的主窗口(MyGameFrame)继承Frame。package com.bjsxt.plane;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Gr…

java 线程类 通信_Java 中利用管道实现线程间的通讯

在Java 语言中,提供了各种各样的输入输出流(stream),使我们能够很方便的对数据进行操作,其中,管道(pipe)流是一种特殊的流,用于在不同线程(threads)间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中…

java整型缓存_JAVA整型包装类的缓存策略

Java Integer的缓存策略public classJavaIntegerCache {public static voidmain(String... strings) {Integer integer1 3;Integer integer2 3;if (integer1 integer2)System.out.println("integer1 integer2");elseSystem.out.println("integer1 ! integer2&q…

java年利润编程题_[编程入门]利润计算-题解(Java代码)

![](/image_editor_upload/20200216102044_14158.png)这也是简单的分类问题,用if进行分类后就可以用switch进行分类计算利润代码如下:package javaapplication;import java.util.Scanner;public class JavaApplication{public static void main(String[]…

java面向方面编程_面向方面编程的介绍----基本概念

面向对象的编程中常用的概念是:继承、封装、多态。在面向方面的编程中常使用的概念是:advices/interceptors, introductions, metadata, and pointcuts。AOP 面向方面编程的介绍----基本概念(3)面向方面的编程思路很简单。从面向过程、函数的编程到面向对…