Oracle db能否将时间戳与不同的时区进行比较?

时间:2016-12-28 22:27:27

标签: java spring oracle date spring-data-jpa

我想知道Oracle是否能够将日期与不同的时区进行比较,如:

12/26/2016 3:58:16.491476 AM -06:00> 12/26/2016 3:58:16.491476 AM +05:00

顺便说一下,我使用JPA进行比较,我的想法是查找一小时前创建的所有行。

我发现我可以使用After关键字来查找它(即findMeasureDateAfter)

2 个答案:

答案 0 :(得分:1)

很容易在Oracle中检查。答案是肯定的。请注意,在下图中,输出显示使用我的会话的NLS设置的时间戳(我并不关心更改它们)。

var express = require("express");
var router = express.Router();
var flash = require("connect-flash");

var fs = require('fs');
var firebase = require("firebase");
var gcloud = require('google-cloud');

var multer = require("multer");
var upload = multer({dest:"./public/images/uploads/", limits: {fileSize: 250000}}).single("image");


// Enable Storage
var gcs = gcloud.storage({
    projectId: 'grape-spaceship-123',
    keyFilename: '/path/to/keyfile.json'
});

// Reference an existing bucket.
var bucket = gcs.bucket('my-existing-bucket');

router.get("/", function(req, res, next){
    if (firebase.auth().currentUser == null) {
        global.page_name = "login";
        res.render("users/login");
    }
    else {
        global.page_name = "upload";
        res.render("upload");
    }
});

router.post("/", function(req, res, next){
    upload(req,res, function (err) {
        if (err) {
            req.flash("error_msg", "File too large. Max Size: 250KB");
            res.redirect("/upload");
            return
        }


        var title = req.body.title;
        var section = req.body.section;

        // Validation
        req.checkBody('title', 'Title is required').notEmpty();
        req.checkBody('title', 'Title is too long, max: 50 charachters !').len(0,50);
        req.checkBody('section', 'Section is required').notEmpty();

        var errors = req.validationErrors();

        if(errors){
            res.render('upload', {
                errors: errors
            });
        }
        else {

            if (req.file){


                console.log("image saved successfully in local");

                //upload to the GCloud
                bucket.upload(req.file.filename, function(err, file) {
                    if (!err) {
                        console.log("image saved successfully in GCloud");


                        //remove local image
                        fs.unlink(req.file.filename, (err) => {
                            if (err) throw err;
                                console.log('successfully deleted /tmp/hello');
                        });


                        //store image name in firebase
                        var image = file.name;//may be another key hold the image name.
                        var section = req.body.section.toLowerCase();

                        var IDref = firebase.database().ref("posts/"+section+"/lastID");

                        IDref.once("value", function(IDsnapshot){
                            var number = IDsnapshot.val();
                            var postRef = firebase.database().ref("posts/"+section).push();
                            var UID = postRef.key;
                            var post = {
                                title: req.body.title,
                                section: req.body.section,
                                image: image,
                                author: firebase.auth().currentUser.uid,
                                section:  section,
                                upvotes: 0,
                                downvotes: 0,
                                id: number + 1,
                                key: UID
                            }

                            IDref.set(post.id);

                            postRef.set(post);

                            var authoredPost = {
                                title: req.body.title,
                                section: section,
                            }

                            var userRef = firebase.database().ref("users/"+firebase.auth().currentUser.uid.toString()+"/posts/"+UID.toString());
                            userRef.set(authoredPost);

                        });

                        req.flash("success_msg", "Post Created");
                        res.redirect("/upload");

                    }
                });




            }
            else {
                console.log("No file uploaded");
                req.flash("error_msg", "Image is required");
                res.redirect("/upload");
            }
        }
    });
});

module.exports = router;

如果你是基于这样的谓词从Oracle表中提取数据,那么在数据库中完成这项工作要好得多 - 所以如何在Java中完成这项工作是无关紧要的。 (你肯定不想获取所有的行,只是在用Java检查时间戳后忽略大部分行。)当然,如果你需要&#34;最后一小时&#34;你会与with inputs ( ts1, ts2 ) as ( select to_timestamp_tz('12/26/2016 3:58:16.491476 AM -06:00', 'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM'), to_timestamp_tz('12/26/2016 3:58:16.491476 AM +05:00', 'mm/dd/yyyy hh:mi:ss.ff AM TZH:TZM') from dual ) select ts1, ts2, case when ts1 > ts2 then 'ts1 > ts2' when ts1 = ts2 then 'ts1 = ts2' when ts1 < ts2 then 'ts1 < ts2' end as comparison, ts1 - ts2 as difference from inputs ; TS1 TS2 COMPARISON DIFFERENCE ----------------------------- ----------------------------- ---------- ------------------- 26-DEC-16 03.58.16.491 AM -06 26-DEC-16 03.58.16.491 AM +05 ts1 > ts2 +00 11:00:00.000000 进行比较。

答案 1 :(得分:0)

ISO 8601

首先,如果这些输入实际上是问题中提供的字符串,则尽可能使用标准ISO 8601格式。标准格式对人类来说很直观,而且计算机更容易解析。实际上,java.time类在解析/生成字符串时默认使用ISO 8601格式。

java.time

虽然我不知道Oracle中的查询(我自己就是Postgres的人),但我可以展示如何在Java端更多地形成查询。

理想情况下,我们会将输入字符串解析为OffsetDateTime,因为它缺少时区指示,只有从UTC偏移。区域是偏移加上一组用于处理夏令时(DST)等异常的规则。时区的格式为continent/region,例如America/Montreal

不幸的是,Java 8中的java.time实现在解析DateTimeFormatter类中的UTC偏移时存在一些缺陷。所以在Java 9之前,这里有一些hack代码要解析为ZonedDateTime并转换为更合适的OffsetDateTime

String input = "12/26/2016 3:58:16.491476 AM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "MM/dd/uuuu h:m:s.SSSSSS a z" , Locale.ENGLISH );
OffsetDateTime odt = ZonedDateTime.parse ( input , f ).toOffsetDateTime ();
  

odt.toString():2016-12-26T03:58:16.491476-06:00

重复你的结束时刻。

如果JDBC驱动程序支持JDBC 4.2或更高版本,则可以通过PreparedStatement::setObject直接传递这些java.time类型。

如果没有,请转换为java.sql类型。要转换,请查看添加到旧类的新方法。 from方法采用Instant,这是UTC时间轴上的一个时刻。您可以将Instant视为剥离其偏移的OffsetDateTime。致电OffsetDateTime::toInstant以提取Instant

java.sql.Timestamp ts = java.sql.Timestamp.from( odt.toInstant() ) ;

为您的开始和结束时刻执行此操作。将这些java.sql.Timestamp个对象传递给您的PreparedStatement

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore